Commit | Line | Data |
---|---|---|
cf7fe8a2 GS |
1 | /* |
2 | * poll.c | |
3 | * | |
4 | * Copyright (c) 1997-8 Graham Barr <gbarr@pobox.com>. All rights reserved. | |
5 | * This program is free software; you can redistribute it and/or | |
6 | * modify it under the same terms as Perl itself. | |
7 | * | |
b38f6a39 GS |
8 | * For systems that do not have the poll() system call (for example Linux |
9 | * kernels < v2.1.23) try to emulate it as closely as possible using select() | |
cf7fe8a2 GS |
10 | * |
11 | */ | |
12 | ||
13 | #include "EXTERN.h" | |
14 | #include "perl.h" | |
21c5e947 JH |
15 | #include "XSUB.h" |
16 | ||
cf7fe8a2 GS |
17 | #include "poll.h" |
18 | #ifdef I_SYS_TIME | |
19 | # include <sys/time.h> | |
20 | #endif | |
21 | #ifdef I_TIME | |
22 | # include <time.h> | |
23 | #endif | |
24 | #include <sys/types.h> | |
4858b6ca | 25 | #if defined(HAS_SOCKET) && !defined(VMS) && !defined(ultrix) /* VMS handles sockets via vmsish.h, ULTRIX dies of socket struct redefinitions */ |
cf7fe8a2 GS |
26 | # include <sys/socket.h> |
27 | #endif | |
28 | #include <sys/stat.h> | |
29 | #include <errno.h> | |
30 | ||
465a6d9a NA |
31 | #ifdef HAS_SELECT |
32 | #ifdef I_SYS_SELECT | |
33 | #include <sys/select.h> | |
34 | #endif | |
35 | #endif | |
36 | ||
cf7fe8a2 GS |
37 | #ifdef EMULATE_POLL_WITH_SELECT |
38 | ||
39 | # define POLL_CAN_READ (POLLIN | POLLRDNORM ) | |
40 | # define POLL_CAN_WRITE (POLLOUT | POLLWRNORM | POLLWRBAND ) | |
41 | # define POLL_HAS_EXCP (POLLRDBAND | POLLPRI ) | |
42 | ||
43 | # define POLL_EVENTS_MASK (POLL_CAN_READ | POLL_CAN_WRITE | POLL_HAS_EXCP) | |
44 | ||
45 | int | |
35ef4773 | 46 | poll(struct pollfd *fds, unsigned long nfds, int timeout) |
cf7fe8a2 GS |
47 | { |
48 | int i,err; | |
49 | fd_set rfd,wfd,efd,ifd; | |
50 | struct timeval timebuf; | |
51 | struct timeval *tbuf = (struct timeval *)0; | |
52 | int n = 0; | |
53 | int count; | |
54 | ||
55 | FD_ZERO(&ifd); | |
56 | ||
4e21c233 | 57 | #ifdef HAS_FSTAT |
cf7fe8a2 | 58 | again: |
4e21c233 | 59 | #endif |
cf7fe8a2 GS |
60 | |
61 | FD_ZERO(&rfd); | |
62 | FD_ZERO(&wfd); | |
63 | FD_ZERO(&efd); | |
64 | ||
91f3b821 | 65 | for(i = 0 ; i < (int)nfds ; i++) { |
cf7fe8a2 GS |
66 | int events = fds[i].events; |
67 | int fd = fds[i].fd; | |
68 | ||
69 | fds[i].revents = 0; | |
70 | ||
71 | if(fd < 0 || FD_ISSET(fd, &ifd)) | |
72 | continue; | |
73 | ||
74 | if(fd > n) | |
75 | n = fd; | |
76 | ||
77 | if(events & POLL_CAN_READ) | |
78 | FD_SET(fd, &rfd); | |
79 | ||
80 | if(events & POLL_CAN_WRITE) | |
81 | FD_SET(fd, &wfd); | |
82 | ||
83 | if(events & POLL_HAS_EXCP) | |
84 | FD_SET(fd, &efd); | |
85 | } | |
86 | ||
87 | if(timeout >= 0) { | |
88 | timebuf.tv_sec = timeout / 1000; | |
89 | timebuf.tv_usec = (timeout % 1000) * 1000; | |
90 | tbuf = &timebuf; | |
91 | } | |
92 | ||
93 | err = select(n+1,&rfd,&wfd,&efd,tbuf); | |
94 | ||
95 | if(err < 0) { | |
96 | #ifdef HAS_FSTAT | |
97 | if(errno == EBADF) { | |
98 | for(i = 0 ; i < nfds ; i++) { | |
99 | struct stat buf; | |
100 | if((fstat(fds[i].fd,&buf) < 0) && (errno == EBADF)) { | |
101 | FD_SET(fds[i].fd, &ifd); | |
102 | goto again; | |
103 | } | |
104 | } | |
105 | } | |
106 | #endif /* HAS_FSTAT */ | |
107 | return err; | |
108 | } | |
109 | ||
110 | count = 0; | |
111 | ||
91f3b821 | 112 | for(i = 0 ; i < (int)nfds ; i++) { |
cf7fe8a2 GS |
113 | int revents = (fds[i].events & POLL_EVENTS_MASK); |
114 | int fd = fds[i].fd; | |
115 | ||
116 | if(fd < 0) | |
117 | continue; | |
118 | ||
119 | if(FD_ISSET(fd, &ifd)) | |
120 | revents = POLLNVAL; | |
121 | else { | |
122 | if(!FD_ISSET(fd, &rfd)) | |
123 | revents &= ~POLL_CAN_READ; | |
124 | ||
125 | if(!FD_ISSET(fd, &wfd)) | |
126 | revents &= ~POLL_CAN_WRITE; | |
127 | ||
128 | if(!FD_ISSET(fd, &efd)) | |
129 | revents &= ~POLL_HAS_EXCP; | |
130 | } | |
131 | ||
132 | if((fds[i].revents = revents) != 0) | |
133 | count++; | |
134 | } | |
135 | ||
136 | return count; | |
137 | } | |
138 | ||
139 | #endif /* EMULATE_POLL_WITH_SELECT */ | |
b76f91fc JH |
140 | |
141 | /* gcc for SunOS 4 produces code from an empty (code/symbolwise) | |
142 | * source code file that makes the SunOS 4.x /usr/bin/ld fail with | |
143 | * ld: poll.o: premature EOF | |
144 | * To avoid this, have at least something in here. */ | |
145 | #if defined(__sun) && !defined(__SVR4) && defined(__GNUC__) | |
146 | static int dummy; | |
147 | #endif | |
148 |