]> git.sur5r.net Git - openldap/blob - servers/slapd/back-shell/fork.c
Fixup bdb_entry_release now that entry_decode uses two memory blocks
[openldap] / servers / slapd / back-shell / fork.c
1 /* fork.c - fork and exec a process, connecting stdin/out w/pipes */
2 /* $OpenLDAP$ */
3 /*
4  * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
5  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
6  */
7
8 #include "portable.h"
9
10 #include <stdio.h>
11
12 #include <ac/string.h>
13 #include <ac/socket.h>
14 #include <ac/unistd.h>
15
16 #include "slap.h"
17 #include "shell.h"
18
19 pid_t
20 forkandexec(
21     char        **args,
22     FILE        **rfp,
23     FILE        **wfp
24 )
25 {
26         int     p2c[2], c2p[2];
27         pid_t   pid;
28
29         if ( pipe( p2c ) != 0 || pipe( c2p ) != 0 ) {
30                 Debug( LDAP_DEBUG_ANY, "pipe failed\n", 0, 0, 0 );
31                 return( -1 );
32         }
33
34         /*
35          * what we're trying to set up looks like this:
36          *      parent *wfp -> p2c[1] | p2c[0] -> stdin child
37          *      parent *rfp <- c2p[0] | c2p[1] <- stdout child
38          */
39
40 #ifdef HAVE_THR
41         switch ( (pid = fork1()) )
42 #else
43         switch ( (pid = fork()) )
44 #endif
45         {
46         case 0:         /* child */
47                 /*
48                  * child could deadlock here due to resources locked
49                  * by our parent
50                  *
51                  * If so, configure --without-threads or implement forking
52                  * via a surrogate parent.
53                  */
54                 close( p2c[1] );
55                 close( c2p[0] );
56                 if ( dup2( p2c[0], 0 ) == -1 || dup2( c2p[1], 1 ) == -1 ) {
57                         Debug( LDAP_DEBUG_ANY, "dup2 failed\n", 0, 0, 0 );
58                         exit( EXIT_FAILURE );
59                 }
60
61                 execv( args[0], args );
62
63                 Debug( LDAP_DEBUG_ANY, "execv failed\n", 0, 0, 0 );
64                 exit( EXIT_FAILURE );
65
66         case -1:        /* trouble */
67                 Debug( LDAP_DEBUG_ANY, "fork failed\n", 0, 0, 0 );
68                 return( -1 );
69
70         default:        /* parent */
71                 close( p2c[0] );
72                 close( c2p[1] );
73                 break;
74         }
75
76         if ( (*rfp = fdopen( c2p[0], "r" )) == NULL || (*wfp = fdopen( p2c[1],
77             "w" )) == NULL ) {
78                 Debug( LDAP_DEBUG_ANY, "fdopen failed\n", 0, 0, 0 );
79                 close( c2p[0] );
80                 close( p2c[1] );
81
82                 return( -1 );
83         }
84
85         return( pid );
86 }