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