infobar

Unixy status monitor
git clone git://wolog.xyz/infobar
Log | Files | Refs | README | LICENSE

ticktack.c (1533B)


      1 /*
      2  * Copyright (C) Raymond Cole <rc@wolog.xyz>
      3  * License: GPL-3.0-or-later
      4  */
      5 #define _POSIX_C_SOURCE 200112L
      6 #include <errno.h>
      7 #include <signal.h>
      8 #include <stdio.h>
      9 #include <stdlib.h>
     10 #include <string.h>
     11 #include <time.h>
     12 #include <unistd.h>
     13 #include <sys/wait.h>
     14 
     15 #include "util.h"
     16 
     17 enum { TTS = 1, TTM = 2 };
     18 
     19 static volatile sig_atomic_t tt, sentterm;
     20 static struct timespec request, now;
     21 
     22 static void
     23 updatereq(int t)
     24 {
     25 	if (t & TTS)
     26 		request.tv_sec = now.tv_sec + 1;
     27 	else if (t & TTM)
     28 		request.tv_sec = now.tv_sec - now.tv_sec % 60 + 60;
     29 }
     30 
     31 int
     32 main(int argc, char **argv)
     33 {
     34 	time_t osec;
     35 	int c;
     36 
     37 	progname = argv[0];
     38 	while ((c = getopt(argc, argv, "smh")) != -1) {
     39 		switch (c) {
     40 		case 's': tt |= TTS; break;
     41 		case 'm': tt |= TTM; break;
     42 		default: exit(1);
     43 		}
     44 	}
     45 	if (optind < argc) {
     46 		fputs("Too many arguments\n", stderr);
     47 		exit(1);
     48 	}
     49 	if (!tt)
     50 		for (;;)
     51 			pause();
     52 	if (clock_gettime(CLOCK_REALTIME, &now) == -1)
     53 		die("clock_gettime:");
     54 	updatereq(tt);
     55 	osec = now.tv_sec;
     56 	for (;;) {
     57 		c = '\0';
     58 		if ((tt & TTM) && now.tv_sec - now.tv_sec % 60 > osec) {
     59 			c = 'm';
     60 			updatereq(tt);
     61 		} else if ((tt & TTS) && now.tv_sec > osec) {
     62 			c = 's';
     63 			updatereq(TTS);
     64 		}
     65 		if (c && write(1, (char []){ c, '\n' }, 2) < 0)
     66 			die("write:");
     67 		osec = now.tv_sec;
     68 		switch (clock_nanosleep(CLOCK_REALTIME, TIMER_ABSTIME, &request, NULL)) {
     69 		case 0:
     70 		case EINTR:
     71 			break;
     72 		default:
     73 			die("clock_nanosleep:");
     74 		}
     75 		if (clock_gettime(CLOCK_REALTIME, &now) == -1)
     76 			die("clock_gettime:");
     77 	}
     78 	return 0;
     79 }