Home | History | Annotate | Line # | Download | only in libiberty
pex-common.c revision 1.1.1.1.8.2
      1  1.1.1.1.8.2  tls /* Common code for executing a program in a sub-process.
      2  1.1.1.1.8.2  tls    Copyright (C) 2005 Free Software Foundation, Inc.
      3  1.1.1.1.8.2  tls    Written by Ian Lance Taylor <ian (at) airs.com>.
      4  1.1.1.1.8.2  tls 
      5  1.1.1.1.8.2  tls This file is part of the libiberty library.
      6  1.1.1.1.8.2  tls Libiberty is free software; you can redistribute it and/or
      7  1.1.1.1.8.2  tls modify it under the terms of the GNU Library General Public
      8  1.1.1.1.8.2  tls License as published by the Free Software Foundation; either
      9  1.1.1.1.8.2  tls version 2 of the License, or (at your option) any later version.
     10  1.1.1.1.8.2  tls 
     11  1.1.1.1.8.2  tls Libiberty is distributed in the hope that it will be useful,
     12  1.1.1.1.8.2  tls but WITHOUT ANY WARRANTY; without even the implied warranty of
     13  1.1.1.1.8.2  tls MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     14  1.1.1.1.8.2  tls Library General Public License for more details.
     15  1.1.1.1.8.2  tls 
     16  1.1.1.1.8.2  tls You should have received a copy of the GNU Library General Public
     17  1.1.1.1.8.2  tls License along with libiberty; see the file COPYING.LIB.  If not,
     18  1.1.1.1.8.2  tls write to the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor,
     19  1.1.1.1.8.2  tls Boston, MA 02110-1301, USA.  */
     20  1.1.1.1.8.2  tls 
     21  1.1.1.1.8.2  tls #include "config.h"
     22  1.1.1.1.8.2  tls #include "libiberty.h"
     23  1.1.1.1.8.2  tls #include "pex-common.h"
     24  1.1.1.1.8.2  tls 
     25  1.1.1.1.8.2  tls #include <stdio.h>
     26  1.1.1.1.8.2  tls #include <errno.h>
     27  1.1.1.1.8.2  tls #ifdef NEED_DECLARATION_ERRNO
     28  1.1.1.1.8.2  tls extern int errno;
     29  1.1.1.1.8.2  tls #endif
     30  1.1.1.1.8.2  tls #ifdef HAVE_STDLIB_H
     31  1.1.1.1.8.2  tls #include <stdlib.h>
     32  1.1.1.1.8.2  tls #endif
     33  1.1.1.1.8.2  tls #ifdef HAVE_STRING_H
     34  1.1.1.1.8.2  tls #include <string.h>
     35  1.1.1.1.8.2  tls #endif
     36  1.1.1.1.8.2  tls #ifdef HAVE_UNISTD_H
     37  1.1.1.1.8.2  tls #include <unistd.h>
     38  1.1.1.1.8.2  tls #endif
     39  1.1.1.1.8.2  tls 
     40  1.1.1.1.8.2  tls extern int mkstemps (char *, int);
     41  1.1.1.1.8.2  tls 
     42  1.1.1.1.8.2  tls /* This file contains subroutines for the program execution routines
     43  1.1.1.1.8.2  tls    (pex_init, pex_run, etc.).  This file is compiled on all
     44  1.1.1.1.8.2  tls    systems.  */
     45  1.1.1.1.8.2  tls 
     46  1.1.1.1.8.2  tls static void pex_add_remove (struct pex_obj *, const char *, int);
     47  1.1.1.1.8.2  tls static int pex_get_status_and_time (struct pex_obj *, int, const char **,
     48  1.1.1.1.8.2  tls 				    int *);
     49  1.1.1.1.8.2  tls 
     50  1.1.1.1.8.2  tls /* Initialize a pex_obj structure.  */
     51  1.1.1.1.8.2  tls 
     52  1.1.1.1.8.2  tls struct pex_obj *
     53  1.1.1.1.8.2  tls pex_init_common (int flags, const char *pname, const char *tempbase,
     54  1.1.1.1.8.2  tls 		 const struct pex_funcs *funcs)
     55  1.1.1.1.8.2  tls {
     56  1.1.1.1.8.2  tls   struct pex_obj *obj;
     57  1.1.1.1.8.2  tls 
     58  1.1.1.1.8.2  tls   obj = XNEW (struct pex_obj);
     59  1.1.1.1.8.2  tls   obj->flags = flags;
     60  1.1.1.1.8.2  tls   obj->pname = pname;
     61  1.1.1.1.8.2  tls   obj->tempbase = tempbase;
     62  1.1.1.1.8.2  tls   obj->next_input = STDIN_FILE_NO;
     63  1.1.1.1.8.2  tls   obj->next_input_name = NULL;
     64  1.1.1.1.8.2  tls   obj->next_input_name_allocated = 0;
     65  1.1.1.1.8.2  tls   obj->stderr_pipe = -1;
     66  1.1.1.1.8.2  tls   obj->count = 0;
     67  1.1.1.1.8.2  tls   obj->children = NULL;
     68  1.1.1.1.8.2  tls   obj->status = NULL;
     69  1.1.1.1.8.2  tls   obj->time = NULL;
     70  1.1.1.1.8.2  tls   obj->number_waited = 0;
     71  1.1.1.1.8.2  tls   obj->input_file = NULL;
     72  1.1.1.1.8.2  tls   obj->read_output = NULL;
     73  1.1.1.1.8.2  tls   obj->read_err = NULL;
     74  1.1.1.1.8.2  tls   obj->remove_count = 0;
     75  1.1.1.1.8.2  tls   obj->remove = NULL;
     76  1.1.1.1.8.2  tls   obj->funcs = funcs;
     77  1.1.1.1.8.2  tls   obj->sysdep = NULL;
     78  1.1.1.1.8.2  tls   return obj;
     79  1.1.1.1.8.2  tls }
     80  1.1.1.1.8.2  tls 
     81  1.1.1.1.8.2  tls /* Add a file to be removed when we are done.  */
     82  1.1.1.1.8.2  tls 
     83  1.1.1.1.8.2  tls static void
     84  1.1.1.1.8.2  tls pex_add_remove (struct pex_obj *obj, const char *name, int allocated)
     85  1.1.1.1.8.2  tls {
     86  1.1.1.1.8.2  tls   char *add;
     87  1.1.1.1.8.2  tls 
     88  1.1.1.1.8.2  tls   ++obj->remove_count;
     89  1.1.1.1.8.2  tls   obj->remove = XRESIZEVEC (char *, obj->remove, obj->remove_count);
     90  1.1.1.1.8.2  tls   if (allocated)
     91  1.1.1.1.8.2  tls     add = (char *) name;
     92  1.1.1.1.8.2  tls   else
     93  1.1.1.1.8.2  tls     add = xstrdup (name);
     94  1.1.1.1.8.2  tls   obj->remove[obj->remove_count - 1] = add;
     95  1.1.1.1.8.2  tls }
     96  1.1.1.1.8.2  tls 
     97  1.1.1.1.8.2  tls /* Generate a temporary file name based on OBJ, FLAGS, and NAME.
     98  1.1.1.1.8.2  tls    Return NULL if we were unable to reserve a temporary filename.
     99  1.1.1.1.8.2  tls 
    100  1.1.1.1.8.2  tls    If non-NULL, the result is either allocated with malloc, or the
    101  1.1.1.1.8.2  tls    same pointer as NAME.  */
    102  1.1.1.1.8.2  tls static char *
    103  1.1.1.1.8.2  tls temp_file (struct pex_obj *obj, int flags, char *name)
    104  1.1.1.1.8.2  tls {
    105  1.1.1.1.8.2  tls   if (name == NULL)
    106  1.1.1.1.8.2  tls     {
    107  1.1.1.1.8.2  tls       if (obj->tempbase == NULL)
    108  1.1.1.1.8.2  tls         {
    109  1.1.1.1.8.2  tls           name = make_temp_file (NULL);
    110  1.1.1.1.8.2  tls         }
    111  1.1.1.1.8.2  tls       else
    112  1.1.1.1.8.2  tls         {
    113  1.1.1.1.8.2  tls           int len = strlen (obj->tempbase);
    114  1.1.1.1.8.2  tls           int out;
    115  1.1.1.1.8.2  tls 
    116  1.1.1.1.8.2  tls           if (len >= 6
    117  1.1.1.1.8.2  tls               && strcmp (obj->tempbase + len - 6, "XXXXXX") == 0)
    118  1.1.1.1.8.2  tls             name = xstrdup (obj->tempbase);
    119  1.1.1.1.8.2  tls           else
    120  1.1.1.1.8.2  tls             name = concat (obj->tempbase, "XXXXXX", NULL);
    121  1.1.1.1.8.2  tls 
    122  1.1.1.1.8.2  tls           out = mkstemps (name, 0);
    123  1.1.1.1.8.2  tls           if (out < 0)
    124  1.1.1.1.8.2  tls             {
    125  1.1.1.1.8.2  tls               free (name);
    126  1.1.1.1.8.2  tls               return NULL;
    127  1.1.1.1.8.2  tls             }
    128  1.1.1.1.8.2  tls 
    129  1.1.1.1.8.2  tls           /* This isn't obj->funcs->close because we got the
    130  1.1.1.1.8.2  tls              descriptor from mkstemps, not from a function in
    131  1.1.1.1.8.2  tls              obj->funcs.  Calling close here is just like what
    132  1.1.1.1.8.2  tls              make_temp_file does.  */
    133  1.1.1.1.8.2  tls           close (out);
    134  1.1.1.1.8.2  tls         }
    135  1.1.1.1.8.2  tls     }
    136  1.1.1.1.8.2  tls   else if ((flags & PEX_SUFFIX) != 0)
    137  1.1.1.1.8.2  tls     {
    138  1.1.1.1.8.2  tls       if (obj->tempbase == NULL)
    139  1.1.1.1.8.2  tls         name = make_temp_file (name);
    140  1.1.1.1.8.2  tls       else
    141  1.1.1.1.8.2  tls         name = concat (obj->tempbase, name, NULL);
    142  1.1.1.1.8.2  tls     }
    143  1.1.1.1.8.2  tls 
    144  1.1.1.1.8.2  tls   return name;
    145  1.1.1.1.8.2  tls }
    146  1.1.1.1.8.2  tls 
    147  1.1.1.1.8.2  tls 
    148  1.1.1.1.8.2  tls /* As for pex_run (), but permits the environment for the child process
    149  1.1.1.1.8.2  tls    to be specified. */
    150  1.1.1.1.8.2  tls 
    151  1.1.1.1.8.2  tls const char *
    152  1.1.1.1.8.2  tls pex_run_in_environment (struct pex_obj *obj, int flags, const char *executable,
    153  1.1.1.1.8.2  tls        	                char * const * argv, char * const * env,
    154  1.1.1.1.8.2  tls                         const char *orig_outname, const char *errname,
    155  1.1.1.1.8.2  tls                   	int *err)
    156  1.1.1.1.8.2  tls {
    157  1.1.1.1.8.2  tls   const char *errmsg;
    158  1.1.1.1.8.2  tls   int in, out, errdes;
    159  1.1.1.1.8.2  tls   char *outname;
    160  1.1.1.1.8.2  tls   int outname_allocated;
    161  1.1.1.1.8.2  tls   int p[2];
    162  1.1.1.1.8.2  tls   int toclose;
    163  1.1.1.1.8.2  tls   pid_t pid;
    164  1.1.1.1.8.2  tls 
    165  1.1.1.1.8.2  tls   in = -1;
    166  1.1.1.1.8.2  tls   out = -1;
    167  1.1.1.1.8.2  tls   errdes = -1;
    168  1.1.1.1.8.2  tls   outname = (char *) orig_outname;
    169  1.1.1.1.8.2  tls   outname_allocated = 0;
    170  1.1.1.1.8.2  tls 
    171  1.1.1.1.8.2  tls   /* If the user called pex_input_file, close the file now.  */
    172  1.1.1.1.8.2  tls   if (obj->input_file)
    173  1.1.1.1.8.2  tls     {
    174  1.1.1.1.8.2  tls       if (fclose (obj->input_file) == EOF)
    175  1.1.1.1.8.2  tls         {
    176  1.1.1.1.8.2  tls           errmsg = "closing pipeline input file";
    177  1.1.1.1.8.2  tls           goto error_exit;
    178  1.1.1.1.8.2  tls         }
    179  1.1.1.1.8.2  tls       obj->input_file = NULL;
    180  1.1.1.1.8.2  tls     }
    181  1.1.1.1.8.2  tls 
    182  1.1.1.1.8.2  tls   /* Set IN.  */
    183  1.1.1.1.8.2  tls 
    184  1.1.1.1.8.2  tls   if (obj->next_input_name != NULL)
    185  1.1.1.1.8.2  tls     {
    186  1.1.1.1.8.2  tls       /* We have to make sure that the previous process has completed
    187  1.1.1.1.8.2  tls 	 before we try to read the file.  */
    188  1.1.1.1.8.2  tls       if (!pex_get_status_and_time (obj, 0, &errmsg, err))
    189  1.1.1.1.8.2  tls 	goto error_exit;
    190  1.1.1.1.8.2  tls 
    191  1.1.1.1.8.2  tls       in = obj->funcs->open_read (obj, obj->next_input_name,
    192  1.1.1.1.8.2  tls 				  (flags & PEX_BINARY_INPUT) != 0);
    193  1.1.1.1.8.2  tls       if (in < 0)
    194  1.1.1.1.8.2  tls 	{
    195  1.1.1.1.8.2  tls 	  *err = errno;
    196  1.1.1.1.8.2  tls 	  errmsg = "open temporary file";
    197  1.1.1.1.8.2  tls 	  goto error_exit;
    198  1.1.1.1.8.2  tls 	}
    199  1.1.1.1.8.2  tls       if (obj->next_input_name_allocated)
    200  1.1.1.1.8.2  tls 	{
    201  1.1.1.1.8.2  tls 	  free (obj->next_input_name);
    202  1.1.1.1.8.2  tls 	  obj->next_input_name_allocated = 0;
    203  1.1.1.1.8.2  tls 	}
    204  1.1.1.1.8.2  tls       obj->next_input_name = NULL;
    205  1.1.1.1.8.2  tls     }
    206  1.1.1.1.8.2  tls   else
    207  1.1.1.1.8.2  tls     {
    208  1.1.1.1.8.2  tls       in = obj->next_input;
    209  1.1.1.1.8.2  tls       if (in < 0)
    210  1.1.1.1.8.2  tls 	{
    211  1.1.1.1.8.2  tls 	  *err = 0;
    212  1.1.1.1.8.2  tls 	  errmsg = "pipeline already complete";
    213  1.1.1.1.8.2  tls 	  goto error_exit;
    214  1.1.1.1.8.2  tls 	}
    215  1.1.1.1.8.2  tls     }
    216  1.1.1.1.8.2  tls 
    217  1.1.1.1.8.2  tls   /* Set OUT and OBJ->NEXT_INPUT/OBJ->NEXT_INPUT_NAME.  */
    218  1.1.1.1.8.2  tls 
    219  1.1.1.1.8.2  tls   if ((flags & PEX_LAST) != 0)
    220  1.1.1.1.8.2  tls     {
    221  1.1.1.1.8.2  tls       if (outname == NULL)
    222  1.1.1.1.8.2  tls 	out = STDOUT_FILE_NO;
    223  1.1.1.1.8.2  tls       else if ((flags & PEX_SUFFIX) != 0)
    224  1.1.1.1.8.2  tls 	{
    225  1.1.1.1.8.2  tls 	  outname = concat (obj->tempbase, outname, NULL);
    226  1.1.1.1.8.2  tls 	  outname_allocated = 1;
    227  1.1.1.1.8.2  tls 	}
    228  1.1.1.1.8.2  tls       obj->next_input = -1;
    229  1.1.1.1.8.2  tls     }
    230  1.1.1.1.8.2  tls   else if ((obj->flags & PEX_USE_PIPES) == 0)
    231  1.1.1.1.8.2  tls     {
    232  1.1.1.1.8.2  tls       outname = temp_file (obj, flags, outname);
    233  1.1.1.1.8.2  tls       if (! outname)
    234  1.1.1.1.8.2  tls         {
    235  1.1.1.1.8.2  tls           *err = 0;
    236  1.1.1.1.8.2  tls           errmsg = "could not create temporary file";
    237  1.1.1.1.8.2  tls           goto error_exit;
    238  1.1.1.1.8.2  tls         }
    239  1.1.1.1.8.2  tls 
    240  1.1.1.1.8.2  tls       if (outname != orig_outname)
    241  1.1.1.1.8.2  tls         outname_allocated = 1;
    242  1.1.1.1.8.2  tls 
    243  1.1.1.1.8.2  tls       if ((obj->flags & PEX_SAVE_TEMPS) == 0)
    244  1.1.1.1.8.2  tls 	{
    245  1.1.1.1.8.2  tls 	  pex_add_remove (obj, outname, outname_allocated);
    246  1.1.1.1.8.2  tls 	  outname_allocated = 0;
    247  1.1.1.1.8.2  tls 	}
    248  1.1.1.1.8.2  tls 
    249  1.1.1.1.8.2  tls       /* Hand off ownership of outname to the next stage.  */
    250  1.1.1.1.8.2  tls       obj->next_input_name = outname;
    251  1.1.1.1.8.2  tls       obj->next_input_name_allocated = outname_allocated;
    252  1.1.1.1.8.2  tls       outname_allocated = 0;
    253  1.1.1.1.8.2  tls     }
    254  1.1.1.1.8.2  tls   else
    255  1.1.1.1.8.2  tls     {
    256  1.1.1.1.8.2  tls       if (obj->funcs->pipe (obj, p, (flags & PEX_BINARY_OUTPUT) != 0) < 0)
    257  1.1.1.1.8.2  tls 	{
    258  1.1.1.1.8.2  tls 	  *err = errno;
    259  1.1.1.1.8.2  tls 	  errmsg = "pipe";
    260  1.1.1.1.8.2  tls 	  goto error_exit;
    261  1.1.1.1.8.2  tls 	}
    262  1.1.1.1.8.2  tls 
    263  1.1.1.1.8.2  tls       out = p[WRITE_PORT];
    264  1.1.1.1.8.2  tls       obj->next_input = p[READ_PORT];
    265  1.1.1.1.8.2  tls     }
    266  1.1.1.1.8.2  tls 
    267  1.1.1.1.8.2  tls   if (out < 0)
    268  1.1.1.1.8.2  tls     {
    269  1.1.1.1.8.2  tls       out = obj->funcs->open_write (obj, outname,
    270  1.1.1.1.8.2  tls 				    (flags & PEX_BINARY_OUTPUT) != 0);
    271  1.1.1.1.8.2  tls       if (out < 0)
    272  1.1.1.1.8.2  tls 	{
    273  1.1.1.1.8.2  tls 	  *err = errno;
    274  1.1.1.1.8.2  tls 	  errmsg = "open temporary output file";
    275  1.1.1.1.8.2  tls 	  goto error_exit;
    276  1.1.1.1.8.2  tls 	}
    277  1.1.1.1.8.2  tls     }
    278  1.1.1.1.8.2  tls 
    279  1.1.1.1.8.2  tls   if (outname_allocated)
    280  1.1.1.1.8.2  tls     {
    281  1.1.1.1.8.2  tls       free (outname);
    282  1.1.1.1.8.2  tls       outname_allocated = 0;
    283  1.1.1.1.8.2  tls     }
    284  1.1.1.1.8.2  tls 
    285  1.1.1.1.8.2  tls   /* Set ERRDES.  */
    286  1.1.1.1.8.2  tls 
    287  1.1.1.1.8.2  tls   if (errname != NULL && (flags & PEX_STDERR_TO_PIPE) != 0)
    288  1.1.1.1.8.2  tls     {
    289  1.1.1.1.8.2  tls       *err = 0;
    290  1.1.1.1.8.2  tls       errmsg = "both ERRNAME and PEX_STDERR_TO_PIPE specified.";
    291  1.1.1.1.8.2  tls       goto error_exit;
    292  1.1.1.1.8.2  tls     }
    293  1.1.1.1.8.2  tls 
    294  1.1.1.1.8.2  tls   if (obj->stderr_pipe != -1)
    295  1.1.1.1.8.2  tls     {
    296  1.1.1.1.8.2  tls       *err = 0;
    297  1.1.1.1.8.2  tls       errmsg = "PEX_STDERR_TO_PIPE used in the middle of pipeline";
    298  1.1.1.1.8.2  tls       goto error_exit;
    299  1.1.1.1.8.2  tls     }
    300  1.1.1.1.8.2  tls 
    301  1.1.1.1.8.2  tls   if (errname == NULL)
    302  1.1.1.1.8.2  tls     {
    303  1.1.1.1.8.2  tls       if (flags & PEX_STDERR_TO_PIPE)
    304  1.1.1.1.8.2  tls 	{
    305  1.1.1.1.8.2  tls 	  if (obj->funcs->pipe (obj, p, (flags & PEX_BINARY_ERROR) != 0) < 0)
    306  1.1.1.1.8.2  tls 	    {
    307  1.1.1.1.8.2  tls 	      *err = errno;
    308  1.1.1.1.8.2  tls 	      errmsg = "pipe";
    309  1.1.1.1.8.2  tls 	      goto error_exit;
    310  1.1.1.1.8.2  tls 	    }
    311  1.1.1.1.8.2  tls 
    312  1.1.1.1.8.2  tls 	  errdes = p[WRITE_PORT];
    313  1.1.1.1.8.2  tls 	  obj->stderr_pipe = p[READ_PORT];
    314  1.1.1.1.8.2  tls 	}
    315  1.1.1.1.8.2  tls       else
    316  1.1.1.1.8.2  tls 	{
    317  1.1.1.1.8.2  tls 	  errdes = STDERR_FILE_NO;
    318  1.1.1.1.8.2  tls 	}
    319  1.1.1.1.8.2  tls     }
    320  1.1.1.1.8.2  tls   else
    321  1.1.1.1.8.2  tls     {
    322  1.1.1.1.8.2  tls       errdes = obj->funcs->open_write (obj, errname,
    323  1.1.1.1.8.2  tls 				       (flags & PEX_BINARY_ERROR) != 0);
    324  1.1.1.1.8.2  tls       if (errdes < 0)
    325  1.1.1.1.8.2  tls 	{
    326  1.1.1.1.8.2  tls 	  *err = errno;
    327  1.1.1.1.8.2  tls 	  errmsg = "open error file";
    328  1.1.1.1.8.2  tls 	  goto error_exit;
    329  1.1.1.1.8.2  tls 	}
    330  1.1.1.1.8.2  tls     }
    331  1.1.1.1.8.2  tls 
    332  1.1.1.1.8.2  tls   /* If we are using pipes, the child process has to close the next
    333  1.1.1.1.8.2  tls      input pipe.  */
    334  1.1.1.1.8.2  tls 
    335  1.1.1.1.8.2  tls   if ((obj->flags & PEX_USE_PIPES) == 0)
    336  1.1.1.1.8.2  tls     toclose = -1;
    337  1.1.1.1.8.2  tls   else
    338  1.1.1.1.8.2  tls     toclose = obj->next_input;
    339  1.1.1.1.8.2  tls 
    340  1.1.1.1.8.2  tls   /* Run the program.  */
    341  1.1.1.1.8.2  tls 
    342  1.1.1.1.8.2  tls   pid = obj->funcs->exec_child (obj, flags, executable, argv, env,
    343  1.1.1.1.8.2  tls 				in, out, errdes, toclose, &errmsg, err);
    344  1.1.1.1.8.2  tls   if (pid < 0)
    345  1.1.1.1.8.2  tls     goto error_exit;
    346  1.1.1.1.8.2  tls 
    347  1.1.1.1.8.2  tls   ++obj->count;
    348  1.1.1.1.8.2  tls   obj->children = XRESIZEVEC (pid_t, obj->children, obj->count);
    349  1.1.1.1.8.2  tls   obj->children[obj->count - 1] = pid;
    350  1.1.1.1.8.2  tls 
    351  1.1.1.1.8.2  tls   return NULL;
    352  1.1.1.1.8.2  tls 
    353  1.1.1.1.8.2  tls  error_exit:
    354  1.1.1.1.8.2  tls   if (in >= 0 && in != STDIN_FILE_NO)
    355  1.1.1.1.8.2  tls     obj->funcs->close (obj, in);
    356  1.1.1.1.8.2  tls   if (out >= 0 && out != STDOUT_FILE_NO)
    357  1.1.1.1.8.2  tls     obj->funcs->close (obj, out);
    358  1.1.1.1.8.2  tls   if (errdes >= 0 && errdes != STDERR_FILE_NO)
    359  1.1.1.1.8.2  tls     obj->funcs->close (obj, errdes);
    360  1.1.1.1.8.2  tls   if (outname_allocated)
    361  1.1.1.1.8.2  tls     free (outname);
    362  1.1.1.1.8.2  tls   return errmsg;
    363  1.1.1.1.8.2  tls }
    364  1.1.1.1.8.2  tls 
    365  1.1.1.1.8.2  tls /* Run a program.  */
    366  1.1.1.1.8.2  tls 
    367  1.1.1.1.8.2  tls const char *
    368  1.1.1.1.8.2  tls pex_run (struct pex_obj *obj, int flags, const char *executable,
    369  1.1.1.1.8.2  tls        	 char * const * argv, const char *orig_outname, const char *errname,
    370  1.1.1.1.8.2  tls          int *err)
    371  1.1.1.1.8.2  tls {
    372  1.1.1.1.8.2  tls   return pex_run_in_environment (obj, flags, executable, argv, NULL,
    373  1.1.1.1.8.2  tls 				 orig_outname, errname, err);
    374  1.1.1.1.8.2  tls }
    375  1.1.1.1.8.2  tls 
    376  1.1.1.1.8.2  tls /* Return a FILE pointer for a temporary file to fill with input for
    377  1.1.1.1.8.2  tls    the pipeline.  */
    378  1.1.1.1.8.2  tls FILE *
    379  1.1.1.1.8.2  tls pex_input_file (struct pex_obj *obj, int flags, const char *in_name)
    380  1.1.1.1.8.2  tls {
    381  1.1.1.1.8.2  tls   char *name = (char *) in_name;
    382  1.1.1.1.8.2  tls   FILE *f;
    383  1.1.1.1.8.2  tls 
    384  1.1.1.1.8.2  tls   /* This must be called before the first pipeline stage is run, and
    385  1.1.1.1.8.2  tls      there must not have been any other input selected.  */
    386  1.1.1.1.8.2  tls   if (obj->count != 0
    387  1.1.1.1.8.2  tls       || (obj->next_input >= 0 && obj->next_input != STDIN_FILE_NO)
    388  1.1.1.1.8.2  tls       || obj->next_input_name)
    389  1.1.1.1.8.2  tls     {
    390  1.1.1.1.8.2  tls       errno = EINVAL;
    391  1.1.1.1.8.2  tls       return NULL;
    392  1.1.1.1.8.2  tls     }
    393  1.1.1.1.8.2  tls 
    394  1.1.1.1.8.2  tls   name = temp_file (obj, flags, name);
    395  1.1.1.1.8.2  tls   if (! name)
    396  1.1.1.1.8.2  tls     return NULL;
    397  1.1.1.1.8.2  tls 
    398  1.1.1.1.8.2  tls   f = fopen (name, (flags & PEX_BINARY_OUTPUT) ? "wb" : "w");
    399  1.1.1.1.8.2  tls   if (! f)
    400  1.1.1.1.8.2  tls     {
    401  1.1.1.1.8.2  tls       free (name);
    402  1.1.1.1.8.2  tls       return NULL;
    403  1.1.1.1.8.2  tls     }
    404  1.1.1.1.8.2  tls 
    405  1.1.1.1.8.2  tls   obj->input_file = f;
    406  1.1.1.1.8.2  tls   obj->next_input_name = name;
    407  1.1.1.1.8.2  tls   obj->next_input_name_allocated = (name != in_name);
    408  1.1.1.1.8.2  tls 
    409  1.1.1.1.8.2  tls   return f;
    410  1.1.1.1.8.2  tls }
    411  1.1.1.1.8.2  tls 
    412  1.1.1.1.8.2  tls /* Return a stream for a pipe connected to the standard input of the
    413  1.1.1.1.8.2  tls    first stage of the pipeline.  */
    414  1.1.1.1.8.2  tls FILE *
    415  1.1.1.1.8.2  tls pex_input_pipe (struct pex_obj *obj, int binary)
    416  1.1.1.1.8.2  tls {
    417  1.1.1.1.8.2  tls   int p[2];
    418  1.1.1.1.8.2  tls   FILE *f;
    419  1.1.1.1.8.2  tls 
    420  1.1.1.1.8.2  tls   /* You must call pex_input_pipe before the first pex_run or pex_one.  */
    421  1.1.1.1.8.2  tls   if (obj->count > 0)
    422  1.1.1.1.8.2  tls     goto usage_error;
    423  1.1.1.1.8.2  tls 
    424  1.1.1.1.8.2  tls   /* You must be using pipes.  Implementations that don't support
    425  1.1.1.1.8.2  tls      pipes clear this flag before calling pex_init_common.  */
    426  1.1.1.1.8.2  tls   if (! (obj->flags & PEX_USE_PIPES))
    427  1.1.1.1.8.2  tls     goto usage_error;
    428  1.1.1.1.8.2  tls 
    429  1.1.1.1.8.2  tls   /* If we have somehow already selected other input, that's a
    430  1.1.1.1.8.2  tls      mistake.  */
    431  1.1.1.1.8.2  tls   if ((obj->next_input >= 0 && obj->next_input != STDIN_FILE_NO)
    432  1.1.1.1.8.2  tls       || obj->next_input_name)
    433  1.1.1.1.8.2  tls     goto usage_error;
    434  1.1.1.1.8.2  tls 
    435  1.1.1.1.8.2  tls   if (obj->funcs->pipe (obj, p, binary != 0) < 0)
    436  1.1.1.1.8.2  tls     return NULL;
    437  1.1.1.1.8.2  tls 
    438  1.1.1.1.8.2  tls   f = obj->funcs->fdopenw (obj, p[WRITE_PORT], binary != 0);
    439  1.1.1.1.8.2  tls   if (! f)
    440  1.1.1.1.8.2  tls     {
    441  1.1.1.1.8.2  tls       int saved_errno = errno;
    442  1.1.1.1.8.2  tls       obj->funcs->close (obj, p[READ_PORT]);
    443  1.1.1.1.8.2  tls       obj->funcs->close (obj, p[WRITE_PORT]);
    444  1.1.1.1.8.2  tls       errno = saved_errno;
    445  1.1.1.1.8.2  tls       return NULL;
    446  1.1.1.1.8.2  tls     }
    447  1.1.1.1.8.2  tls 
    448  1.1.1.1.8.2  tls   obj->next_input = p[READ_PORT];
    449  1.1.1.1.8.2  tls 
    450  1.1.1.1.8.2  tls   return f;
    451  1.1.1.1.8.2  tls 
    452  1.1.1.1.8.2  tls  usage_error:
    453  1.1.1.1.8.2  tls   errno = EINVAL;
    454  1.1.1.1.8.2  tls   return NULL;
    455  1.1.1.1.8.2  tls }
    456  1.1.1.1.8.2  tls 
    457  1.1.1.1.8.2  tls /* Return a FILE pointer for the output of the last program
    458  1.1.1.1.8.2  tls    executed.  */
    459  1.1.1.1.8.2  tls 
    460  1.1.1.1.8.2  tls FILE *
    461  1.1.1.1.8.2  tls pex_read_output (struct pex_obj *obj, int binary)
    462  1.1.1.1.8.2  tls {
    463  1.1.1.1.8.2  tls   if (obj->next_input_name != NULL)
    464  1.1.1.1.8.2  tls     {
    465  1.1.1.1.8.2  tls       const char *errmsg;
    466  1.1.1.1.8.2  tls       int err;
    467  1.1.1.1.8.2  tls 
    468  1.1.1.1.8.2  tls       /* We have to make sure that the process has completed before we
    469  1.1.1.1.8.2  tls 	 try to read the file.  */
    470  1.1.1.1.8.2  tls       if (!pex_get_status_and_time (obj, 0, &errmsg, &err))
    471  1.1.1.1.8.2  tls 	{
    472  1.1.1.1.8.2  tls 	  errno = err;
    473  1.1.1.1.8.2  tls 	  return NULL;
    474  1.1.1.1.8.2  tls 	}
    475  1.1.1.1.8.2  tls 
    476  1.1.1.1.8.2  tls       obj->read_output = fopen (obj->next_input_name, binary ? "rb" : "r");
    477  1.1.1.1.8.2  tls 
    478  1.1.1.1.8.2  tls       if (obj->next_input_name_allocated)
    479  1.1.1.1.8.2  tls 	{
    480  1.1.1.1.8.2  tls 	  free (obj->next_input_name);
    481  1.1.1.1.8.2  tls 	  obj->next_input_name_allocated = 0;
    482  1.1.1.1.8.2  tls 	}
    483  1.1.1.1.8.2  tls       obj->next_input_name = NULL;
    484  1.1.1.1.8.2  tls     }
    485  1.1.1.1.8.2  tls   else
    486  1.1.1.1.8.2  tls     {
    487  1.1.1.1.8.2  tls       int o;
    488  1.1.1.1.8.2  tls 
    489  1.1.1.1.8.2  tls       o = obj->next_input;
    490  1.1.1.1.8.2  tls       if (o < 0 || o == STDIN_FILE_NO)
    491  1.1.1.1.8.2  tls 	return NULL;
    492  1.1.1.1.8.2  tls       obj->read_output = obj->funcs->fdopenr (obj, o, binary);
    493  1.1.1.1.8.2  tls       obj->next_input = -1;
    494  1.1.1.1.8.2  tls     }
    495  1.1.1.1.8.2  tls 
    496  1.1.1.1.8.2  tls   return obj->read_output;
    497  1.1.1.1.8.2  tls }
    498  1.1.1.1.8.2  tls 
    499  1.1.1.1.8.2  tls FILE *
    500  1.1.1.1.8.2  tls pex_read_err (struct pex_obj *obj, int binary)
    501  1.1.1.1.8.2  tls {
    502  1.1.1.1.8.2  tls   int o;
    503  1.1.1.1.8.2  tls 
    504  1.1.1.1.8.2  tls   o = obj->stderr_pipe;
    505  1.1.1.1.8.2  tls   if (o < 0 || o == STDIN_FILE_NO)
    506  1.1.1.1.8.2  tls     return NULL;
    507  1.1.1.1.8.2  tls   obj->read_err = obj->funcs->fdopenr (obj, o, binary);
    508  1.1.1.1.8.2  tls   return obj->read_err;
    509  1.1.1.1.8.2  tls }
    510  1.1.1.1.8.2  tls 
    511  1.1.1.1.8.2  tls /* Get the exit status and, if requested, the resource time for all
    512  1.1.1.1.8.2  tls    the child processes.  Return 0 on failure, 1 on success.  */
    513  1.1.1.1.8.2  tls 
    514  1.1.1.1.8.2  tls static int
    515  1.1.1.1.8.2  tls pex_get_status_and_time (struct pex_obj *obj, int done, const char **errmsg,
    516  1.1.1.1.8.2  tls 			 int *err)
    517  1.1.1.1.8.2  tls {
    518  1.1.1.1.8.2  tls   int ret;
    519  1.1.1.1.8.2  tls   int i;
    520  1.1.1.1.8.2  tls 
    521  1.1.1.1.8.2  tls   if (obj->number_waited == obj->count)
    522  1.1.1.1.8.2  tls     return 1;
    523  1.1.1.1.8.2  tls 
    524  1.1.1.1.8.2  tls   obj->status = XRESIZEVEC (int, obj->status, obj->count);
    525  1.1.1.1.8.2  tls   if ((obj->flags & PEX_RECORD_TIMES) != 0)
    526  1.1.1.1.8.2  tls     obj->time = XRESIZEVEC (struct pex_time, obj->time, obj->count);
    527  1.1.1.1.8.2  tls 
    528  1.1.1.1.8.2  tls   ret = 1;
    529  1.1.1.1.8.2  tls   for (i = obj->number_waited; i < obj->count; ++i)
    530  1.1.1.1.8.2  tls     {
    531  1.1.1.1.8.2  tls       if (obj->funcs->wait (obj, obj->children[i], &obj->status[i],
    532  1.1.1.1.8.2  tls 			    obj->time == NULL ? NULL : &obj->time[i],
    533  1.1.1.1.8.2  tls 			    done, errmsg, err) < 0)
    534  1.1.1.1.8.2  tls 	ret = 0;
    535  1.1.1.1.8.2  tls     }
    536  1.1.1.1.8.2  tls   obj->number_waited = i;
    537  1.1.1.1.8.2  tls 
    538  1.1.1.1.8.2  tls   return ret;
    539  1.1.1.1.8.2  tls }
    540  1.1.1.1.8.2  tls 
    541  1.1.1.1.8.2  tls /* Get exit status of executed programs.  */
    542  1.1.1.1.8.2  tls 
    543  1.1.1.1.8.2  tls int
    544  1.1.1.1.8.2  tls pex_get_status (struct pex_obj *obj, int count, int *vector)
    545  1.1.1.1.8.2  tls {
    546  1.1.1.1.8.2  tls   if (obj->status == NULL)
    547  1.1.1.1.8.2  tls     {
    548  1.1.1.1.8.2  tls       const char *errmsg;
    549  1.1.1.1.8.2  tls       int err;
    550  1.1.1.1.8.2  tls 
    551  1.1.1.1.8.2  tls       if (!pex_get_status_and_time (obj, 0, &errmsg, &err))
    552  1.1.1.1.8.2  tls 	return 0;
    553  1.1.1.1.8.2  tls     }
    554  1.1.1.1.8.2  tls 
    555  1.1.1.1.8.2  tls   if (count > obj->count)
    556  1.1.1.1.8.2  tls     {
    557  1.1.1.1.8.2  tls       memset (vector + obj->count, 0, (count - obj->count) * sizeof (int));
    558  1.1.1.1.8.2  tls       count = obj->count;
    559  1.1.1.1.8.2  tls     }
    560  1.1.1.1.8.2  tls 
    561  1.1.1.1.8.2  tls   memcpy (vector, obj->status, count * sizeof (int));
    562  1.1.1.1.8.2  tls 
    563  1.1.1.1.8.2  tls   return 1;
    564  1.1.1.1.8.2  tls }
    565  1.1.1.1.8.2  tls 
    566  1.1.1.1.8.2  tls /* Get process times of executed programs.  */
    567  1.1.1.1.8.2  tls 
    568  1.1.1.1.8.2  tls int
    569  1.1.1.1.8.2  tls pex_get_times (struct pex_obj *obj, int count, struct pex_time *vector)
    570  1.1.1.1.8.2  tls {
    571  1.1.1.1.8.2  tls   if (obj->status == NULL)
    572  1.1.1.1.8.2  tls     {
    573  1.1.1.1.8.2  tls       const char *errmsg;
    574  1.1.1.1.8.2  tls       int err;
    575  1.1.1.1.8.2  tls 
    576  1.1.1.1.8.2  tls       if (!pex_get_status_and_time (obj, 0, &errmsg, &err))
    577  1.1.1.1.8.2  tls 	return 0;
    578  1.1.1.1.8.2  tls     }
    579  1.1.1.1.8.2  tls 
    580  1.1.1.1.8.2  tls   if (obj->time == NULL)
    581  1.1.1.1.8.2  tls     return 0;
    582  1.1.1.1.8.2  tls 
    583  1.1.1.1.8.2  tls   if (count > obj->count)
    584  1.1.1.1.8.2  tls     {
    585  1.1.1.1.8.2  tls       memset (vector + obj->count, 0,
    586  1.1.1.1.8.2  tls 	      (count - obj->count) * sizeof (struct pex_time));
    587  1.1.1.1.8.2  tls       count = obj->count;
    588  1.1.1.1.8.2  tls     }
    589  1.1.1.1.8.2  tls 
    590  1.1.1.1.8.2  tls   memcpy (vector, obj->time, count * sizeof (struct pex_time));
    591  1.1.1.1.8.2  tls 
    592  1.1.1.1.8.2  tls   return 1;
    593  1.1.1.1.8.2  tls }
    594  1.1.1.1.8.2  tls 
    595  1.1.1.1.8.2  tls /* Free a pex_obj structure.  */
    596  1.1.1.1.8.2  tls 
    597  1.1.1.1.8.2  tls void
    598  1.1.1.1.8.2  tls pex_free (struct pex_obj *obj)
    599  1.1.1.1.8.2  tls {
    600  1.1.1.1.8.2  tls   if (obj->next_input >= 0 && obj->next_input != STDIN_FILE_NO)
    601  1.1.1.1.8.2  tls     obj->funcs->close (obj, obj->next_input);
    602  1.1.1.1.8.2  tls 
    603  1.1.1.1.8.2  tls   /* If the caller forgot to wait for the children, we do it here, to
    604  1.1.1.1.8.2  tls      avoid zombies.  */
    605  1.1.1.1.8.2  tls   if (obj->status == NULL)
    606  1.1.1.1.8.2  tls     {
    607  1.1.1.1.8.2  tls       const char *errmsg;
    608  1.1.1.1.8.2  tls       int err;
    609  1.1.1.1.8.2  tls 
    610  1.1.1.1.8.2  tls       obj->flags &= ~ PEX_RECORD_TIMES;
    611  1.1.1.1.8.2  tls       pex_get_status_and_time (obj, 1, &errmsg, &err);
    612  1.1.1.1.8.2  tls     }
    613  1.1.1.1.8.2  tls 
    614  1.1.1.1.8.2  tls   if (obj->next_input_name_allocated)
    615  1.1.1.1.8.2  tls     free (obj->next_input_name);
    616  1.1.1.1.8.2  tls   if (obj->children != NULL)
    617  1.1.1.1.8.2  tls     free (obj->children);
    618  1.1.1.1.8.2  tls   if (obj->status != NULL)
    619  1.1.1.1.8.2  tls     free (obj->status);
    620  1.1.1.1.8.2  tls   if (obj->time != NULL)
    621  1.1.1.1.8.2  tls     free (obj->time);
    622  1.1.1.1.8.2  tls   if (obj->read_output != NULL)
    623  1.1.1.1.8.2  tls     fclose (obj->read_output);
    624  1.1.1.1.8.2  tls   if (obj->read_err != NULL)
    625  1.1.1.1.8.2  tls     fclose (obj->read_err);
    626  1.1.1.1.8.2  tls 
    627  1.1.1.1.8.2  tls   if (obj->remove_count > 0)
    628  1.1.1.1.8.2  tls     {
    629  1.1.1.1.8.2  tls       int i;
    630  1.1.1.1.8.2  tls 
    631  1.1.1.1.8.2  tls       for (i = 0; i < obj->remove_count; ++i)
    632  1.1.1.1.8.2  tls 	{
    633  1.1.1.1.8.2  tls 	  remove (obj->remove[i]);
    634  1.1.1.1.8.2  tls 	  free (obj->remove[i]);
    635  1.1.1.1.8.2  tls 	}
    636  1.1.1.1.8.2  tls       free (obj->remove);
    637  1.1.1.1.8.2  tls     }
    638  1.1.1.1.8.2  tls 
    639  1.1.1.1.8.2  tls   if (obj->funcs->cleanup != NULL)
    640  1.1.1.1.8.2  tls     obj->funcs->cleanup (obj);
    641  1.1.1.1.8.2  tls 
    642  1.1.1.1.8.2  tls   free (obj);
    643  1.1.1.1.8.2  tls }
    644