/* Common code for executing a program in a sub-process.
   Copyright (C) 2005, 2010 Free Software Foundation, Inc.
   Written by Ian Lance Taylor <ian@airs.com>.

This file is part of the libiberty library.
Libiberty is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.

Libiberty is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Library General Public License for more details.

You should have received a copy of the GNU Library General Public
License along with libiberty; see the file COPYING.LIB.  If not,
write to the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor,
Boston, MA 02110-1301, USA.  */

#include "config.h"
#include "libiberty.h"
#include "pex-common.h"

#include <stdio.h>
#include <errno.h>
#ifdef NEED_DECLARATION_ERRNO
extern int errno;
#endif
#ifdef HAVE_STDLIB_H
#include <stdlib.h>
#endif
#ifdef HAVE_STRING_H
#include <string.h>
#endif
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif

extern int mkstemps (char *, int);

/* This file contains subroutines for the program execution routines
   (pex_init, pex_run, etc.).  This file is compiled on all
   systems.  */

static void pex_add_remove (struct pex_obj *, const char *, int);
static int pex_get_status_and_time (struct pex_obj *, int, const char **,
				    int *);

/* Initialize a pex_obj structure.  */

struct pex_obj *
pex_init_common (int flags, const char *pname, const char *tempbase,
		 const struct pex_funcs *funcs)
{
  struct pex_obj *obj;

  obj = XNEW (struct pex_obj);
  obj->flags = flags;
  obj->pname = pname;
  obj->tempbase = tempbase;
  obj->next_input = STDIN_FILE_NO;
  obj->next_input_name = NULL;
  obj->next_input_name_allocated = 0;
  obj->stderr_pipe = -1;
  obj->count = 0;
  obj->children = NULL;
  obj->status = NULL;
  obj->time = NULL;
  obj->number_waited = 0;
  obj->input_file = NULL;
  obj->read_output = NULL;
  obj->read_err = NULL;
  obj->remove_count = 0;
  obj->remove = NULL;
  obj->funcs = funcs;
  obj->sysdep = NULL;
  return obj;
}

/* Add a file to be removed when we are done.  */

static void
pex_add_remove (struct pex_obj *obj, const char *name, int allocated)
{
  char *add;

  ++obj->remove_count;
  obj->remove = XRESIZEVEC (char *, obj->remove, obj->remove_count);
  if (allocated)
    add = (char *) name;
  else
    add = xstrdup (name);
  obj->remove[obj->remove_count - 1] = add;
}

/* Generate a temporary file name based on OBJ, FLAGS, and NAME.
   Return NULL if we were unable to reserve a temporary filename.

   If non-NULL, the result is either allocated with malloc, or the
   same pointer as NAME.  */
static char *
temp_file (struct pex_obj *obj, int flags, char *name)
{
  if (name == NULL)
    {
      if (obj->tempbase == NULL)
        {
          name = make_temp_file (NULL);
        }
      else
        {
          int len = strlen (obj->tempbase);
          int out;

          if (len >= 6
              && strcmp (obj->tempbase + len - 6, "XXXXXX") == 0)
            name = xstrdup (obj->tempbase);
          else
            name = concat (obj->tempbase, "XXXXXX", NULL);

          out = mkstemps (name, 0);
          if (out < 0)
            {
              free (name);
              return NULL;
            }

          /* This isn't obj->funcs->close because we got the
             descriptor from mkstemps, not from a function in
             obj->funcs.  Calling close here is just like what
             make_temp_file does.  */
          close (out);
        }
    }
  else if ((flags & PEX_SUFFIX) != 0)
    {
      if (obj->tempbase == NULL)
        name = make_temp_file (name);
      else
        name = concat (obj->tempbase, name, NULL);
    }

  return name;
}


/* As for pex_run (), but permits the environment for the child process
   to be specified. */

const char *
pex_run_in_environment (struct pex_obj *obj, int flags, const char *executable,
       	                char * const * argv, char * const * env,
                        const char *orig_outname, const char *errname,
                  	int *err)
{
  const char *errmsg;
  int in, out, errdes;
  char *outname;
  int outname_allocated;
  int p[2];
  int toclose;
  pid_t pid;

  in = -1;
  out = -1;
  errdes = -1;
  outname = (char *) orig_outname;
  outname_allocated = 0;

  /* If the user called pex_input_file, close the file now.  */
  if (obj->input_file)
    {
      if (fclose (obj->input_file) == EOF)
        {
          errmsg = "closing pipeline input file";
          goto error_exit;
        }
      obj->input_file = NULL;
    }

  /* Set IN.  */

  if (obj->next_input_name != NULL)
    {
      /* We have to make sure that the previous process has completed
	 before we try to read the file.  */
      if (!pex_get_status_and_time (obj, 0, &errmsg, err))
	goto error_exit;

      in = obj->funcs->open_read (obj, obj->next_input_name,
				  (flags & PEX_BINARY_INPUT) != 0);
      if (in < 0)
	{
	  *err = errno;
	  errmsg = "open temporary file";
	  goto error_exit;
	}
      if (obj->next_input_name_allocated)
	{
	  free (obj->next_input_name);
	  obj->next_input_name_allocated = 0;
	}
      obj->next_input_name = NULL;
    }
  else
    {
      in = obj->next_input;
      if (in < 0)
	{
	  *err = 0;
	  errmsg = "pipeline already complete";
	  goto error_exit;
	}
    }

  /* Set OUT and OBJ->NEXT_INPUT/OBJ->NEXT_INPUT_NAME.  */

  if ((flags & PEX_LAST) != 0)
    {
      if (outname == NULL)
	out = STDOUT_FILE_NO;
      else if ((flags & PEX_SUFFIX) != 0)
	{
	  outname = concat (obj->tempbase, outname, NULL);
	  outname_allocated = 1;
	}
      obj->next_input = -1;
    }
  else if ((obj->flags & PEX_USE_PIPES) == 0)
    {
      outname = temp_file (obj, flags, outname);
      if (! outname)
        {
          *err = 0;
          errmsg = "could not create temporary file";
          goto error_exit;
        }

      if (outname != orig_outname)
        outname_allocated = 1;

      if ((obj->flags & PEX_SAVE_TEMPS) == 0)
	{
	  pex_add_remove (obj, outname, outname_allocated);
	  outname_allocated = 0;
	}

      /* Hand off ownership of outname to the next stage.  */
      obj->next_input_name = outname;
      obj->next_input_name_allocated = outname_allocated;
      outname_allocated = 0;
    }
  else
    {
      if (obj->funcs->pipe (obj, p, (flags & PEX_BINARY_OUTPUT) != 0) < 0)
	{
	  *err = errno;
	  errmsg = "pipe";
	  goto error_exit;
	}

      out = p[WRITE_PORT];
      obj->next_input = p[READ_PORT];
    }

  if (out < 0)
    {
      out = obj->funcs->open_write (obj, outname,
				    (flags & PEX_BINARY_OUTPUT) != 0,
				    (flags & PEX_STDOUT_APPEND) != 0);
      if (out < 0)
	{
	  *err = errno;
	  errmsg = "open temporary output file";
	  goto error_exit;
	}
    }

  if (outname_allocated)
    {
      free (outname);
      outname_allocated = 0;
    }

  /* Set ERRDES.  */

  if (errname != NULL && (flags & PEX_STDERR_TO_PIPE) != 0)
    {
      *err = 0;
      errmsg = "both ERRNAME and PEX_STDERR_TO_PIPE specified.";
      goto error_exit;
    }

  if (obj->stderr_pipe != -1)
    {
      *err = 0;
      errmsg = "PEX_STDERR_TO_PIPE used in the middle of pipeline";
      goto error_exit;
    }

  if (errname == NULL)
    {
      if (flags & PEX_STDERR_TO_PIPE)
	{
	  if (obj->funcs->pipe (obj, p, (flags & PEX_BINARY_ERROR) != 0) < 0)
	    {
	      *err = errno;
	      errmsg = "pipe";
	      goto error_exit;
	    }
	  
	  errdes = p[WRITE_PORT];
	  obj->stderr_pipe = p[READ_PORT];	  
	}
      else
	{
	  errdes = STDERR_FILE_NO;
	}
    }
  else
    {
      errdes = obj->funcs->open_write (obj, errname,
				       (flags & PEX_BINARY_ERROR) != 0,
				       (flags & PEX_STDERR_APPEND) != 0);
      if (errdes < 0)
	{
	  *err = errno;
	  errmsg = "open error file";
	  goto error_exit;
	}
    }

  /* If we are using pipes, the child process has to close the next
     input pipe.  */

  if ((obj->flags & PEX_USE_PIPES) == 0)
    toclose = -1;
  else
    toclose = obj->next_input;

  /* Run the program.  */

  pid = obj->funcs->exec_child (obj, flags, executable, argv, env,
				in, out, errdes, toclose, &errmsg, err);
  if (pid < 0)
    goto error_exit;

  ++obj->count;
  obj->children = XRESIZEVEC (pid_t, obj->children, obj->count);
  obj->children[obj->count - 1] = pid;

  return NULL;

 error_exit:
  if (in >= 0 && in != STDIN_FILE_NO)
    obj->funcs->close (obj, in);
  if (out >= 0 && out != STDOUT_FILE_NO)
    obj->funcs->close (obj, out);
  if (errdes >= 0 && errdes != STDERR_FILE_NO)
    obj->funcs->close (obj, errdes);
  if (outname_allocated)
    free (outname);
  return errmsg;
}

/* Run a program.  */

const char *
pex_run (struct pex_obj *obj, int flags, const char *executable,
       	 char * const * argv, const char *orig_outname, const char *errname,
         int *err)
{
  return pex_run_in_environment (obj, flags, executable, argv, NULL,
				 orig_outname, errname, err);
}

/* Return a FILE pointer for a temporary file to fill with input for
   the pipeline.  */
FILE *
pex_input_file (struct pex_obj *obj, int flags, const char *in_name)
{
  char *name = (char *) in_name;
  FILE *f;

  /* This must be called before the first pipeline stage is run, and
     there must not have been any other input selected.  */
  if (obj->count != 0
      || (obj->next_input >= 0 && obj->next_input != STDIN_FILE_NO)
      || obj->next_input_name)
    {
      errno = EINVAL;
      return NULL;
    }

  name = temp_file (obj, flags, name);
  if (! name)
    return NULL;

  f = fopen (name, (flags & PEX_BINARY_OUTPUT) ? "wb" : "w");
  if (! f)
    {
      free (name);
      return NULL;
    }

  obj->input_file = f;
  obj->next_input_name = name;
  obj->next_input_name_allocated = (name != in_name);

  return f;
}

/* Return a stream for a pipe connected to the standard input of the
   first stage of the pipeline.  */
FILE *
pex_input_pipe (struct pex_obj *obj, int binary)
{
  int p[2];
  FILE *f;

  /* You must call pex_input_pipe before the first pex_run or pex_one.  */
  if (obj->count > 0)
    goto usage_error;

  /* You must be using pipes.  Implementations that don't support
     pipes clear this flag before calling pex_init_common.  */
  if (! (obj->flags & PEX_USE_PIPES))
    goto usage_error;

  /* If we have somehow already selected other input, that's a
     mistake.  */
  if ((obj->next_input >= 0 && obj->next_input != STDIN_FILE_NO)
      || obj->next_input_name)
    goto usage_error;

  if (obj->funcs->pipe (obj, p, binary != 0) < 0)
    return NULL;

  f = obj->funcs->fdopenw (obj, p[WRITE_PORT], binary != 0);
  if (! f)
    {
      int saved_errno = errno;
      obj->funcs->close (obj, p[READ_PORT]);
      obj->funcs->close (obj, p[WRITE_PORT]);
      errno = saved_errno;
      return NULL;
    }

  obj->next_input = p[READ_PORT];

  return f;

 usage_error:
  errno = EINVAL;
  return NULL;
}

/* Return a FILE pointer for the output of the last program
   executed.  */

FILE *
pex_read_output (struct pex_obj *obj, int binary)
{
  if (obj->next_input_name != NULL)
    {
      const char *errmsg;
      int err;

      /* We have to make sure that the process has completed before we
	 try to read the file.  */
      if (!pex_get_status_and_time (obj, 0, &errmsg, &err))
	{
	  errno = err;
	  return NULL;
	}

      obj->read_output = fopen (obj->next_input_name, binary ? "rb" : "r");

      if (obj->next_input_name_allocated)
	{
	  free (obj->next_input_name);
	  obj->next_input_name_allocated = 0;
	}
      obj->next_input_name = NULL;
    }
  else
    {
      int o;

      o = obj->next_input;
      if (o < 0 || o == STDIN_FILE_NO)
	return NULL;
      obj->read_output = obj->funcs->fdopenr (obj, o, binary);
      obj->next_input = -1;
    }

  return obj->read_output;
}

FILE *
pex_read_err (struct pex_obj *obj, int binary)
{
  int o;
  
  o = obj->stderr_pipe;
  if (o < 0 || o == STDIN_FILE_NO)
    return NULL;
  obj->read_err = obj->funcs->fdopenr (obj, o, binary);
  obj->stderr_pipe = -1;
  return obj->read_err;    
}

/* Get the exit status and, if requested, the resource time for all
   the child processes.  Return 0 on failure, 1 on success.  */

static int
pex_get_status_and_time (struct pex_obj *obj, int done, const char **errmsg,
			 int *err)
{
  int ret;
  int i;

  if (obj->number_waited == obj->count)
    return 1;

  obj->status = XRESIZEVEC (int, obj->status, obj->count);
  if ((obj->flags & PEX_RECORD_TIMES) != 0)
    obj->time = XRESIZEVEC (struct pex_time, obj->time, obj->count);

  ret = 1;
  for (i = obj->number_waited; i < obj->count; ++i)
    {
      if (obj->funcs->wait (obj, obj->children[i], &obj->status[i],
			    obj->time == NULL ? NULL : &obj->time[i],
			    done, errmsg, err) < 0)
	ret = 0;
    }
  obj->number_waited = i;

  return ret;
}

/* Get exit status of executed programs.  */

int
pex_get_status (struct pex_obj *obj, int count, int *vector)
{
  if (obj->status == NULL)
    {
      const char *errmsg;
      int err;

      if (!pex_get_status_and_time (obj, 0, &errmsg, &err))
	return 0;
    }

  if (count > obj->count)
    {
      memset (vector + obj->count, 0, (count - obj->count) * sizeof (int));
      count = obj->count;
    }

  memcpy (vector, obj->status, count * sizeof (int));

  return 1;
}

/* Get process times of executed programs.  */

int
pex_get_times (struct pex_obj *obj, int count, struct pex_time *vector)
{
  if (obj->status == NULL)
    {
      const char *errmsg;
      int err;

      if (!pex_get_status_and_time (obj, 0, &errmsg, &err))
	return 0;
    }

  if (obj->time == NULL)
    return 0;

  if (count > obj->count)
    {
      memset (vector + obj->count, 0,
	      (count - obj->count) * sizeof (struct pex_time));
      count = obj->count;
    }

  memcpy (vector, obj->time, count * sizeof (struct pex_time));

  return 1;
}

/* Free a pex_obj structure.  */

void
pex_free (struct pex_obj *obj)
{
  /* Close pipe file descriptors corresponding to child's stdout and
     stderr so that the child does not hang trying to output something
     while we're waiting for it.  */
  if (obj->next_input >= 0 && obj->next_input != STDIN_FILE_NO)
    obj->funcs->close (obj, obj->next_input);
  if (obj->stderr_pipe >= 0 && obj->stderr_pipe != STDIN_FILE_NO)
    obj->funcs->close (obj, obj->stderr_pipe);
  if (obj->read_output != NULL)
    fclose (obj->read_output);
  if (obj->read_err != NULL)
    fclose (obj->read_err);

  /* If the caller forgot to wait for the children, we do it here, to
     avoid zombies.  */
  if (obj->status == NULL)
    {
      const char *errmsg;
      int err;

      obj->flags &= ~ PEX_RECORD_TIMES;
      pex_get_status_and_time (obj, 1, &errmsg, &err);
    }

  if (obj->next_input_name_allocated)
    free (obj->next_input_name);
  free (obj->children);
  free (obj->status);
  free (obj->time);

  if (obj->remove_count > 0)
    {
      int i;

      for (i = 0; i < obj->remove_count; ++i)
	{
	  remove (obj->remove[i]);
	  free (obj->remove[i]);
	}
      free (obj->remove);
    }

  if (obj->funcs->cleanup != NULL)
    obj->funcs->cleanup (obj);

  free (obj);
}
