ucspi-ssl  0.99e
TLS encryption for IPv6 communication
iopause.c
Go to the documentation of this file.
1 /* Public domain. */
2 
3 #include "taia.h"
4 #include "select.h"
5 #include "iopause.h"
6 
7 int iopause(iopause_fd *x,unsigned int len,struct taia *deadline,struct taia *stamp)
8 {
9  struct taia t;
10  int millisecs;
11  double d;
12  int i;
13  int ret;
14 
15  if (taia_less(deadline,stamp))
16  millisecs = 0;
17  else {
18  t = *stamp;
19  taia_sub(&t,deadline,&t);
20  d = taia_approx(&t);
21  if (d > 1000.0) d = 1000.0;
22  millisecs = d * 1000.0 + 20.0;
23  }
24 
25  for (i = 0;i < len;++i)
26  x[i].revents = 0;
27 
28 #ifdef IOPAUSE_POLL
29 
30  ret = poll(x,len,millisecs);
31  /* XXX: some kernels apparently need x[0] even if len is 0 */
32  /* XXX: how to handle EAGAIN? are kernels really this dumb? */
33  /* XXX: how to handle EINVAL? when exactly can this happen? */
34 
35 #else
36 {
37 
38  struct timeval tv;
39  fd_set rfds;
40  fd_set wfds;
41  int nfds;
42  int fd;
43 
44  FD_ZERO(&rfds);
45  FD_ZERO(&wfds);
46 
47  nfds = 1;
48  for (i = 0;i < len;++i) {
49  fd = x[i].fd;
50  if (fd < 0) continue;
51  if (fd >= 8 * sizeof(fd_set)) continue; /*XXX*/
52 
53  if (fd >= nfds) nfds = fd + 1;
54  if (x[i].events & IOPAUSE_READ) FD_SET(fd,&rfds);
55  if (x[i].events & IOPAUSE_WRITE) FD_SET(fd,&wfds);
56  }
57 
58  tv.tv_sec = millisecs / 1000;
59  tv.tv_usec = 1000 * (millisecs % 1000);
60 
61  if ((ret=select(nfds,&rfds,&wfds,(fd_set *) 0,&tv)) <= 0)
62  return ret;
63  /* XXX: for EBADF, could seek out and destroy the bad descriptor */
64 
65  for (i = 0; i < len; ++i) {
66  fd = x[i].fd;
67  if (fd < 0) continue;
68  if (fd >= 8 * sizeof(fd_set)) continue; /*XXX*/
69 
70  if (x[i].events & IOPAUSE_READ)
71  if (FD_ISSET(fd,&rfds)) x[i].revents |= IOPAUSE_READ;
72  if (x[i].events & IOPAUSE_WRITE)
73  if (FD_ISSET(fd,&wfds)) x[i].revents |= IOPAUSE_WRITE;
74  }
75 
76 }
77 #endif
78  return ret;
79 
80 }
Definition: taia.h:8
int iopause(iopause_fd *x, unsigned int len, struct taia *deadline, struct taia *stamp)
Definition: iopause.c:7
void taia_sub(struct taia *, const struct taia *, const struct taia *)
Definition: taia_sub.c:7
int taia_less(const struct taia *, const struct taia *)
Definition: taia_less.c:7
double taia_approx(const struct taia *)
Definition: taia_approx.c:5