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