7 /* wait operations with timeout
9 /* #include <timed_wait.h>
11 /* int timed_waitpid(pid, statusp, options, time_limit)
13 /* WAIT_STATUS_T *statusp;
17 /* \fItimed_waitpid\fR() waits at most \fItime_limit\fR seconds
18 /* for process termination.
21 /* .IP "pid, statusp, options"
22 /* The process ID, status pointer and options passed to waitpid(3).
24 /* The time in seconds that timed_waitpid() will wait.
25 /* This must be a number > 0.
27 /* Panic: interface violation.
29 /* When the time limit is exceeded, the result is -1 and errno
30 /* is set to ETIMEDOUT. Otherwise, the result value is the result
31 /* from the underlying waitpid() routine.
33 /* If there were a \fIportable\fR way to select() on process status
34 /* information, these routines would not have to use a steenkeeng
35 /* alarm() timer and signal() handler.
39 /* The Secure Mailer license must be distributed with this software.
42 /* IBM T.J. Watson Research
44 /* Yorktown Heights, NY 10598, USA
55 /* Utility library. */
58 #include <posix_signals.h>
59 #include <timed_wait.h>
61 /* Application-specific. */
63 static int timed_wait_expired
;
65 /* timed_wait_alarm - timeout handler */
67 static void timed_wait_alarm(int unused_sig
)
71 * WARNING WARNING WARNING.
73 * This code runs at unpredictable moments, as a signal handler. This code
74 * is here only so that we can break out of waitpid(). Don't put any code
75 * here other than for setting a global flag.
77 timed_wait_expired
= 1;
80 /* timed_waitpid - waitpid with time limit */
82 int timed_waitpid(pid_t pid
, WAIT_STATUS_T
*statusp
, int options
,
85 const char *myname
= "timed_waitpid";
86 struct sigaction action
;
87 struct sigaction old_action
;
95 msg_panic("%s: bad time limit: %d", myname
, time_limit
);
100 sigemptyset(&action
.sa_mask
);
102 action
.sa_handler
= timed_wait_alarm
;
103 if (sigaction(SIGALRM
, &action
, &old_action
) < 0)
104 msg_fatal("%s: sigaction(SIGALRM): %m", myname
);
105 timed_wait_expired
= 0;
106 time_left
= alarm(time_limit
);
109 * Wait for only a limited amount of time.
111 if ((wpid
= waitpid(pid
, statusp
, options
)) < 0 && timed_wait_expired
)
118 if (sigaction(SIGALRM
, &old_action
, (struct sigaction
*) 0) < 0)
119 msg_fatal("%s: sigaction(SIGALRM): %m", myname
);