diff options
Diffstat (limited to 'sleep_good.c')
-rw-r--r-- | sleep_good.c | 100 |
1 files changed, 100 insertions, 0 deletions
diff --git a/sleep_good.c b/sleep_good.c new file mode 100644 index 0000000..6382352 --- /dev/null +++ b/sleep_good.c @@ -0,0 +1,100 @@ +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <termios.h> +#include <string.h> +#include <poll.h> + +int parse(char *s) { + int cur=0,tot=0; + int pos; char c; + for (pos=0; c=s[pos],c!=0; pos++) { + if ('0'<=c && c<='9') { + cur*=10; + cur+=c-'0'; + } else { + switch(c) { + case 'h': cur *= 60; + case 'm': cur *= 60; + case 's': break; + default: return -1; + } + tot+=cur; cur=0; + } + } + return tot+cur; +} + +void disp(int secs) { + int rem; + int h = secs/3600; rem= secs%3600; + int m = rem/60; int s = rem%60; + if (h>0) printf("%02dh",h); + if (h>0||m>0) printf("%02dm",m); + printf("%02ds",s); + fflush(stdout); +} + +int main(int argc, char **argv) { + if (argc != 2) { + fprintf(stderr, "usage: %s TIMESPEC\n", argv[0]); + exit(1); + } + + int secs = parse(argv[1]); + if (secs==0) return 0; + if (secs<0) { + fprintf(stderr, "%s: invalid timespec %s\n", argv[0], argv[1]); + exit(1); + } + + struct termios orig_term, new_term; + tcgetattr(0, &orig_term); + memcpy(&new_term, &orig_term, sizeof(struct termios)); + cfmakeraw(&new_term); + tcsetattr(0, TCSADRAIN, &new_term); + + int paused = 0; + struct pollfd pf = { + .fd = 0, + .events = POLLIN, + }; + while (secs>0) { + if (paused) printf("[paused] "); + disp(secs); + int rc = poll(&pf, 1, paused ? -1 : 1000); + if (rc == 0 && !paused) secs--; + + printf("\033[2K\033[G"); + if (pf.revents & POLLIN) { + char c; + read(0,&c,1); + switch(c){ + case 'q': + case 3: // ctrl-C + goto end; + case '+': + secs+=10; + break; + case '=': + secs++; + break; + case '_': + secs -= 10; + if (secs <= 0) secs=10; + break; + case '-': + secs--; + if (secs <= 0) secs=1; + break; + case ' ': + paused = !paused; + break; + } + } + } +end: + tcsetattr(0, TCSADRAIN, &orig_term); + return 0; +} + |