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 }