No empty .Rs/.Re
[netbsd-mini2440.git] / external / ibm-public / postfix / dist / src / util / timed_wait.c
blob84f358cd15d5f42334cd471a52d25ba979b8899d
1 /* $NetBSD$ */
3 /*++
4 /* NAME
5 /* timed_wait 3
6 /* SUMMARY
7 /* wait operations with timeout
8 /* SYNOPSIS
9 /* #include <timed_wait.h>
11 /* int timed_waitpid(pid, statusp, options, time_limit)
12 /* pid_t pid;
13 /* WAIT_STATUS_T *statusp;
14 /* int options;
15 /* int time_limit;
16 /* DESCRIPTION
17 /* \fItimed_waitpid\fR() waits at most \fItime_limit\fR seconds
18 /* for process termination.
20 /* Arguments:
21 /* .IP "pid, statusp, options"
22 /* The process ID, status pointer and options passed to waitpid(3).
23 /* .IP time_limit
24 /* The time in seconds that timed_waitpid() will wait.
25 /* This must be a number > 0.
26 /* DIAGNOSTICS
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.
32 /* BUGS
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.
36 /* LICENSE
37 /* .ad
38 /* .fi
39 /* The Secure Mailer license must be distributed with this software.
40 /* AUTHOR(S)
41 /* Wietse Venema
42 /* IBM T.J. Watson Research
43 /* P.O. Box 704
44 /* Yorktown Heights, NY 10598, USA
45 /*--*/
47 /* System library. */
49 #include <sys_defs.h>
50 #include <sys/wait.h>
51 #include <unistd.h>
52 #include <signal.h>
53 #include <errno.h>
55 /* Utility library. */
57 #include <msg.h>
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,
83 int time_limit)
85 const char *myname = "timed_waitpid";
86 struct sigaction action;
87 struct sigaction old_action;
88 int time_left;
89 int wpid;
92 * Sanity checks.
94 if (time_limit <= 0)
95 msg_panic("%s: bad time limit: %d", myname, time_limit);
98 * Set up a timer.
100 sigemptyset(&action.sa_mask);
101 action.sa_flags = 0;
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)
112 errno = ETIMEDOUT;
115 * Cleanup.
117 alarm(0);
118 if (sigaction(SIGALRM, &old_action, (struct sigaction *) 0) < 0)
119 msg_fatal("%s: sigaction(SIGALRM): %m", myname);
120 if (time_left)
121 alarm(time_left);
123 return (wpid);