aboutsummaryrefslogtreecommitdiffstats
path: root/timer.c
diff options
context:
space:
mode:
authorTomasz Kramkowski <tk@the-tk.com>2015-06-11 22:37:34 +0100
committerTomasz Kramkowski <tk@the-tk.com>2015-06-11 22:37:34 +0100
commit0dc36e29dd1e65b22745ffe4b348047e36f38d1b (patch)
treef544bb54381ab11c5d9c237476be0eeb47e9ad22 /timer.c
parent2ca65abe1cf7825184116982fedb6aa991540d24 (diff)
downloadc-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.
Diffstat (limited to 'timer.c')
-rw-r--r--timer.c30
1 files changed, 23 insertions, 7 deletions
diff --git a/timer.c b/timer.c
index 875cb5c..87c90a3 100644
--- a/timer.c
+++ b/timer.c
@@ -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)