]> asedeno.scripts.mit.edu Git - 1ts-debian.git/blob - zephyr/lib/ZWait4Not.c
r4254@bucket (orig r244): kcr | 2008-01-20 14:40:42 -0500
[1ts-debian.git] / zephyr / lib / ZWait4Not.c
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  *      $Id$
8  *
9  *      Copyright (c) 1991 by the Massachusetts Institute of Technology.
10  *      For copying and distribution information, see the file
11  *      "mit-copyright.h". 
12  */
13
14 #include "mit-copyright.h"
15
16 #ifndef lint
17 static char rcsid_ZWaitForNotice_c[] = "$Id$";
18 #endif
19
20 #include <internal.h>
21 #include <sys/socket.h>
22
23 Code_t
24 Z_WaitForNotice(ZNotice_t *notice,
25                 int (*pred) __P((ZNotice_t *, void *)),
26                 void *arg,
27                 int timeout)
28 {
29   Code_t retval;
30   struct timeval tv, t0;
31   fd_set fdmask;
32   int i, fd;
33
34   retval = ZCheckIfNotice (notice, (struct sockaddr_in *) 0, pred,
35                            (char *) arg);
36   if (retval == ZERR_NONE)
37     return ZERR_NONE;
38   if (retval != ZERR_NONOTICE)
39     return retval;
40
41   fd = ZGetFD ();
42   FD_ZERO (&fdmask);
43   tv.tv_sec = timeout;
44   tv.tv_usec = 0;
45   gettimeofday (&t0, (struct timezone *) 0);
46   t0.tv_sec += timeout;
47   while (1) {
48     FD_SET (fd, &fdmask);
49     i = select (fd + 1, &fdmask, (fd_set *) 0, (fd_set *) 0, &tv);
50     if (i == 0)
51       return ETIMEDOUT;
52     if (i < 0 && errno != EINTR)
53       return errno;
54     if (i > 0) {
55       retval = ZCheckIfNotice (notice, (struct sockaddr_in *) 0, pred,
56                                (char *) arg);
57       if (retval != ZERR_NONOTICE) /* includes ZERR_NONE */
58         return retval;
59     }
60     gettimeofday (&tv, (struct timezone *) 0);
61     tv.tv_usec = t0.tv_usec - tv.tv_usec;
62     if (tv.tv_usec < 0) {
63       tv.tv_usec += 1000000;
64       tv.tv_sec = t0.tv_sec - tv.tv_sec - 1;
65     }
66     else
67       tv.tv_sec = t0.tv_sec - tv.tv_sec;
68   }
69   /*NOTREACHED*/
70 }