X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=servers%2Fslapd%2Fback-shell%2Ffork.c;h=a85bd20a9b68328c5c354b3ded0b7dac37bf6ed9;hb=63e843d2003ddf20f3725ad439991e769ffc792a;hp=195daa8d70020e8c9f414bc40b46ab9e673fd0a6;hpb=1677f178ce17284e773162a23dbb9646ec33a427;p=openldap diff --git a/servers/slapd/back-shell/fork.c b/servers/slapd/back-shell/fork.c index 195daa8d70..a85bd20a9b 100644 --- a/servers/slapd/back-shell/fork.c +++ b/servers/slapd/back-shell/fork.c @@ -1,8 +1,31 @@ /* fork.c - fork and exec a process, connecting stdin/out w/pipes */ /* $OpenLDAP$ */ -/* - * Copyright 1998-2002 The OpenLDAP Foundation, All Rights Reserved. - * COPYING RESTRICTIONS APPLY, see COPYRIGHT file +/* This work is part of OpenLDAP Software . + * + * Copyright 1998-2005 The OpenLDAP Foundation. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted only as authorized by the OpenLDAP + * Public License. + * + * A copy of this license is available in the file LICENSE in the + * top-level directory of the distribution or, alternatively, at + * . + */ +/* Portions Copyright (c) 1995 Regents of the University of Michigan. + * All rights reserved. + * + * Redistribution and use in source and binary forms are permitted + * provided that this notice is preserved and that due credit is given + * to the University of Michigan at Ann Arbor. The name of the University + * may not be used to endorse or promote products derived from this + * software without specific prior written permission. This software + * is provided ``as is'' without express or implied warranty. + */ +/* ACKNOWLEDGEMENTS: + * This work was originally developed by the University of Michigan + * (as part of U-MICH LDAP). */ #include "portable.h" @@ -17,222 +40,9 @@ #include "slap.h" #include "shell.h" -#ifdef SHELL_SURROGATE_PARENT - -#include - -/* Use several socketpairs to the surrogate parent, because * - * a single communication channel to it could be a bottleneck */ -ldap_pvt_thread_mutex_t shell_surrogate_fd_mutex[2]; -int shell_surrogate_fd[2] = { -1, -1 }; -/* Index to shell_surrogate_fd, and its mutex */ -ldap_pvt_thread_mutex_t shell_surrogate_index_mutex; -static int shell_surrogate_index = 1; - -pid_t shell_surrogate_pid = -1; - -#define nread( fd, buf, len ) n_rw( 0, fd, buf, len ) -#define nwrite( fd, buf, len ) n_rw( 1, fd, buf, len ) - -static int -n_rw( - int do_write, - int fd, - void *buf, - int len -) -{ - int ret = 0, i; - while( len ) { - for(;;) { - i = (do_write - ? write( fd, buf, len ) - : read( fd, buf, len )); - if( i < 0 ) { - if( errno == EINTR ) - continue; - if( ret == 0 ) - ret = -1; - } - break; - } - if( i <= 0 ) - break; - ret += i; - buf = (char *)buf + i; - len -= i; - } - return ret; -} - -void -make_surrogate_parent( void ) -{ - int pair[2][2], io[2], i, j, p, argc; - ber_len_t len, buflen, offset; - char *buf, **argv; - pid_t pid; - - if( socketpair( AF_LOCAL, SOCK_STREAM, 0, pair[0] ) < 0 || - socketpair( AF_LOCAL, SOCK_STREAM, 0, pair[1] ) < 0 ) { - Debug( LDAP_DEBUG_ANY, "socketpair failed\n", 0, 0, 0 ); - exit( EXIT_FAILURE ); - } - fflush( NULL ); - switch( fork() ) { - case -1: - Debug( LDAP_DEBUG_ANY, "fork failed\n", 0, 0, 0 ); - exit( EXIT_FAILURE ); - case 0: - break; - default: - shell_surrogate_fd[0] = pair[0][0]; - shell_surrogate_fd[1] = pair[1][0]; - close( pair[0][1] ); - close( pair[1][1] ); - return; - } - - /* Close unused file descriptors */ - for( i = 3, j = 32; j && i < 1024; i++ ) - if( i != pair[0][1] && i != pair[1][1] && close( i ) < 0 ) - --j; - else if( j < 32 ) - j = 32; - - /* Surrogate parent running */ - - buflen = 0; - buf = NULL; - argc = 0; - argv = NULL; - p = 0; - - for(;;) { - /* Read file descriptors io[] from socket */ - static char dummy; - static struct iovec iov = { &dummy, 1 }; - struct msghdr msg; -# ifdef CMSG_SPACE - union { - struct cmsghdr cm; - char control[CMSG_SPACE(sizeof(io))]; - } control_un; - struct cmsghdr *cmptr; -# endif - - /* clear msghdr */ - memset( &msg, 0, sizeof msg ); - -# ifdef CMSG_SPACE - msg.msg_control = control_un.control; - msg.msg_controllen = sizeof(control_un.control); -# else - msg.msg_accrights = (caddr_t) io; - msg.msg_accrightslen = sizeof(io); -# endif - - msg.msg_name = NULL; - msg.msg_namelen = 0; - msg.msg_iov = &iov; - msg.msg_iovlen = 1; - - switch( recvmsg( pair[p][1], &msg, MSG_WAITALL ) ) { - case -1: - if( errno == EINTR ) - continue; - _exit( EXIT_FAILURE ); - case 0: - _exit( EXIT_SUCCESS ); - } -# ifdef CMSG_SPACE - if( (cmptr = CMSG_FIRSTHDR(&msg)) == NULL || - cmptr->cmsg_len != CMSG_LEN(sizeof(io)) || - cmptr->cmsg_level != SOL_SOCKET || - cmptr->cmsg_type != SCM_RIGHTS ) { - fputs( "bad descriptor message received\n", stderr ); - exit( EXIT_FAILURE ); - } - memcpy( io, CMSG_DATA( cmptr ), sizeof(io) ); -# else - if( msg.msg_accrightslen != sizeof(io) ) { - fputs( "bad descriptor message received\n", stderr ); - exit( EXIT_FAILURE ); - } -# endif - - /* Read length of arguments and then arguments from socket */ - if( nread( pair[p][1], &len, sizeof(len) ) != sizeof(len) ) { - fputs( "bad descriptor message received\n", stderr ); - exit( EXIT_FAILURE ); - } - if( buflen < len ) { - buf = realloc( buf, buflen = len ); - if( buf == NULL ) { - fputs( "realloc failed\n", stderr ); - exit( EXIT_FAILURE ); - } - } - if( nread( pair[p][1], buf, len ) != len ) { - fputs( "bad descriptor message received\n", stderr ); - exit( EXIT_FAILURE ); - } - i = 0; - offset = 0; - while( offset < len ) { - if( i >= argc-1 ) { - argc += i + 10; - argv = realloc( argv, argc * sizeof(*argv) ); - if( argv == NULL ) { - fputs( "realloc failed\n", stderr ); - exit( EXIT_FAILURE ); - } - } - argv[i++] = buf + offset; - offset += strlen( buf + offset ) + 1; - } - argv[i] = NULL; - - /* Run program */ - pid = fork(); - switch( pid ) - { - case 0: /* child */ - if( dup2( io[0], 0 ) == -1 || dup2( io[1], 1 ) == -1 ) { - fputs( "dup2 failed\n", stderr ); - exit( EXIT_FAILURE ); - } - close( io[0] ); - close( io[1] ); - close( pair[0][1] ); - close( pair[1][1] ); - execv( argv[0], argv ); - - fputs( "execv failed\n", stderr ); - exit( EXIT_FAILURE ); - - case -1: /* trouble */ - fputs( "fork failed\n", stderr ); - break; - - default: /* parent */ - close( io[0] ); - close( io[1] ); - break; - } - if( nwrite( pair[p][1], &pid, - sizeof(pid_t) ) != sizeof(pid_t) ) { - fputs( "could not send pid\n", stderr ); - exit( EXIT_FAILURE ); - } - p ^= 1; - } -} -#endif /* SHELL_SURROGATE_PARENT */ - pid_t forkandexec( - Cmd_info args, + char **args, FILE **rfp, FILE **wfp ) @@ -253,70 +63,6 @@ forkandexec( * parent *rfp <- c2p[0] | c2p[1] <- stdout child */ -#ifdef SHELL_SURROGATE_PARENT - - { - int io[2] = { p2c[0], c2p[1] }, i, c; - static char dummy = '\0'; - static struct iovec iov = { &dummy, 1 }; - struct msghdr msg; -# ifdef CMSG_SPACE - union { - struct cmsghdr cm; - char control[CMSG_SPACE(sizeof(io))]; - } control_un; - struct cmsghdr *cmptr; -# endif - - /* clear msghdr */ - memset( &msg, 0, sizeof msg ); - -# ifdef CMSG_SPACE - msg.msg_control = control_un.control; - msg.msg_controllen = sizeof(control_un.control); - cmptr = CMSG_FIRSTHDR(&msg); - cmptr->cmsg_len = CMSG_LEN(sizeof(io)); - cmptr->cmsg_level = SOL_SOCKET; - cmptr->cmsg_type = SCM_RIGHTS; - memcpy( CMSG_DATA(cmptr), io, sizeof(io) ); -# else - msg.msg_accrights = (caddr_t) io; - msg.msg_accrightslen = sizeof(io); -# endif - - msg.msg_name = NULL; - msg.msg_namelen = 0; - msg.msg_iov = &iov; - msg.msg_iovlen = 1; - - ldap_pvt_thread_mutex_lock( &shell_surrogate_index_mutex ); - i = shell_surrogate_index ^= 1; - ldap_pvt_thread_mutex_unlock( &shell_surrogate_index_mutex ); - ldap_pvt_thread_mutex_lock( &shell_surrogate_fd_mutex[i] ); - c = (sendmsg( shell_surrogate_fd[i], &msg, 0 ) == 1 && - nwrite( shell_surrogate_fd[i], &args.bv_len, - sizeof(args.bv_len) ) == sizeof(args.bv_len) && - nwrite( shell_surrogate_fd[i], args.bv_val, - args.bv_len ) == args.bv_len && - nread( shell_surrogate_fd[i], &pid, - sizeof(pid) ) == sizeof(pid)); - ldap_pvt_thread_mutex_unlock( &shell_surrogate_fd_mutex[i] ); - close( p2c[0] ); - close( c2p[1] ); - if ( !c ) { - Debug( LDAP_DEBUG_ANY, "process creation failed\n", 0, 0, 0 ); - close( p2c[1] ); - close( c2p[0] ); - close( shell_surrogate_fd[0] ); - close( shell_surrogate_fd[1] ); - shell_surrogate_fd[0] = - shell_surrogate_fd[1] = -1; - return( -1 ); - } - } - -#else /* !SHELL_SURROGATE_PARENT */ - fflush( NULL ); # ifdef HAVE_THR pid = fork1(); @@ -353,8 +99,6 @@ forkandexec( return( -1 ); } -#endif /* SHELL_SURROGATE_PARENT */ - /* parent */ if ( (*rfp = fdopen( c2p[0], "r" )) == NULL || (*wfp = fdopen( p2c[1], "w" )) == NULL ) {