tt

A simple terminal timer
git clone git://git.laack.co/tt.git
Log | Files | Refs | README | LICENSE

main.c (2103B)


      1 #include <errno.h>
      2 #include <stdio.h>
      3 #include <stdlib.h>
      4 #include <unistd.h>
      5 #include <sys/select.h>
      6 #include <termios.h>
      7 #include <limits.h>
      8 
      9 #define USAGE_STRING "usage: tt {num_minutes}\n"
     10 #define INVALID_INPUT -1
     11 
     12 void clear_screen() {
     13     printf("\033[2J\033[1;1H");
     14     fflush(stdout);
     15 }
     16 
     17 int main(int argc, char** argv) {
     18 
     19     fd_set readfds;
     20     int nfds = 1;
     21     int paused = 0;
     22 
     23     FD_ZERO(&readfds);
     24     FD_SET(0, &readfds);
     25 
     26     if (argc <= 1 || argc > 2) {
     27         printf(USAGE_STRING);
     28         return INVALID_INPUT;
     29     }
     30 
     31     char *end;
     32     errno = 0;
     33 
     34     long value = strtol(argv[1], &end, 10);
     35     if (end == argv[1] || *end != '\0' || errno == ERANGE || value <= 0) {
     36         printf("Invalid number: %s\n", argv[1]);
     37         return INVALID_INPUT;
     38     }
     39 
     40     if (value > LONG_MAX / 60) {
     41         printf("Number too large: %s\n", argv[1]);
     42         return INVALID_INPUT;
     43     }
     44 
     45     value *= 60;
     46 
     47     struct termios oldt, newt;
     48     tcgetattr(0, &oldt);
     49     newt = oldt;
     50     newt.c_lflag &= ~(ICANON | ECHO);
     51     tcsetattr(0, TCSANOW, &newt);
     52 
     53     clear_screen();
     54 
     55     while (value > 0) {
     56         long minutes = value / 60;
     57         long seconds = value % 60;
     58 
     59         char timeStr[16];
     60         snprintf(timeStr, sizeof(timeStr), "%02ld:%02ld", minutes, seconds);
     61 
     62         char commandToRun[100];
     63         snprintf(commandToRun, sizeof(commandToRun), "figlet %s", timeStr);
     64         system(commandToRun);
     65 
     66         while (1) {
     67             struct timeval timeout;
     68             timeout.tv_sec = paused ? 0 : 1;
     69             timeout.tv_usec = 0;
     70 
     71             FD_ZERO(&readfds);
     72             FD_SET(0, &readfds);
     73 
     74             select(nfds, &readfds, NULL, NULL, &timeout);
     75 
     76             if (FD_ISSET(0, &readfds)) {
     77                 char c;
     78                 read(0, &c, 1);
     79 
     80                 if (c == ' ') {
     81                     paused = !paused;
     82                 }
     83             }
     84 
     85             if (!paused) {
     86                 value -= 1;
     87                 break;
     88             }
     89         }
     90 
     91         if (value > 0) {
     92             clear_screen();
     93         }
     94     }
     95 
     96     tcsetattr(0, TCSANOW, &oldt);
     97 
     98     return 0;
     99 }