commit b140a8a0e418d5d0583df15655023e236be446f7
parent 3f41c8c96e27600924aaefa6b205442159bc05f9
Author: Anders Damsgaard <anders@adamsgaard.dk>
Date: Tue, 30 Jul 2019 14:14:54 +0200
Add own watch implementation
Diffstat:
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;
+}