summaryrefslogtreecommitdiff
path: root/sleep_good.c
diff options
context:
space:
mode:
authorubq323 <ubq323@ubq323.website>2023-11-16 21:26:56 +0000
committerubq323 <ubq323@ubq323.website>2023-11-16 21:26:56 +0000
commitc70dd01e2ea56e9d90317359b8da051299a69bd5 (patch)
tree1f942cd8265d14a727c2278be4859cc5aba10b61 /sleep_good.c
parentc3c7afda0bd65a0333060addaf27331f6e414367 (diff)
add sleep_good.cHEADtrunk
Diffstat (limited to 'sleep_good.c')
-rw-r--r--sleep_good.c100
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;
+}
+