lib/sock_exec.c

説明を見る。
00001 /* 
00002    Unix SMB/CIFS implementation.
00003    Samba utility functions
00004    Copyright (C) Andrew Tridgell 1992-1998
00005    Copyright (C) Tim Potter      2000-2001
00006    
00007    This program is free software; you can redistribute it and/or modify
00008    it under the terms of the GNU General Public License as published by
00009    the Free Software Foundation; either version 2 of the License, or
00010    (at your option) any later version.
00011    
00012    This program is distributed in the hope that it will be useful,
00013    but WITHOUT ANY WARRANTY; without even the implied warranty of
00014    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015    GNU General Public License for more details.
00016    
00017    You should have received a copy of the GNU General Public License
00018    along with this program; if not, write to the Free Software
00019    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
00020 */
00021 
00022 #include "includes.h"
00023 
00024 /*******************************************************************
00025 this is like socketpair but uses tcp. It is used by the Samba
00026 regression test code
00027 The function guarantees that nobody else can attach to the socket,
00028 or if they do that this function fails and the socket gets closed
00029 returns 0 on success, -1 on failure
00030 the resulting file descriptors are symmetrical
00031  ******************************************************************/
00032 static int socketpair_tcp(int fd[2])
00033 {
00034         int listener;
00035         struct sockaddr_in sock;
00036         struct sockaddr_in sock2;
00037         socklen_t socklen = sizeof(sock);
00038         int connect_done = 0;
00039         
00040         fd[0] = fd[1] = listener = -1;
00041 
00042         memset(&sock, 0, sizeof(sock));
00043         
00044         if ((listener = socket(PF_INET, SOCK_STREAM, 0)) == -1) goto failed;
00045 
00046         memset(&sock2, 0, sizeof(sock2));
00047 #ifdef HAVE_SOCK_SIN_LEN
00048         sock2.sin_len = sizeof(sock2);
00049 #endif
00050         sock2.sin_family = PF_INET;
00051 
00052         bind(listener, (struct sockaddr *)&sock2, sizeof(sock2));
00053 
00054         if (listen(listener, 1) != 0) goto failed;
00055 
00056         if (getsockname(listener, (struct sockaddr *)&sock, &socklen) != 0) goto failed;
00057 
00058         if ((fd[1] = socket(PF_INET, SOCK_STREAM, 0)) == -1) goto failed;
00059 
00060         set_blocking(fd[1], 0);
00061 
00062         sock.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
00063 
00064         if (connect(fd[1],(struct sockaddr *)&sock,sizeof(sock)) == -1) {
00065                 if (errno != EINPROGRESS) goto failed;
00066         } else {
00067                 connect_done = 1;
00068         }
00069 
00070         if ((fd[0] = accept(listener, (struct sockaddr *)&sock, &socklen)) == -1) goto failed;
00071 
00072         close(listener);
00073         if (connect_done == 0) {
00074                 if (connect(fd[1],(struct sockaddr *)&sock,sizeof(sock)) != 0
00075                     && errno != EISCONN) goto failed;
00076         }
00077 
00078         set_blocking(fd[1], 1);
00079 
00080         /* all OK! */
00081         return 0;
00082 
00083  failed:
00084         if (fd[0] != -1) close(fd[0]);
00085         if (fd[1] != -1) close(fd[1]);
00086         if (listener != -1) close(listener);
00087         return -1;
00088 }
00089 
00090 
00091 /*******************************************************************
00092 run a program on a local tcp socket, this is used to launch smbd
00093 when regression testing
00094 the return value is a socket which is attached to a subprocess
00095 running "prog". stdin and stdout are attached. stderr is left
00096 attached to the original stderr
00097  ******************************************************************/
00098 int sock_exec(const char *prog)
00099 {
00100         int fd[2];
00101         if (socketpair_tcp(fd) != 0) {
00102                 DEBUG(0,("socketpair_tcp failed (%s)\n", strerror(errno)));
00103                 return -1;
00104         }
00105         if (fork() == 0) {
00106                 close(fd[0]);
00107                 close(0);
00108                 close(1);
00109                 dup(fd[1]);
00110                 dup(fd[1]);
00111                 exit(system(prog));
00112         }
00113         close(fd[1]);
00114         return fd[0];
00115 }

Sambaに対してSat Aug 29 21:22:59 2009に生成されました。  doxygen 1.4.7