dotfiles

configuration files for shell, text editor, graphical environment, etc.
git clone git://src.adamsgaard.dk/dotfiles
Log | Files | Refs | README | LICENSE Back to index

commit b140a8a0e418d5d0583df15655023e236be446f7
parent 3f41c8c96e27600924aaefa6b205442159bc05f9
Author: Anders Damsgaard <anders@adamsgaard.dk>
Date:   Tue, 30 Jul 2019 14:14:54 +0200

Add own watch implementation

Diffstat:
A.local/lib/watch/Makefile | 35+++++++++++++++++++++++++++++++++++
A.local/lib/watch/watch.c | 137+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 172 insertions(+), 0 deletions(-)

diff --git a/.local/lib/watch/Makefile b/.local/lib/watch/Makefile @@ -0,0 +1,35 @@ +CFLAGS = -g -std=c99 -pedantic -Wall +LDFLAGS = -lm +SRC = $(wildcard *.c) +OBJ = $(patsubst %.c,%.o,$(SRC)) +HDR = $(wildcard *.h) +BIN = ./watch + +PREFIX ?= ~/.local/bin +INSTALL ?= install +STRIP ?= strip + +default: $(BIN) + +$(BIN): $(OBJ) $(HDR) + $(CC) $(LDFLAGS) $(OBJ) -o $@ + +install: $(BIN) + $(STRIP) $(BIN) + $(INSTALL) -m 0755 -d $(DESTDIR)$(PREFIX)/bin + $(INSTALL) -m 0755 $(BIN) $(DESTDIR)$(PREFIX)/bin + +uninstall: + $(RM) $(DESTDIR)$(PREFIX)/bin/$(BIN) + +memtest: $(BIN) + valgrind --error-exitcode=1 --leak-check=full $(BIN) -h + valgrind --error-exitcode=1 --leak-check=full $(BIN) -v + valgrind --error-exitcode=1 --leak-check=full $(BIN) -q -r 2 date + valgrind --error-exitcode=1 --leak-check=full $(BIN) -q -n 2 -r 2 ls + +clean: + $(RM) *.o + $(RM) $(BIN) + +.PHONY: default install uninstall memtest clean diff --git a/.local/lib/watch/watch.c b/.local/lib/watch/watch.c @@ -0,0 +1,137 @@ +#include <stdio.h> +#include <stdlib.h> +#include <getopt.h> +#include <string.h> +#include <unistd.h> + +#define VERSION "0.1.0" +#define PROGNAME "watch" + +void +usage(int interval) +{ + printf("%s: %s [OPTIONS] COMMAND\n" + "will repeatedly run COMMAND every %d seconds.\n" + "Following OPTIONS are valid:\n" + " -h, --help show this message\n" + " -v, --version show version and license information\n" + " -n, --interval SECONDS set interval between command invocations\n" + " -r, --repeat N repeat for N times and then quit\n" + " -q, --quiet suppress output (stdout) from COMMAND\n" + " -c, --no-clear do not clear screen between COMMAND calls\n" + " -- do not consider any following args as options\n" + , + __func__, PROGNAME, interval); +} + +void +version() +{ + printf("%s version %s\n" + "Licensed under the GNU Public License, v3+\n" + "Written by Anders Damsgaard, anders@adamsgaard.dk\n", + PROGNAME, VERSION); +} + +void +die(char* error_message) +{ + fprintf(stderr, "%s", error_message); + exit(1); +} + +void +run_cmd(int sleeptime, char* command, int quiet, int clearscreen) +{ + if (!quiet) { + if (clearscreen) + printf("\e[1;1H\e[2J"); /* clear screen (POSIX) */ + else + puts(""); + printf("Every %ds: %s\n\n", sleeptime, command); + } + if (quiet) + strcat(command, " >/dev/null"); + system(command); + sleep(sleeptime); +} + +int +main(int argc, char* argv[]) +{ + int i, opt; + int interval, repeat, quiet, clearscreen; + const char* optstring; + char* command; + + interval = 5; + quiet = 0; + optstring = "hvn:r:qc"; + const struct option longopts[] = { + {"help", no_argument, NULL, 'h'}, + {"version", no_argument, NULL, 'v'}, + {"interval", required_argument, NULL, 'n'}, + {"repeat", required_argument, NULL, 'r'}, + {"quiet", no_argument, NULL, 'q'}, + {"no-clear", no_argument, NULL, 'c'}, + {NULL, 0, NULL, 0} + }; + + repeat = 0; + clearscreen = 1; + while ((opt = getopt_long(argc, argv, optstring, longopts, NULL)) != -1) { + switch (opt) { + case -1: /* no more arguments */ + case 0: /* long options toggles*/ + break; + case 'h': + usage(interval); + return 0; + case 'v': + version(); + return 0; + case 'n': + interval = atoi(optarg); + break; + case 'r': + repeat = atoi(optarg); + break; + case 'q': + quiet = 1; + break; + case 'c': + clearscreen = 0; + break; + default: + fprintf(stderr, "%s: invalid option -- %c\n", argv[0], opt); + fprintf(stderr, "try `%s --help` for more information\n", + argv[0]); + return -2; + } + } + + if (optind == argc) + die("error: no COMMAND specified\n"); + + if ((command = malloc(512)) != NULL) { + command[0] = '\0'; + strcat(command, "[ -f ~/.commands.sh ] && . ~/.commands.sh; "); + for (i=optind; i<argc; ++i) { + strcat(command, argv[i]); + if (i < argc-1) + strcat(command, " "); + } + } else { + die("command malloc failed"); + } + + if (repeat > 0) { + for (i=0; i<repeat; ++i) + run_cmd(interval, command, quiet, clearscreen); + } else { + for (;;) + run_cmd(interval, command, quiet, clearscreen); + } + free(command); + return 0; +}