00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "includes.h"
00023
00024
00025
00026
00027
00028
00029
00030
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
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
00093
00094
00095
00096
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 }