From d743c48c9ca851dd6f0239435cb2167eb02b63d7 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 27 Jun 2001 17:26:17 +0000 Subject: [PATCH] Merge in HEAD build changes. Jeremy. --- source/lib/util_sock.c | 89 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 89 insertions(+) diff --git a/source/lib/util_sock.c b/source/lib/util_sock.c index 9045e60111f..ccbc86bb0bd 100644 --- a/source/lib/util_sock.c +++ b/source/lib/util_sock.c @@ -1144,3 +1144,92 @@ int create_pipe_socket(char *dir, int dir_perms, return s; } + +/******************************************************************* +this is like socketpair but uses tcp. It is used by the Samba +regression test code +The function guarantees that nobody else can attach to the socket, +or if they do that this function fails and the socket gets closed +returns 0 on success, -1 on failure +the resulting file descriptors are symmetrical + ******************************************************************/ +static int socketpair_tcp(int fd[2]) +{ + int listener; + struct sockaddr sock; + struct sockaddr_in sock2; + socklen_t socklen = sizeof(sock); + int connect_done = 0; + + fd[0] = fd[1] = listener = -1; + + memset(&sock, 0, sizeof(sock)); + + if ((listener = socket(PF_INET, SOCK_STREAM, 0)) == -1) goto failed; + + memset(&sock2, 0, sizeof(sock2)); +#ifdef HAVE_SOCK_SIN_LEN + sock2.sin_len = sizeof(sock2); +#endif + sock2.sin_family = PF_INET; + + bind(listener, (struct sockaddr *)&sock2, sizeof(sock2)); + + if (listen(listener, 1) != 0) goto failed; + + if (getsockname(listener, &sock, &socklen) != 0) goto failed; + + if ((fd[1] = socket(PF_INET, SOCK_STREAM, 0)) == -1) goto failed; + + set_blocking(fd[1], 0); + + if (connect(fd[1],(struct sockaddr *)&sock,sizeof(sock)) == -1) { + if (errno != EINPROGRESS) goto failed; + } else { + connect_done = 1; + } + + if ((fd[0] = accept(listener, &sock, &socklen)) == -1) goto failed; + + close(listener); + if (connect_done == 0) { + if (connect(fd[1],(struct sockaddr *)&sock,sizeof(sock)) != 0 + && errno != EISCONN) goto failed; + } + + set_blocking(fd[1], 1); + + /* all OK! */ + return 0; + + failed: + if (fd[0] != -1) close(fd[0]); + if (fd[1] != -1) close(fd[1]); + if (listener != -1) close(listener); + return -1; +} + + +/******************************************************************* +run a program on a local tcp socket, this is used to launch smbd +when regression testing +the return value is a socket which is attached to a subprocess +running "prog". stdin and stdout are attached. stderr is left +attached to the original stderr + ******************************************************************/ +int sock_exec(const char *prog) +{ + int fd[2]; + if (socketpair_tcp(fd) != 0) return -1; + if (fork() == 0) { + close(fd[0]); + close(0); + close(1); + dup(fd[1]); + dup(fd[1]); + exit(system(prog)); + } + close(fd[1]); + return fd[0]; +} + -- 2.11.4.GIT