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