From: Daniel Lezcano <daniel.lezc...@linaro.org>

Add a timeout for the specified command.

The timeout option is shared with the -t option. When no command line has to be
executed, the timeout becomes the duration of the acquisition, otherwise the
command is executed during an amount of time and terminated if the timeout
occur.

Signed-off-by: Daniel Lezcano <daniel.lezc...@linaro.org>
---
 idlestat.c |   36 ++++++++++++++++++++++++++++++++++--
 1 file changed, 34 insertions(+), 2 deletions(-)

diff --git a/idlestat.c b/idlestat.c
index 7ed9f85..d9ce30a 100644
--- a/idlestat.c
+++ b/idlestat.c
@@ -25,6 +25,7 @@
  *
  */
 #define _GNU_SOURCE
+#include <errno.h>
 #include <getopt.h>
 #include <stdio.h>
 #include <stdlib.h>
@@ -1126,6 +1127,14 @@ static int idlestat_wake_all(void)
        return 0;
 }
 
+static volatile sig_atomic_t sigalrm = 0;
+
+static void sighandler(int sig)
+{
+       if (sig == SIGALRM)
+               sigalrm = 1;
+}
+
 static int execute(int argc, char *argv[], char *const envp[],
                   struct idledebug_options *options)
 {
@@ -1148,9 +1157,32 @@ static int execute(int argc, char *argv[], char *const 
envp[],
        }
 
        if (pid) {
-               waitpid(pid, &status, 0);
 
-               if (WIFEXITED(status) && !WEXITSTATUS(status))
+               struct sigaction s = {
+                       .sa_handler = sighandler,
+                       .sa_flags = SA_RESETHAND,
+               };
+
+               sigaddset(&s.sa_mask, SIGALRM);
+               sigaction(SIGALRM, &s, NULL);
+               alarm(options->duration);
+       again:
+               if (waitpid(pid, &status, 0) < 0) {
+                       if (errno != EINTR || !sigalrm)
+                               goto again;
+                       kill(pid, SIGTERM);
+               }
+
+               if (WIFEXITED(status) && !WEXITSTATUS(status)) {
+                       /*
+                        * Cancel the timer in case the program
+                        * finished before the timeout
+                        */
+                       alarm(0);
+                       return 0;
+               }
+
+               if (WIFSIGNALED(status) && WTERMSIG(status) == SIGTERM)
                        return 0;
        }
 
-- 
1.7.9.5


_______________________________________________
linaro-dev mailing list
linaro-dev@lists.linaro.org
http://lists.linaro.org/mailman/listinfo/linaro-dev

Reply via email to