#include <time.h>
#include <errno.h>
#include <libgen.h>
+#include <assert.h>
#define ENSC_WRAPPERS_PREFIX "vwait: "
#define ENSC_WRAPPERS_STDLIB 1
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);
}
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 {
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;