]> git.ipfire.org Git - thirdparty/man-pages.git/blob - man2/select_tut.2
select_tut.2: SYNOPSIS: defer to select(2), rather than repeating the same info
[thirdparty/man-pages.git] / man2 / select_tut.2
1 .\" This manpage is copyright (C) 2001 Paul Sheer.
2 .\"
3 .\" %%%LICENSE_START(VERBATIM)
4 .\" Permission is granted to make and distribute verbatim copies of this
5 .\" manual provided the copyright notice and this permission notice are
6 .\" preserved on all copies.
7 .\"
8 .\" Permission is granted to copy and distribute modified versions of this
9 .\" manual under the conditions for verbatim copying, provided that the
10 .\" entire resulting derived work is distributed under the terms of a
11 .\" permission notice identical to this one.
12 .\"
13 .\" Since the Linux kernel and libraries are constantly changing, this
14 .\" manual page may be incorrect or out-of-date. The author(s) assume no
15 .\" responsibility for errors or omissions, or for damages resulting from
16 .\" the use of the information contained herein. The author(s) may not
17 .\" have taken the same level of care in the production of this manual,
18 .\" which is licensed free of charge, as they might when working
19 .\" professionally.
20 .\"
21 .\" Formatted or processed versions of this manual, if unaccompanied by
22 .\" the source, must acknowledge the copyright and authors of this work.
23 .\" %%%LICENSE_END
24 .\"
25 .\" very minor changes, aeb
26 .\"
27 .\" Modified 5 June 2002, Michael Kerrisk <mtk.manpages@gmail.com>
28 .\" 2006-05-13, mtk, removed much material that is redundant with select.2
29 .\" various other changes
30 .\" 2008-01-26, mtk, substantial changes and rewrites
31 .\"
32 .TH SELECT_TUT 2 2019-03-06 "Linux" "Linux Programmer's Manual"
33 .SH NAME
34 select, pselect, FD_CLR, FD_ISSET, FD_SET, FD_ZERO \-
35 synchronous I/O multiplexing
36 .SH SYNOPSIS
37 .PP
38 See
39 .BR select (2)
40 .SH DESCRIPTION
41 .BR select ()
42 (or
43 .BR pselect ())
44 is used to efficiently monitor multiple file descriptors,
45 to see if any of them is, or becomes, "ready";
46 that is, to see whether I/O becomes possible,
47 or an "exceptional condition" has occurred on any of the file descriptors.
48 .PP
49 Its principal arguments are three "sets" of file descriptors:
50 \fIreadfds\fP, \fIwritefds\fP, and \fIexceptfds\fP.
51 Each set is declared as type
52 .IR fd_set ,
53 and its contents can be manipulated with the macros
54 .BR FD_CLR (),
55 .BR FD_ISSET (),
56 .BR FD_SET (),
57 and
58 .BR FD_ZERO ().
59 A newly declared set should first be cleared using
60 .BR FD_ZERO ().
61 .BR select ()
62 modifies the contents of the sets according to the rules
63 described below; after calling
64 .BR select ()
65 you can test if a file descriptor is still present in a set with the
66 .BR FD_ISSET ()
67 macro.
68 .BR FD_ISSET ()
69 returns nonzero if a specified file descriptor is present in a set
70 and zero if it is not.
71 .BR FD_CLR ()
72 removes a file descriptor from a set.
73 .SS Arguments
74 .TP
75 \fIreadfds\fP
76 This set is watched to see if data is available for reading from any of
77 its file descriptors.
78 After
79 .BR select ()
80 has returned, \fIreadfds\fP will be
81 cleared of all file descriptors except for those that
82 are immediately available for reading.
83 .TP
84 \fIwritefds\fP
85 This set is watched to see if there is space to write data to any of
86 its file descriptors.
87 After
88 .BR select ()
89 has returned, \fIwritefds\fP will be
90 cleared of all file descriptors except for those that
91 are immediately available for writing.
92 .TP
93 \fIexceptfds\fP
94 This set is watched for "exceptional conditions".
95 In practice, only one such exceptional condition is common:
96 the availability of \fIout-of-band\fP (OOB) data for reading
97 from a TCP socket.
98 See
99 .BR recv (2),
100 .BR send (2),
101 and
102 .BR tcp (7)
103 for more details about OOB data.
104 (One other less common case where
105 .BR select (2)
106 indicates an exceptional condition occurs with pseudoterminals
107 in packet mode; see
108 .BR ioctl_tty (2).)
109 After
110 .BR select ()
111 has returned,
112 \fIexceptfds\fP will be cleared of all file descriptors except for those
113 for which an exceptional condition has occurred.
114 .TP
115 \fInfds\fP
116 This is an integer one more than the maximum of any file descriptor in
117 any of the sets.
118 In other words, while adding file descriptors to each of the sets,
119 you must calculate the maximum integer value of all of them,
120 then increment this value by one, and then pass this as \fInfds\fP.
121 .TP
122 \fIutimeout\fP
123 This is the longest time
124 .BR select ()
125 may wait before returning, even if nothing interesting happened.
126 If this value is passed as NULL, then
127 .BR select ()
128 blocks indefinitely waiting for a file descriptor to become ready.
129 \fIutimeout\fP can be set to zero seconds, which causes
130 .BR select ()
131 to return immediately, with information about the readiness
132 of file descriptors at the time of the call.
133 The structure \fIstruct timeval\fP is defined as:
134 .IP
135 .in +4n
136 .EX
137 struct timeval {
138 time_t tv_sec; /* seconds */
139 long tv_usec; /* microseconds */
140 };
141 .EE
142 .in
143 .TP
144 \fIntimeout\fP
145 This argument for
146 .BR pselect ()
147 has the same meaning as
148 .IR utimeout ,
149 but
150 .I "struct timespec"
151 has nanosecond precision as follows:
152 .IP
153 .in +4n
154 .EX
155 struct timespec {
156 long tv_sec; /* seconds */
157 long tv_nsec; /* nanoseconds */
158 };
159 .EE
160 .in
161 .TP
162 \fIsigmask\fP
163 This argument holds a set of signals that the kernel should unblock
164 (i.e., remove from the signal mask of the calling thread),
165 while the caller is blocked inside the
166 .BR pselect ()
167 call (see
168 .BR sigaddset (3)
169 and
170 .BR sigprocmask (2)).
171 It may be NULL,
172 in which case the call does not modify the signal mask on
173 entry and exit to the function.
174 In this case,
175 .BR pselect ()
176 will then behave just like
177 .BR select ().
178 .SS Combining signal and data events
179 .BR pselect ()
180 is useful if you are waiting for a signal as well as
181 for file descriptor(s) to become ready for I/O.
182 Programs that receive signals
183 normally use the signal handler only to raise a global flag.
184 The global flag will indicate that the event must be processed
185 in the main loop of the program.
186 A signal will cause the
187 .BR select ()
188 (or
189 .BR pselect ())
190 call to return with \fIerrno\fP set to \fBEINTR\fP.
191 This behavior is essential so that signals can be processed
192 in the main loop of the program, otherwise
193 .BR select ()
194 would block indefinitely.
195 Now, somewhere
196 in the main loop will be a conditional to check the global flag.
197 So we must ask:
198 what if a signal arrives after the conditional, but before the
199 .BR select ()
200 call?
201 The answer is that
202 .BR select ()
203 would block indefinitely, even though an event is actually pending.
204 This race condition is solved by the
205 .BR pselect ()
206 call.
207 This call can be used to set the signal mask to a set of signals
208 that are to be received only within the
209 .BR pselect ()
210 call.
211 For instance, let us say that the event in question
212 was the exit of a child process.
213 Before the start of the main loop, we
214 would block \fBSIGCHLD\fP using
215 .BR sigprocmask (2).
216 Our
217 .BR pselect ()
218 call would enable
219 .B SIGCHLD
220 by using an empty signal mask.
221 Our program would look like:
222 .PP
223 .EX
224 static volatile sig_atomic_t got_SIGCHLD = 0;
225
226 static void
227 child_sig_handler(int sig)
228 {
229 got_SIGCHLD = 1;
230 }
231
232 int
233 main(int argc, char *argv[])
234 {
235 sigset_t sigmask, empty_mask;
236 struct sigaction sa;
237 fd_set readfds, writefds, exceptfds;
238 int r;
239
240 sigemptyset(&sigmask);
241 sigaddset(&sigmask, SIGCHLD);
242 if (sigprocmask(SIG_BLOCK, &sigmask, NULL) == \-1) {
243 perror("sigprocmask");
244 exit(EXIT_FAILURE);
245 }
246
247 sa.sa_flags = 0;
248 sa.sa_handler = child_sig_handler;
249 sigemptyset(&sa.sa_mask);
250 if (sigaction(SIGCHLD, &sa, NULL) == \-1) {
251 perror("sigaction");
252 exit(EXIT_FAILURE);
253 }
254
255 sigemptyset(&empty_mask);
256
257 for (;;) { /* main loop */
258 /* Initialize readfds, writefds, and exceptfds
259 before the pselect() call. (Code omitted.) */
260
261 r = pselect(nfds, &readfds, &writefds, &exceptfds,
262 NULL, &empty_mask);
263 if (r == \-1 && errno != EINTR) {
264 /* Handle error */
265 }
266
267 if (got_SIGCHLD) {
268 got_SIGCHLD = 0;
269
270 /* Handle signalled event here; e.g., wait() for all
271 terminated children. (Code omitted.) */
272 }
273
274 /* main body of program */
275 }
276 }
277 .EE
278 .SS Practical
279 So what is the point of
280 .BR select ()?
281 Can't I just read and write to my file descriptors whenever I want?
282 The point of
283 .BR select ()
284 is that it watches
285 multiple descriptors at the same time and properly puts the process to
286 sleep if there is no activity.
287 UNIX programmers often find
288 themselves in a position where they have to handle I/O from more than one
289 file descriptor where the data flow may be intermittent.
290 If you were to merely create a sequence of
291 .BR read (2)
292 and
293 .BR write (2)
294 calls, you would
295 find that one of your calls may block waiting for data from/to a file
296 descriptor, while another file descriptor is unused though ready for I/O.
297 .BR select ()
298 efficiently copes with this situation.
299 .SS Select law
300 Many people who try to use
301 .BR select ()
302 come across behavior that is
303 difficult to understand and produces nonportable or borderline results.
304 For instance, the above program is carefully written not to
305 block at any point, even though it does not set its file descriptors to
306 nonblocking mode.
307 It is easy to introduce
308 subtle errors that will remove the advantage of using
309 .BR select (),
310 so here is a list of essentials to watch for when using
311 .BR select ().
312 .TP 4
313 1.
314 You should always try to use
315 .BR select ()
316 without a timeout.
317 Your program
318 should have nothing to do if there is no data available.
319 Code that
320 depends on timeouts is not usually portable and is difficult to debug.
321 .TP
322 2.
323 The value \fInfds\fP must be properly calculated for efficiency as
324 explained above.
325 .TP
326 3.
327 No file descriptor must be added to any set if you do not intend
328 to check its result after the
329 .BR select ()
330 call, and respond appropriately.
331 See next rule.
332 .TP
333 4.
334 After
335 .BR select ()
336 returns, all file descriptors in all sets
337 should be checked to see if they are ready.
338 .TP
339 5.
340 The functions
341 .BR read (2),
342 .BR recv (2),
343 .BR write (2),
344 and
345 .BR send (2)
346 do \fInot\fP necessarily read/write the full amount of data
347 that you have requested.
348 If they do read/write the full amount, it's
349 because you have a low traffic load and a fast stream.
350 This is not always going to be the case.
351 You should cope with the case of your
352 functions managing to send or receive only a single byte.
353 .TP
354 6.
355 Never read/write only in single bytes at a time unless you are really
356 sure that you have a small amount of data to process.
357 It is extremely
358 inefficient not to read/write as much data as you can buffer each time.
359 The buffers in the example below are 1024 bytes although they could
360 easily be made larger.
361 .TP
362 7.
363 Calls to
364 .BR read (2),
365 .BR recv (2),
366 .BR write (2),
367 .BR send (2),
368 and
369 .BR select ()
370 can fail with the error
371 \fBEINTR\fP,
372 and calls to
373 .BR read (2),
374 .BR recv (2)
375 .BR write (2),
376 and
377 .BR send (2)
378 can fail with
379 .I errno
380 set to \fBEAGAIN\fP (\fBEWOULDBLOCK\fP).
381 These results must be properly managed (not done properly above).
382 If your program is not going to receive any signals, then
383 it is unlikely you will get \fBEINTR\fP.
384 If your program does not set nonblocking I/O,
385 you will not get \fBEAGAIN\fP.
386 .\" Nonetheless, you should still cope with these errors for completeness.
387 .TP
388 8.
389 Never call
390 .BR read (2),
391 .BR recv (2),
392 .BR write (2),
393 or
394 .BR send (2)
395 with a buffer length of zero.
396 .TP
397 9.
398 If the functions
399 .BR read (2),
400 .BR recv (2),
401 .BR write (2),
402 and
403 .BR send (2)
404 fail with errors other than those listed in \fB7.\fP,
405 or one of the input functions returns 0, indicating end of file,
406 then you should \fInot\fP pass that file descriptor to
407 .BR select ()
408 again.
409 In the example below,
410 I close the file descriptor immediately, and then set it to \-1
411 to prevent it being included in a set.
412 .TP
413 10.
414 The timeout value must be initialized with each new call to
415 .BR select (),
416 since some operating systems modify the structure.
417 .BR pselect ()
418 however does not modify its timeout structure.
419 .TP
420 11.
421 Since
422 .BR select ()
423 modifies its file descriptor sets,
424 if the call is being used in a loop,
425 then the sets must be reinitialized before each call.
426 .\" "I have heard" does not fill me with confidence, and doesn't
427 .\" belong in a man page, so I've commented this point out.
428 .\" .TP
429 .\" 11.
430 .\" I have heard that the Windows socket layer does not cope with OOB data
431 .\" properly.
432 .\" It also does not cope with
433 .\" .BR select ()
434 .\" calls when no file descriptors are set at all.
435 .\" Having no file descriptors set is a useful
436 .\" way to sleep the process with subsecond precision by using the timeout.
437 .\" (See further on.)
438 .SH RETURN VALUE
439 On success,
440 .BR select ()
441 returns the total number of file descriptors
442 still present in the file descriptor sets.
443 .PP
444 If
445 .BR select ()
446 timed out, then the return value will be zero.
447 The file descriptors set should be all
448 empty (but may not be on some systems).
449 .PP
450 A return value of \-1 indicates an error, with \fIerrno\fP being
451 set appropriately.
452 In the case of an error, the contents of the returned sets and
453 the \fIstruct timeout\fP contents are undefined and should not be used.
454 .BR pselect ()
455 however never modifies \fIntimeout\fP.
456 .SH NOTES
457 Generally speaking,
458 all operating systems that support sockets also support
459 .BR select ().
460 .BR select ()
461 can be used to solve
462 many problems in a portable and efficient way that naive programmers try
463 to solve in a more complicated manner using
464 threads, forking, IPCs, signals, memory sharing, and so on.
465 .PP
466 The
467 .BR poll (2)
468 system call has the same functionality as
469 .BR select (),
470 and is somewhat more efficient when monitoring sparse
471 file descriptor sets.
472 It is nowadays widely available, but historically was less portable than
473 .BR select ().
474 .PP
475 The Linux-specific
476 .BR epoll (7)
477 API provides an interface that is more efficient than
478 .BR select (2)
479 and
480 .BR poll (2)
481 when monitoring large numbers of file descriptors.
482 .SH EXAMPLE
483 Here is an example that better demonstrates the true utility of
484 .BR select ().
485 The listing below is a TCP forwarding program that forwards
486 from one TCP port to another.
487 .PP
488 .EX
489 #include <stdlib.h>
490 #include <stdio.h>
491 #include <unistd.h>
492 #include <sys/time.h>
493 #include <sys/types.h>
494 #include <string.h>
495 #include <signal.h>
496 #include <sys/socket.h>
497 #include <netinet/in.h>
498 #include <arpa/inet.h>
499 #include <errno.h>
500
501 static int forward_port;
502
503 #undef max
504 #define max(x,y) ((x) > (y) ? (x) : (y))
505
506 static int
507 listen_socket(int listen_port)
508 {
509 struct sockaddr_in addr;
510 int lfd;
511 int yes;
512
513 lfd = socket(AF_INET, SOCK_STREAM, 0);
514 if (lfd == \-1) {
515 perror("socket");
516 return \-1;
517 }
518
519 yes = 1;
520 if (setsockopt(lfd, SOL_SOCKET, SO_REUSEADDR,
521 &yes, sizeof(yes)) == \-1) {
522 perror("setsockopt");
523 close(lfd);
524 return \-1;
525 }
526
527 memset(&addr, 0, sizeof(addr));
528 addr.sin_port = htons(listen_port);
529 addr.sin_family = AF_INET;
530 if (bind(lfd, (struct sockaddr *) &addr, sizeof(addr)) == \-1) {
531 perror("bind");
532 close(lfd);
533 return \-1;
534 }
535
536 printf("accepting connections on port %d\en", listen_port);
537 listen(lfd, 10);
538 return lfd;
539 }
540
541 static int
542 connect_socket(int connect_port, char *address)
543 {
544 struct sockaddr_in addr;
545 int cfd;
546
547 cfd = socket(AF_INET, SOCK_STREAM, 0);
548 if (cfd == \-1) {
549 perror("socket");
550 return \-1;
551 }
552
553 memset(&addr, 0, sizeof(addr));
554 addr.sin_port = htons(connect_port);
555 addr.sin_family = AF_INET;
556
557 if (!inet_aton(address, (struct in_addr *) &addr.sin_addr.s_addr)) {
558 fprintf(stderr, "inet_aton(): bad IP address format\en");
559 close(cfd);
560 return \-1;
561 }
562
563 if (connect(cfd, (struct sockaddr *) &addr, sizeof(addr)) == \-1) {
564 perror("connect()");
565 shutdown(cfd, SHUT_RDWR);
566 close(cfd);
567 return \-1;
568 }
569 return cfd;
570 }
571
572 #define SHUT_FD1 do { \e
573 if (fd1 >= 0) { \e
574 shutdown(fd1, SHUT_RDWR); \e
575 close(fd1); \e
576 fd1 = \-1; \e
577 } \e
578 } while (0)
579
580 #define SHUT_FD2 do { \e
581 if (fd2 >= 0) { \e
582 shutdown(fd2, SHUT_RDWR); \e
583 close(fd2); \e
584 fd2 = \-1; \e
585 } \e
586 } while (0)
587
588 #define BUF_SIZE 1024
589
590 int
591 main(int argc, char *argv[])
592 {
593 int h;
594 int fd1 = \-1, fd2 = \-1;
595 char buf1[BUF_SIZE], buf2[BUF_SIZE];
596 int buf1_avail = 0, buf1_written = 0;
597 int buf2_avail = 0, buf2_written = 0;
598
599 if (argc != 4) {
600 fprintf(stderr, "Usage\en\etfwd <listen\-port> "
601 "<forward\-to\-port> <forward\-to\-ip\-address>\en");
602 exit(EXIT_FAILURE);
603 }
604
605 signal(SIGPIPE, SIG_IGN);
606
607 forward_port = atoi(argv[2]);
608
609 h = listen_socket(atoi(argv[1]));
610 if (h == \-1)
611 exit(EXIT_FAILURE);
612
613 for (;;) {
614 int ready, nfds = 0;
615 ssize_t nbytes;
616 fd_set readfds, writefds, exceptfds;
617
618 FD_ZERO(&readfds);
619 FD_ZERO(&writefds);
620 FD_ZERO(&exceptfds);
621 FD_SET(h, &readfds);
622 nfds = max(nfds, h);
623
624 if (fd1 > 0 && buf1_avail < BUF_SIZE)
625 FD_SET(fd1, &readfds);
626 /* Note: nfds is updated below, when fd1 is added to
627 exceptfds. */
628 if (fd2 > 0 && buf2_avail < BUF_SIZE)
629 FD_SET(fd2, &readfds);
630
631 if (fd1 > 0 && buf2_avail \- buf2_written > 0)
632 FD_SET(fd1, &writefds);
633 if (fd2 > 0 && buf1_avail \- buf1_written > 0)
634 FD_SET(fd2, &writefds);
635
636 if (fd1 > 0) {
637 FD_SET(fd1, &exceptfds);
638 nfds = max(nfds, fd1);
639 }
640 if (fd2 > 0) {
641 FD_SET(fd2, &exceptfds);
642 nfds = max(nfds, fd2);
643 }
644
645 ready = select(nfds + 1, &readfds, &writefds, &exceptfds, NULL);
646
647 if (ready == \-1 && errno == EINTR)
648 continue;
649
650 if (ready == \-1) {
651 perror("select()");
652 exit(EXIT_FAILURE);
653 }
654
655 if (FD_ISSET(h, &readfds)) {
656 socklen_t addrlen;
657 struct sockaddr_in client_addr;
658 int fd;
659
660 addrlen = sizeof(client_addr);
661 memset(&client_addr, 0, addrlen);
662 fd = accept(h, (struct sockaddr *) &client_addr, &addrlen);
663 if (fd == \-1) {
664 perror("accept()");
665 } else {
666 SHUT_FD1;
667 SHUT_FD2;
668 buf1_avail = buf1_written = 0;
669 buf2_avail = buf2_written = 0;
670 fd1 = fd;
671 fd2 = connect_socket(forward_port, argv[3]);
672 if (fd2 == \-1)
673 SHUT_FD1;
674 else
675 printf("connect from %s\en",
676 inet_ntoa(client_addr.sin_addr));
677
678 /* Skip any events on the old, closed file descriptors. */
679 continue;
680 }
681 }
682
683 /* NB: read OOB data before normal reads */
684
685 if (fd1 > 0 && FD_ISSET(fd1, &exceptfds)) {
686 char c;
687
688 nbytes = recv(fd1, &c, 1, MSG_OOB);
689 if (nbytes < 1)
690 SHUT_FD1;
691 else
692 send(fd2, &c, 1, MSG_OOB);
693 }
694 if (fd2 > 0 && FD_ISSET(fd2, &exceptfds)) {
695 char c;
696
697 nbytes = recv(fd2, &c, 1, MSG_OOB);
698 if (nbytes < 1)
699 SHUT_FD2;
700 else
701 send(fd1, &c, 1, MSG_OOB);
702 }
703 if (fd1 > 0 && FD_ISSET(fd1, &readfds)) {
704 nbytes = read(fd1, buf1 + buf1_avail,
705 BUF_SIZE \- buf1_avail);
706 if (nbytes < 1)
707 SHUT_FD1;
708 else
709 buf1_avail += nbytes;
710 }
711 if (fd2 > 0 && FD_ISSET(fd2, &readfds)) {
712 nbytes = read(fd2, buf2 + buf2_avail,
713 BUF_SIZE \- buf2_avail);
714 if (nbytes < 1)
715 SHUT_FD2;
716 else
717 buf2_avail += nbytes;
718 }
719 if (fd1 > 0 && FD_ISSET(fd1, &writefds) && buf2_avail > 0) {
720 nbytes = write(fd1, buf2 + buf2_written,
721 buf2_avail \- buf2_written);
722 if (nbytes < 1)
723 SHUT_FD1;
724 else
725 buf2_written += nbytes;
726 }
727 if (fd2 > 0 && FD_ISSET(fd2, &writefds) && buf1_avail > 0) {
728 nbytes = write(fd2, buf1 + buf1_written,
729 buf1_avail \- buf1_written);
730 if (nbytes < 1)
731 SHUT_FD2;
732 else
733 buf1_written += nbytes;
734 }
735
736 /* Check if write data has caught read data */
737
738 if (buf1_written == buf1_avail)
739 buf1_written = buf1_avail = 0;
740 if (buf2_written == buf2_avail)
741 buf2_written = buf2_avail = 0;
742
743 /* One side has closed the connection, keep
744 writing to the other side until empty */
745
746 if (fd1 < 0 && buf1_avail \- buf1_written == 0)
747 SHUT_FD2;
748 if (fd2 < 0 && buf2_avail \- buf2_written == 0)
749 SHUT_FD1;
750 }
751 exit(EXIT_SUCCESS);
752 }
753 .EE
754 .PP
755 The above program properly forwards most kinds of TCP connections
756 including OOB signal data transmitted by \fBtelnet\fP servers.
757 It handles the tricky problem of having data flow in both directions
758 simultaneously.
759 You might think it more efficient to use a
760 .BR fork (2)
761 call and devote a thread to each stream.
762 This becomes more tricky than you might suspect.
763 Another idea is to set nonblocking I/O using
764 .BR fcntl (2).
765 This also has its problems because you end up using
766 inefficient timeouts.
767 .PP
768 The program does not handle more than one simultaneous connection at a
769 time, although it could easily be extended to do this with a linked list
770 of buffers\(emone for each connection.
771 At the moment, new
772 connections cause the current connection to be dropped.
773 .SH SEE ALSO
774 .BR accept (2),
775 .BR connect (2),
776 .BR ioctl (2),
777 .BR poll (2),
778 .BR read (2),
779 .BR recv (2),
780 .BR select (2),
781 .BR send (2),
782 .BR sigprocmask (2),
783 .BR write (2),
784 .BR sigaddset (3),
785 .BR sigdelset (3),
786 .BR sigemptyset (3),
787 .BR sigfillset (3),
788 .BR sigismember (3),
789 .BR epoll (7)
790 .\" .SH AUTHORS
791 .\" This man page was written by Paul Sheer.