| |
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 * Copyright (c) 1991 by the Massachusetts Institute of Technology. |
| |
6 * For copying and distribution information, see the file |
| |
7 * "mit-copyright.h". |
| |
8 */ |
| |
9 |
| |
10 #include "internal.h" |
| |
11 |
| |
12 #ifdef WIN32 |
| |
13 #include <winsock2.h> |
| |
14 |
| |
15 #ifndef ZEPHYR_USES_KERBEROS |
| |
16 static int gettimeofday(struct timeval* tv, struct timezone* tz){ |
| |
17 union { |
| |
18 long long ns100; /*time since 1 Jan 1601 in 100ns units */ |
| |
19 FILETIME ft; |
| |
20 } _now; |
| |
21 |
| |
22 GetSystemTimeAsFileTime( &(_now.ft) ); |
| |
23 tv->tv_usec=(long)((_now.ns100 / 10LL) % 1000000LL ); |
| |
24 tv->tv_sec= (long)((_now.ns100-(116444736000000000LL))/10000000LL); |
| |
25 return 0; |
| |
26 } |
| |
27 #endif |
| |
28 |
| |
29 #else |
| |
30 #include <sys/socket.h> |
| |
31 #endif |
| |
32 |
| |
33 Code_t Z_WaitForNotice (notice, pred, arg, timeout) |
| |
34 ZNotice_t *notice; |
| |
35 int (*pred) __P((ZNotice_t *, void *)); |
| |
36 void *arg; |
| |
37 int timeout; |
| |
38 { |
| |
39 Code_t retval; |
| |
40 struct timeval tv, t0; |
| |
41 fd_set fdmask; |
| |
42 int i, fd; |
| |
43 |
| |
44 retval = ZCheckIfNotice (notice, (struct sockaddr_in *) 0, pred, |
| |
45 (char *) arg); |
| |
46 if (retval == ZERR_NONE) |
| |
47 return ZERR_NONE; |
| |
48 if (retval != ZERR_NONOTICE) |
| |
49 return retval; |
| |
50 |
| |
51 fd = ZGetFD (); |
| |
52 FD_ZERO (&fdmask); |
| |
53 tv.tv_sec = timeout; |
| |
54 tv.tv_usec = 0; |
| |
55 gettimeofday (&t0, (struct timezone *)NULL); |
| |
56 t0.tv_sec += timeout; |
| |
57 while (1) { |
| |
58 FD_SET (fd, &fdmask); |
| |
59 i = select (fd + 1, &fdmask, (fd_set *) 0, (fd_set *) 0, &tv); |
| |
60 if (i == 0) |
| |
61 return ETIMEDOUT; |
| |
62 if (i < 0 && errno != EINTR) |
| |
63 return errno; |
| |
64 if (i > 0) { |
| |
65 retval = ZCheckIfNotice (notice, (struct sockaddr_in *) 0, pred, |
| |
66 (char *) arg); |
| |
67 if (retval != ZERR_NONOTICE) /* includes ZERR_NONE */ |
| |
68 return retval; |
| |
69 } |
| |
70 gettimeofday (&tv, (struct timezone *) NULL); |
| |
71 tv.tv_usec = t0.tv_usec - tv.tv_usec; |
| |
72 if (tv.tv_usec < 0) { |
| |
73 tv.tv_usec += 1000000; |
| |
74 tv.tv_sec = t0.tv_sec - tv.tv_sec - 1; |
| |
75 } |
| |
76 else |
| |
77 tv.tv_sec = t0.tv_sec - tv.tv_sec; |
| |
78 } |
| |
79 /*NOTREACHED*/ |
| |
80 } |