00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027 #include "pex-common.h"
00028
00029 #include <stdio.h>
00030 #include <errno.h>
00031 #ifdef NEED_DECLARATION_ERRNO
00032 extern int errno;
00033 #endif
00034 #ifdef HAVE_STRING_H
00035 #include <string.h>
00036 #endif
00037 #ifdef HAVE_UNISTD_H
00038 #include <unistd.h>
00039 #endif
00040 #ifdef HAVE_STDLIB_H
00041 #include <stdlib.h>
00042 #endif
00043 #ifdef HAVE_SYS_WAIT_H
00044 #include <sys/wait.h>
00045 #endif
00046
00047 #ifndef HAVE_WAITPID
00048 #define waitpid(pid, status, flags) wait(status)
00049 #endif
00050
00051 #ifdef vfork
00052 # define VFORK_STRING "fork"
00053 #else
00054 # define VFORK_STRING "vfork"
00055 #endif
00056 #ifdef HAVE_VFORK_H
00057 #include <vfork.h>
00058 #endif
00059 #ifdef VMS
00060 #define vfork() (decc$$alloc_vfork_blocks() >= 0 ? \
00061 lib$get_current_invo_context(decc$$get_vfork_jmpbuf()) : -1)
00062 #endif
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086 int
00087 pexecute (program, argv, this_pname, temp_base, errmsg_fmt, errmsg_arg,
00088 flagsarg)
00089 const char *program;
00090 char * const *argv;
00091 const char *this_pname;
00092 const char *temp_base ATTRIBUTE_UNUSED;
00093 char **errmsg_fmt, **errmsg_arg;
00094 int flagsarg;
00095 {
00096 int pid;
00097 int pdes[2];
00098 int out;
00099 int input_desc, output_desc;
00100 int flags;
00101
00102
00103 volatile int retries, sleep_interval;
00104
00105
00106
00107 static int last_pipe_input;
00108
00109 flags = flagsarg;
00110
00111
00112 if (flags & PEXECUTE_FIRST)
00113 last_pipe_input = STDIN_FILE_NO;
00114
00115 input_desc = last_pipe_input;
00116
00117
00118
00119 if (! (flags & PEXECUTE_LAST))
00120 {
00121 if (pipe (pdes) < 0)
00122 {
00123 *errmsg_fmt = "pipe";
00124 *errmsg_arg = NULL;
00125 return -1;
00126 }
00127 out = pdes[WRITE_PORT];
00128 last_pipe_input = pdes[READ_PORT];
00129 }
00130 else
00131 {
00132
00133 out = STDOUT_FILE_NO;
00134 last_pipe_input = STDIN_FILE_NO;
00135 }
00136
00137 output_desc = out;
00138
00139
00140 sleep_interval = 1;
00141 pid = -1;
00142 for (retries = 0; retries < 4; retries++)
00143 {
00144 pid = vfork ();
00145 if (pid >= 0)
00146 break;
00147 sleep (sleep_interval);
00148 sleep_interval *= 2;
00149 }
00150
00151 switch (pid)
00152 {
00153 case -1:
00154 *errmsg_fmt = "fork";
00155 *errmsg_arg = NULL;
00156 return -1;
00157
00158 case 0:
00159
00160 if (input_desc != STDIN_FILE_NO)
00161 {
00162 close (STDIN_FILE_NO);
00163 dup (input_desc);
00164 close (input_desc);
00165 }
00166 if (output_desc != STDOUT_FILE_NO)
00167 {
00168 close (STDOUT_FILE_NO);
00169 dup (output_desc);
00170 close (output_desc);
00171 }
00172
00173
00174 if (last_pipe_input != STDIN_FILE_NO)
00175 close (last_pipe_input);
00176
00177
00178 if (flags & PEXECUTE_SEARCH)
00179 execvp (program, argv);
00180 else
00181 execv (program, argv);
00182
00183
00184 #define writeerr(s) write (STDERR_FILE_NO, s, strlen (s))
00185 writeerr (this_pname);
00186 writeerr (": ");
00187 writeerr ("installation problem, cannot exec '");
00188 writeerr (program);
00189 writeerr ("': ");
00190 writeerr (xstrerror (errno));
00191 writeerr ("\n");
00192 _exit (-1);
00193
00194 return 0;
00195
00196 default:
00197
00198
00199 if (input_desc != STDIN_FILE_NO)
00200 close (input_desc);
00201 if (output_desc != STDOUT_FILE_NO)
00202 close (output_desc);
00203
00204
00205 return pid;
00206 }
00207 }
00208
00209 int
00210 pwait (pid, status, flags)
00211 int pid;
00212 int *status;
00213 int flags ATTRIBUTE_UNUSED;
00214 {
00215
00216
00217 pid = waitpid (pid, status, 0);
00218 return pid;
00219 }