30 |
#include <time.h> |
#include <time.h> |
31 |
#include <errno.h> |
#include <errno.h> |
32 |
#include <libgen.h> |
#include <libgen.h> |
33 |
|
#include <assert.h> |
34 |
|
|
35 |
#define ENSC_WRAPPERS_PREFIX "vwait: " |
#define ENSC_WRAPPERS_PREFIX "vwait: " |
36 |
#define ENSC_WRAPPERS_STDLIB 1 |
#define ENSC_WRAPPERS_STDLIB 1 |
106 |
static struct StatusType |
static struct StatusType |
107 |
doit(struct Arguments const *args) |
doit(struct Arguments const *args) |
108 |
{ |
{ |
109 |
time_t end_time = 0; |
time_t end_time = 0, now = 0; |
110 |
struct StatusType res; |
struct StatusType res; |
111 |
|
|
112 |
if (args->timeout>0) { |
if (args->timeout>0) { |
113 |
end_time = time(0) + args->timeout; |
end_time = time(0) + args->timeout; |
114 |
|
siginterrupt(SIGALRM, 1); |
115 |
signal(SIGALRM, handler); |
signal(SIGALRM, handler); |
116 |
alarm(args->timeout); |
alarm(args->timeout); |
117 |
} |
} |
120 |
res.rc = vc_wait_exit(args->xid); |
res.rc = vc_wait_exit(args->xid); |
121 |
|
|
122 |
if (res.rc==-1 && errno!=EAGAIN && errno!=EINTR) { |
if (res.rc==-1 && errno!=EAGAIN && errno!=EINTR) { |
123 |
|
// the error-case |
124 |
res.rc = errno; |
res.rc = errno; |
125 |
res.status = stERROR; |
res.status = stERROR; |
126 |
perror(ENSC_WRAPPERS_PREFIX "vc_wait_exit()"); |
perror(ENSC_WRAPPERS_PREFIX "vc_wait_exit()"); |
127 |
} |
} |
128 |
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) { |
129 |
|
// an EINTR or EAGAIN signal was delivered, a timeout was set and |
130 |
|
// reached |
131 |
if (!args->do_terminate) |
if (!args->do_terminate) |
132 |
res.status = stTIMEOUT; |
res.status = stTIMEOUT; |
133 |
else { |
else { |
136 |
res.status = stKILLED; |
res.status = stKILLED; |
137 |
} |
} |
138 |
} |
} |
139 |
else if (res.rc==-1) |
else if (res.rc==-1) { |
140 |
continue; // signal |
// an EINTR or EAGAIN signal was delivered but the timeout not set or |
141 |
|
// not reached yet |
142 |
|
|
143 |
|
// we are here, when args->timeout==0 or 'now' was initialized (and |
144 |
|
// compared with 'end_time'). So, 'now' can be used below. |
145 |
|
assert(args->timeout<=0 || (now < end_time)); |
146 |
|
|
147 |
|
if (args->timeout>0) // (re)set the alarm-clock |
148 |
|
alarm(end_time-now); |
149 |
|
|
150 |
|
continue; |
151 |
|
} |
152 |
else |
else |
153 |
|
// vc_wait_exit(2) finished successfully |
154 |
res.status = stFINISHED; |
res.status = stFINISHED; |
155 |
|
|
156 |
break; |
break; |