X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=servers%2Fslapd%2Fback-shell%2Ffork.c;h=8175657b433dbb57c99283b57ee9f1ab120d371a;hb=aa33f4b220924d9b054c5acbce3440dadef41a27;hp=aff0e5bbe446778c06ec249e3312b0d435c077b5;hpb=42e0d83cb3a1a1c5b25183f1ab74ce7edbe25de7;p=openldap diff --git a/servers/slapd/back-shell/fork.c b/servers/slapd/back-shell/fork.c index aff0e5bbe4..8175657b43 100644 --- a/servers/slapd/back-shell/fork.c +++ b/servers/slapd/back-shell/fork.c @@ -1,22 +1,59 @@ /* fork.c - fork and exec a process, connecting stdin/out w/pipes */ +/* $OpenLDAP$ */ +/* This work is part of OpenLDAP Software . + * + * Copyright 1998-2012 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" #include -#include -#include -#include + +#include +#include +#include +#include + #include "slap.h" +#include "shell.h" +pid_t forkandexec( char **args, FILE **rfp, FILE **wfp ) { - int p2c[2], c2p[2]; - int pid; + int p2c[2] = { -1, -1 }, c2p[2]; + pid_t pid; if ( pipe( p2c ) != 0 || pipe( c2p ) != 0 ) { Debug( LDAP_DEBUG_ANY, "pipe failed\n", 0, 0, 0 ); + close( p2c[0] ); + close( p2c[1] ); return( -1 ); } @@ -26,34 +63,52 @@ forkandexec( * parent *rfp <- c2p[0] | c2p[1] <- stdout child */ - switch ( (pid = fork()) ) { - case 0: /* child */ - close( p2c[1] ); - close( c2p[0] ); + fflush( NULL ); +# ifdef HAVE_THR + pid = fork1(); +# else + pid = fork(); +# endif + if ( pid == 0 ) { /* child */ + /* + * child could deadlock here due to resources locked + * by our parent + * + * If so, configure --without-threads. + */ if ( dup2( p2c[0], 0 ) == -1 || dup2( c2p[1], 1 ) == -1 ) { Debug( LDAP_DEBUG_ANY, "dup2 failed\n", 0, 0, 0 ); - exit( -1 ); + exit( EXIT_FAILURE ); } - + } + close( p2c[0] ); + close( c2p[1] ); + if ( pid <= 0 ) { + close( p2c[1] ); + close( c2p[0] ); + } + switch ( pid ) { + case 0: execv( args[0], args ); Debug( LDAP_DEBUG_ANY, "execv failed\n", 0, 0, 0 ); - exit( -1 ); + exit( EXIT_FAILURE ); case -1: /* trouble */ Debug( LDAP_DEBUG_ANY, "fork failed\n", 0, 0, 0 ); return( -1 ); - - default: /* parent */ - close( p2c[0] ); - close( c2p[1] ); - break; } + /* parent */ if ( (*rfp = fdopen( c2p[0], "r" )) == NULL || (*wfp = fdopen( p2c[1], "w" )) == NULL ) { Debug( LDAP_DEBUG_ANY, "fdopen failed\n", 0, 0, 0 ); - close( c2p[0] ); + if ( *rfp ) { + fclose( *rfp ); + *rfp = NULL; + } else { + close( c2p[0] ); + } close( p2c[1] ); return( -1 );