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