diff options
author | Tomasz Kramkowski <tk@the-tk.com> | 2015-06-11 22:37:34 +0100 |
---|---|---|
committer | Tomasz Kramkowski <tk@the-tk.com> | 2015-06-11 22:37:34 +0100 |
commit | 0dc36e29dd1e65b22745ffe4b348047e36f38d1b (patch) | |
tree | f544bb54381ab11c5d9c237476be0eeb47e9ad22 | |
parent | 2ca65abe1cf7825184116982fedb6aa991540d24 (diff) | |
download | c-stuff-0dc36e29dd1e65b22745ffe4b348047e36f38d1b.tar.gz c-stuff-0dc36e29dd1e65b22745ffe4b348047e36f38d1b.tar.xz c-stuff-0dc36e29dd1e65b22745ffe4b348047e36f38d1b.zip |
timer.c: Use SIGWINCH handler to get term_width when changed.
timer.c no longer spams ioctl TIOCGWINSZ 4 times a second, it now
handles SIGWINCH and sets a file scope variable to the width.
-rw-r--r-- | timer.c | 30 |
1 files changed, 23 insertions, 7 deletions
@@ -30,6 +30,19 @@ #define SEC_YEAR 31556940 static const unsigned long interval_nsec = 1000000000 / 4; +unsigned short term_width = 0; /* Maybe volatile? */ + +void sigwinch(int sig) { + if (sig != SIGWINCH) + return; + + struct winsize ws; + + if (ioctl(STDOUT_FILENO, TIOCGWINSZ, &ws) == -1) + error(1, errno, "Failed to get terminal width"); + + term_width = ws.ws_col; +} unsigned long int get_seconds(char *code) { @@ -67,15 +80,10 @@ unsigned long int get_seconds(char *code) void clear_line(void) { - struct winsize ws; - - if (ioctl(STDOUT_FILENO, TIOCGWINSZ, &ws) == -1) - error(1, errno, "IOCTL failed"); - - if (ws.ws_col <= 1) + if (term_width <= 1) return; - for (unsigned short i = 0; i < ws.ws_col - 1; i++) + for (unsigned short i = 0; i < term_width - 1; i++) putchar(' '); putchar('\r'); @@ -152,6 +160,7 @@ int main(int argc, char **argv) sigset_t sigset; struct itimerspec its; struct sigevent sev; + struct sigaction sigact; timer_t timerid; unsigned long total_seconds = 0; @@ -165,6 +174,11 @@ int main(int argc, char **argv) for (int i = 1; i < argc; i++) total_seconds += get_seconds(argv[i]); + sigact.sa_handler = sigwinch; + + if (sigaction(SIGWINCH, &sigact, NULL) != 0) + error(1, errno, "Unable to set SIGWINCH signal action"); + sev.sigev_notify = SIGEV_SIGNAL; sev.sigev_signo = SIGRTMIN; sev.sigev_value.sival_ptr = &timerid; @@ -189,6 +203,8 @@ int main(int argc, char **argv) if (timer_settime(timerid, 0, &its, NULL) != 0) error(1, errno, "Could not set timer"); + sigwinch(SIGWINCH); + for (unsigned long i = 0; i < total_seconds; i++) for (int ii = 0; ii < 4; ii++) { if (sigwait(&sigset, &sig), sig != SIGRTMIN) |