From 28000d3b3f05ea2b1adf602409352e933bd3ee0f Mon Sep 17 00:00:00 2001 From: Enrico Scholz Date: Mon, 25 Jul 2005 15:50:48 +0000 Subject: [PATCH] - made the alarm() code working with glibc also; glibc restarts 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 | 25 +++++++++++++++++++++---- 1 file changed, 21 insertions(+), 4 deletions(-) diff --git a/util-vserver/src/vwait.c b/util-vserver/src/vwait.c index 4d34fba..8de778e 100644 --- a/util-vserver/src/vwait.c +++ b/util-vserver/src/vwait.c @@ -30,6 +30,7 @@ #include #include #include +#include #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; -- 1.8.1.5