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 }