4 #include <sys/socket.h>
6 /* work out what fcntl flag to use for non-blocking */
8 # define NONBLOCK_FLAG O_NONBLOCK
10 # define NONBLOCK_FLAG O_NDELAY
12 # define NONBLOCK_FLAG FNDELAY
17 /****************************************************************************
18 Set a fd into nonblocking mode.
19 ****************************************************************************/
20 int set_nonblocking(int fd)
24 if((val = fcntl(fd, F_GETFL, 0)) == -1)
26 if (!(val & NONBLOCK_FLAG)) {
28 fcntl(fd, F_SETFL, val);
33 /****************************************************************************
34 Set a fd into blocking mode.
35 ****************************************************************************/
36 int set_blocking(int fd)
40 if((val = fcntl(fd, F_GETFL, 0)) == -1)
42 if (val & NONBLOCK_FLAG) {
43 val &= ~NONBLOCK_FLAG;
44 fcntl(fd, F_SETFL, val);
49 int socketpair_tcp(int fd[2])
53 socklen_t socklen = sizeof(sock);
58 fd[0] = fd[1] = listener = -1;
60 memset(&sock, 0, sizeof(sock));
62 if ((listener = socket(PF_INET, SOCK_STREAM, 0)) == -1) goto failed;
64 setsockopt(listener,SOL_SOCKET,SO_REUSEADDR,(char *)&one,sizeof(one));
66 if (listen(listener, 1) != 0) goto failed;
68 if (getsockname(listener, &sock, &socklen) != 0) goto failed;
70 if ((fd[1] = socket(PF_INET, SOCK_STREAM, 0)) == -1) goto failed;
72 setsockopt(fd[1],SOL_SOCKET,SO_REUSEADDR,(char *)&one,sizeof(one));
74 set_nonblocking(fd[1]);
76 if (connect(fd[1],(struct sockaddr *)&sock,sizeof(sock)) == -1) {
77 if (errno != EINPROGRESS) goto failed;
82 if ((fd[0] = accept(listener, &sock, &len)) == -1) goto failed;
84 setsockopt(fd[0],SOL_SOCKET,SO_REUSEADDR,(char *)&one,sizeof(one));
87 if (connect_done == 0) {
88 if (connect(fd[1],(struct sockaddr *)&sock,sizeof(sock)) != 0) goto failed;
97 if (fd[0] != -1) close(fd[0]);
98 if (fd[1] != -1) close(fd[1]);
99 if (listener != -1) close(listener);
112 if (socketpair_tcp(fd) != 0) exit(1);
116 maxfd = fd[0] > fd[1] ? fd[0] : fd[1];
117 select(maxfd+1, NULL, &set, NULL, NULL);
118 ret = write(fd[0], buf, sizeof(buf));
119 if (ret > 0 && ret < sizeof(buf)) exit(0);