infobar

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

ticktack.c (1670B)


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