|
|
1.1 root 1: /* select.c - select() abstractions */
2:
3: #ifndef lint
4: static char *rcsid = "$Header: /f/osi/compat/RCS/select.c,v 7.3 90/05/22 19:33:29 mrose Exp $";
5: #endif
6:
7: /*
8: * $Header: /f/osi/compat/RCS/select.c,v 7.3 90/05/22 19:33:29 mrose Exp $
9: *
10: *
11: * $Log: select.c,v $
12: * Revision 7.3 90/05/22 19:33:29 mrose
13: * update
14: *
15: * Revision 7.2 89/12/05 22:04:41 mrose
16: * touch-up
17: *
18: * Revision 7.1 89/11/30 23:53:31 mrose
19: * touch-up
20: *
21: * Revision 7.0 89/11/23 21:23:24 mrose
22: * Release 6.0
23: *
24: */
25:
26: /*
27: * NOTICE
28: *
29: * Acquisition, use, and distribution of this module and related
30: * materials are subject to the restrictions of a license agreement.
31: * Consult the Preface in the User's Manual for the full terms of
32: * this agreement.
33: *
34: */
35:
36:
37: /* LINTLIBRARY */
38:
39: #include <errno.h>
40: #include <stdio.h>
41: #include "manifest.h"
42: #include "tailor.h"
43: #include <sys/stat.h>
44:
45:
46: extern int errno;
47:
48: /* */
49:
50:
51: #ifdef SOCKETS
52:
53: #include <sys/time.h>
54:
55:
56: /* Synchronous multiplexing:
57: < 0 : block indefinately
58: = 0 : poll
59: > 0 : wait
60: */
61:
62: int selsocket (nfds, rfds, wfds, efds, secs)
63: int nfds;
64: fd_set *rfds,
65: *wfds,
66: *efds;
67: int secs;
68: {
69: int n;
70: fd_set ifds,
71: ofds,
72: xfds;
73: struct timeval tvs;
74: register struct timeval *tv = &tvs;
75:
76: if (secs != NOTOK)
77: tv -> tv_sec = secs, tv -> tv_usec = 0;
78: else
79: tv = NULL;
80:
81: if (rfds)
82: ifds = *rfds;
83: if (wfds)
84: ofds = *wfds;
85: if (efds)
86: xfds = *efds;
87: for (;;) {
88: switch (n = select (nfds, rfds, wfds, efds, tv)) {
89: case OK:
90: if (secs == NOTOK)
91: break;
92: return OK;
93:
94: case NOTOK:
95: default:
96: return n;
97: }
98:
99: if (rfds)
100: *rfds = ifds;
101: if (wfds)
102: *wfds = ofds;
103: if (efds)
104: *efds = xfds;
105: }
106: }
107: #endif
108:
109: /* */
110:
111: #ifdef EXOS
112:
113: #ifdef SYS5
114:
115: /* There seems to be a bug in the SYS5 EXOS select() routine when a socket can
116: be read immediately (don't know about write). The bug is that select()
117: returns ZERO, and the mask is zero'd as well. The code below explicitly
118: checks for this case.
119: */
120:
121: #include "sys/soioctl.h"
122:
123:
124: int selsocket (nfds, rfds, wfds, efds, secs)
125: int nfds;
126: fd_set *rfds,
127: *wfds,
128: *efds;
129: int secs;
130: {
131: register int fd;
132: int n;
133: fd_set ifds,
134: ofds;
135: long nbytes,
136: usecs;
137:
138: if (secs != NOTOK)
139: usecs = secs * 1000;
140: else
141: usecs = 0xffff; /* used to be ~(1L << (8 * sizeof usecs - 1)) */
142:
143: if (rfds)
144: ifds = *rfds;
145: if (wfds)
146: ofds = *wfds;
147: if (efds)
148: FD_ZERO (efds);
149:
150: for (;;) {
151: switch (n = select (nfds + 1, rfds, wfds, usecs)) { /* +1 for UNISYS */
152: case OK:
153: if (rfds)
154: for (fd = 0; fd < nfds; fd++)
155: if (FD_ISSET (fd, &ifds)
156: && ioctl (fd, FIONREAD, (char *) &nbytes)
157: != NOTOK
158: && nbytes > 0) {
159: FD_SET (fd, rfds);
160: n++;
161: }
162: if (n == 0 && secs == NOTOK)
163: break;
164: return n;
165:
166: case NOTOK:
167: default:
168: return n;
169: }
170:
171: if (rfds)
172: *rfds = ifds;
173: if (wfds)
174: *wfds = ofds;
175: }
176: }
177: #endif
178: #endif
179:
180: /* */
181:
182: /* These routines are necessary because some network interfaces (i.e.,
183: the CAMTEC) don't support real select()'s. This code first calls any
184: special interface-specific select() routines, and then calls the
185: standard selsocket routine.
186:
187: In general, inter-working between network interfaces with a real select
188: and interfaces with a real select won't work well. You shouldn't expect
189: to be able to handle parallel notification of events on several transport
190: descriptors. Hopefully, you will only need to work synchronously on one or
191: two descriptors.
192: */
193:
194: static IFP sfnx[FD_SETSIZE] = { NULL };
195:
196:
197: IFP set_select_fd (fd, fnx)
198: int fd;
199: IFP fnx;
200: {
201: IFP ofnx;
202:
203: if (fd < 0 || fd >= FD_SETSIZE)
204: return NULLIFP;
205:
206: ofnx = sfnx[fd];
207: sfnx[fd] = fnx;
208:
209: return ofnx;
210: }
211:
212: set_select_mask (mask,fnx)
213: fd_set *mask;
214: IFP fnx;
215: {
216: int fd;
217:
218: for (fd = 0; fd < FD_SETSIZE; fd++)
219: if (FD_ISSET (fd, mask))
220: sfnx[fd] = fnx;
221: }
222:
223: /* */
224:
225: int xselect (nfds, rfds, wfds, efds, secs)
226: int nfds;
227: fd_set *rfds,
228: *wfds,
229: *efds;
230: int secs;
231: {
232: int n;
233: register int fd;
234: fd_set ifds,
235: ofds,
236: xfds;
237: static int nsysfds = NOTOK;
238:
239: if (nsysfds == NOTOK)
240: nsysfds = getdtablesize ();
241: if (nfds > FD_SETSIZE)
242: nfds = FD_SETSIZE;
243: if (nfds > nsysfds + 1)
244: nfds = nsysfds + 1;
245:
246: for (fd = 0; fd < nfds; fd++)
247: if (sfnx[fd] != NULLIFP
248: && ((rfds && FD_ISSET (fd, rfds))
249: || (wfds && FD_ISSET (fd, wfds))
250: || (efds && FD_ISSET (fd, efds))))
251: return ((*sfnx[fd]) (nfds, rfds, wfds, efds, secs));
252:
253: if (rfds)
254: ifds = *rfds; /* struct copy */
255: if (wfds)
256: ofds = *wfds; /* struct copy */
257: if (efds)
258: xfds = *efds; /* struct copy */
259:
260: if ((n = selsocket (nfds, rfds, wfds, efds, secs)) != NOTOK)
261: return n;
262:
263: if (errno == EBADF) {
264: struct stat st;
265:
266: if (rfds)
267: FD_ZERO (rfds);
268: if (wfds)
269: FD_ZERO (wfds);
270: if (efds)
271: FD_ZERO (efds);
272:
273: n = 0;
274: for (fd = 0; fd < nfds; fd++)
275: if (((rfds && FD_ISSET (fd, &ifds))
276: || (wfds && FD_ISSET (fd, &ofds))
277: || (efds && FD_ISSET (fd, &xfds)))
278: && fstat (fd, &st) == NOTOK) {
279: if (rfds && FD_ISSET (fd, &ifds))
280: FD_SET (fd, rfds);
281: if (wfds && FD_ISSET (fd, &ofds))
282: FD_SET (fd, wfds);
283: if (efds && FD_ISSET (fd, &xfds))
284: FD_SET (fd, efds);
285:
286: SLOG (compat_log, LLOG_EXCEPTIONS, "",
287: ("fd %d has gone bad", fd));
288: n++;
289: }
290:
291: if (n)
292: return n;
293:
294: errno = EBADF;
295: }
296:
297: return NOTOK;
298: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.