5 #include <sys/socket.h>
6 #include <netinet/in.h>
16 /****************************************************************************
17 Set a fd into blocking/nonblocking mode. Uses POSIX O_NONBLOCK if available,
21 ****************************************************************************/
22 int set_blocking(int fd, BOOL set)
26 #define FLAG_TO_SET O_NONBLOCK
29 #define FLAG_TO_SET O_NDELAY
31 #define FLAG_TO_SET FNDELAY
35 if((val = fcntl(fd, F_GETFL, 0)) == -1)
37 if(set) /* Turn blocking on - ie. clear nonblock flag */
41 return fcntl( fd, F_SETFL, val);
45 /*******************************************************************
46 this is like socketpair but uses tcp. It is used by the Samba
48 The function guarantees that nobody else can attach to the socket,
49 or if they do that this function fails and the socket gets closed
50 returns 0 on success, -1 on failure
51 the resulting file descriptors are symmetrical
52 ******************************************************************/
53 static int socketpair_tcp(int fd[2])
57 struct sockaddr_in sock2;
58 socklen_t socklen = sizeof(sock);
61 fd[0] = fd[1] = listener = -1;
63 memset(&sock, 0, sizeof(sock));
65 if ((listener = socket(PF_INET, SOCK_STREAM, 0)) == -1) goto failed;
67 memset(&sock2, 0, sizeof(sock2));
68 #ifdef HAVE_SOCK_SIN_LEN
69 sock2.sin_len = sizeof(sock2);
71 sock2.sin_family = PF_INET;
73 bind(listener, (struct sockaddr *)&sock2, sizeof(sock2));
75 if (listen(listener, 1) != 0) goto failed;
77 if (getsockname(listener, &sock, &socklen) != 0) goto failed;
79 if ((fd[1] = socket(PF_INET, SOCK_STREAM, 0)) == -1) goto failed;
81 set_blocking(fd[1], 0);
83 if (connect(fd[1],(struct sockaddr *)&sock,sizeof(sock)) == -1) {
84 if (errno != EINPROGRESS) goto failed;
89 if ((fd[0] = accept(listener, &sock, &socklen)) == -1) goto failed;
92 if (connect_done == 0) {
93 if (connect(fd[1],(struct sockaddr *)&sock,sizeof(sock)) != 0
94 && errno != EISCONN) goto failed;
97 set_blocking(fd[1], 1);
103 if (fd[0] != -1) close(fd[0]);
104 if (fd[1] != -1) close(fd[1]);
105 if (listener != -1) close(listener);
110 /*******************************************************************
111 run a program on a local tcp socket, this is used to launch smbd
112 when regression testing
113 the return value is a socket which is attached to a subprocess
114 running "prog". stdin and stdout are attached. stderr is left
115 attached to the original stderr
116 ******************************************************************/
117 int sock_exec(const char *prog)
120 if (socketpair_tcp(fd) != 0) return -1;
134 int main(int argc, char *argv[])
140 fd = sock_exec(argv[1]);
142 while ((n = read(fd, buf, sizeof(buf))) > 0) {