OSDN Git Service

Import translated manuals from JM CVS Repository.
[linuxjm/jm.git] / manual / LDP_man-pages / original / 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 2009-01-26 "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_FD1;
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.