- made the alarm() code working with glibc also; glibc restarts
authorEnrico Scholz <enrico.scholz@informatik.tu-chemnitz.de>
Mon, 25 Jul 2005 15:50:48 +0000 (15:50 +0000)
committerEnrico Scholz <enrico.scholz@informatik.tu-chemnitz.de>
Mon, 25 Jul 2005 15:50:48 +0000 (15:50 +0000)
  vc_wait_exit() instead of interrupting it so an explicit
  siginterrupt(2) is required
- call alarm(2) again when EINTR was seen

git-svn-id: http://svn.linux-vserver.org/svn/util-vserver/trunk@2168 94cd875c-1c1d-0410-91d2-eb244daf1a30

util-vserver/src/vwait.c

index 4d34fba..8de778e 100644 (file)
@@ -30,6 +30,7 @@
 #include <time.h>
 #include <errno.h>
 #include <libgen.h>
+#include <assert.h>
 
 #define ENSC_WRAPPERS_PREFIX   "vwait: "
 #define ENSC_WRAPPERS_STDLIB   1
@@ -105,11 +106,12 @@ handler(int UNUSED num)
 static struct StatusType
 doit(struct Arguments const *args)
 {
-  time_t                       end_time = 0;
+  time_t                       end_time = 0, now = 0;
   struct StatusType            res;
   
   if (args->timeout>0) {
     end_time = time(0) + args->timeout;
+    siginterrupt(SIGALRM, 1);
     signal(SIGALRM, handler);
     alarm(args->timeout);
   }
@@ -118,11 +120,14 @@ doit(struct Arguments const *args)
     res.rc = vc_wait_exit(args->xid);
     
     if      (res.rc==-1 && errno!=EAGAIN && errno!=EINTR) {
+       // the error-case
       res.rc     = errno;
       res.status = stERROR;
       perror(ENSC_WRAPPERS_PREFIX "vc_wait_exit()");
     }
-    else if (res.rc==-1 && args->timeout>0 && time(0)>=end_time) {
+    else if (res.rc==-1 && args->timeout>0 && (now=time(0))>=end_time) {
+       // an EINTR or EAGAIN signal was delivered, a timeout was set and
+       // reached
       if (!args->do_terminate)
        res.status = stTIMEOUT;
       else {
@@ -131,9 +136,21 @@ doit(struct Arguments const *args)
        res.status = stKILLED;
       }
     }
-    else if (res.rc==-1)
-      continue;                // signal
+    else if (res.rc==-1) {
+       // an EINTR or EAGAIN signal was delivered but the timeout not set or
+       // not reached yet
+
+       // we are here, when args->timeout==0 or 'now' was initialized (and
+       // compared with 'end_time'). So, 'now' can be used below.
+      assert(args->timeout<=0 || (now < end_time));
+
+      if (args->timeout>0)     // (re)set the alarm-clock
+       alarm(end_time-now);
+
+      continue;
+    }
     else
+       // vc_wait_exit(2) finished successfully
       res.status = stFINISHED;
 
     break;