14192
|
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 }
|