| |
1 /* This file is part of the Project Athena Zephyr Notification System. |
| |
2 * It contains the ZCheckIfNotice/select loop used for waiting for |
| |
3 * a notice, with a timeout. |
| |
4 * |
| |
5 * Created by: <Joe Random Hacker> |
| |
6 * |
| |
7 * $Source$ |
| |
8 * $Author: warmenhoven $ |
| |
9 * |
| |
10 * Copyright (c) 1991 by the Massachusetts Institute of Technology. |
| |
11 * For copying and distribution information, see the file |
| |
12 * "mit-copyright.h". |
| |
13 */ |
| |
14 |
| |
15 #include "mit-copyright.h" |
| |
16 |
| |
17 #ifndef lint |
| |
18 static char rcsid_ZWaitForNotice_c[] = "$Zephyr$"; |
| |
19 #endif |
| |
20 |
| |
21 #include <internal.h> |
| |
22 #include <sys/socket.h> |
| |
23 |
| |
24 Code_t Z_WaitForNotice (notice, pred, arg, timeout) |
| |
25 ZNotice_t *notice; |
| |
26 int (*pred) __P((ZNotice_t *, void *)); |
| |
27 void *arg; |
| |
28 int timeout; |
| |
29 { |
| |
30 Code_t retval; |
| |
31 struct timeval tv, t0; |
| |
32 fd_set fdmask; |
| |
33 int i, fd; |
| |
34 |
| |
35 retval = ZCheckIfNotice (notice, (struct sockaddr_in *) 0, pred, |
| |
36 (char *) arg); |
| |
37 if (retval == ZERR_NONE) |
| |
38 return ZERR_NONE; |
| |
39 if (retval != ZERR_NONOTICE) |
| |
40 return retval; |
| |
41 |
| |
42 fd = ZGetFD (); |
| |
43 FD_ZERO (&fdmask); |
| |
44 tv.tv_sec = timeout; |
| |
45 tv.tv_usec = 0; |
| |
46 gettimeofday (&t0, (struct timezone *) 0); |
| |
47 t0.tv_sec += timeout; |
| |
48 while (1) { |
| |
49 FD_SET (fd, &fdmask); |
| |
50 i = select (fd + 1, &fdmask, (fd_set *) 0, (fd_set *) 0, &tv); |
| |
51 if (i == 0) |
| |
52 return ETIMEDOUT; |
| |
53 if (i < 0 && errno != EINTR) |
| |
54 return errno; |
| |
55 if (i > 0) { |
| |
56 retval = ZCheckIfNotice (notice, (struct sockaddr_in *) 0, pred, |
| |
57 (char *) arg); |
| |
58 if (retval != ZERR_NONOTICE) /* includes ZERR_NONE */ |
| |
59 return retval; |
| |
60 } |
| |
61 gettimeofday (&tv, (struct timezone *) 0); |
| |
62 tv.tv_usec = t0.tv_usec - tv.tv_usec; |
| |
63 if (tv.tv_usec < 0) { |
| |
64 tv.tv_usec += 1000000; |
| |
65 tv.tv_sec = t0.tv_sec - tv.tv_sec - 1; |
| |
66 } |
| |
67 else |
| |
68 tv.tv_sec = t0.tv_sec - tv.tv_sec; |
| |
69 } |
| |
70 /*NOTREACHED*/ |
| |
71 } |