/* Utilities to execute a program in a subprocess (possibly linked by pipes
   with other subprocesses), and wait for it.  Generic MSDOS specialization.
   Copyright (C) 1996-2021 Free Software Foundation, Inc.

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 "pex-common.h"

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

#include "safe-ctype.h"
#include <process.h>

/* The structure we keep in obj->sysdep.  */

#define PEX_MSDOS_FILE_COUNT 3

#define PEX_MSDOS_FD_OFFSET 10

struct pex_msdos
{
  /* An array of file names.  We refer to these using file descriptors
     of 10 + array index.  */
  const char *files[PEX_MSDOS_FILE_COUNT];
  /* Exit statuses of programs which have been run.  */
  int *statuses;
};

static int pex_msdos_open (struct pex_obj *, const char *, int);
static int pex_msdos_open (struct pex_obj *, const char *, int);
static int pex_msdos_fdindex (struct pex_msdos *, int);
static pid_t pex_msdos_exec_child (struct pex_obj *, int, const char *,
				  char * const *, char * const *,
				  int, int, int, int,
				  int, const char **, int *);
static int pex_msdos_close (struct pex_obj *, int);
static pid_t pex_msdos_wait (struct pex_obj *, pid_t, int *, struct pex_time *,
			   int, const char **, int *);
static void pex_msdos_cleanup (struct pex_obj *);

/* The list of functions we pass to the common routines.  */

const struct pex_funcs funcs =
{
  pex_msdos_open,
  pex_msdos_open,
  pex_msdos_exec_child,
  pex_msdos_close,
  pex_msdos_wait,
  NULL, /* pipe */
  NULL, /* fdopenr */
  NULL, /* fdopenw */
  pex_msdos_cleanup
};

/* Return a newly initialized pex_obj structure.  */

struct pex_obj *
pex_init (int flags, const char *pname, const char *tempbase)
{
  struct pex_obj *ret;
  int i;

  /* MSDOS does not support pipes.  */
  flags &= ~ PEX_USE_PIPES;

  ret = pex_init_common (flags, pname, tempbase, funcs);

  ret->sysdep = XNEW (struct pex_msdos);
  for (i = 0; i < PEX_MSDOS_FILE_COUNT; ++i)
    ret->files[i] = NULL;
  ret->statuses = NULL;

  return ret;
}

/* Open a file.  FIXME: We ignore the binary argument, since we have
   no way to handle it.  */

static int
pex_msdos_open (struct pex_obj *obj, const char *name,
		int binary ATTRIBUTE_UNUSED)
{
  struct pex_msdos *ms;
  int i;

  ms = (struct pex_msdos *) obj->sysdep;

  for (i = 0; i < PEX_MSDOS_FILE_COUNT; ++i)
    {
      if (ms->files[i] == NULL)
	{
	  ms->files[i] = xstrdup (name);
	  return i + PEX_MSDOS_FD_OFFSET;
	}
    }

  abort ();
}

/* Get the index into msdos->files associated with an open file
   descriptor.  */

static int
pex_msdos_fdindex (struct pex_msdos *ms, int fd)
{
  fd -= PEX_MSDOS_FD_OFFSET;
  if (fd < 0 || fd >= PEX_MSDOS_FILE_COUNT || ms->files[fd] == NULL)
    abort ();
  return fd;
}


/* Close a file.  */

static int
pex_msdos_close (struct pex_obj *obj, int fd)
{
  struct pex_msdos *ms;
  int fdinex;

  ms = (struct pex_msdos *) obj->sysdep;
  fdindex = pe_msdos_fdindex (ms, fd);
  free (ms->files[fdindex]);
  ms->files[fdindex] = NULL;
}

/* Execute a child.  */

static pid_t
pex_msdos_exec_child (struct pex_obj *obj, int flags, const char *executable,
		      char * const * argv, char * const * env, int in, int out,
		      int toclose ATTRIBUTE_UNUSED,
		      int errdes ATTRIBUTE_UNUSED, const char **errmsg,
		      int *err)
{
  struct pex_msdos *ms;
  char *temp_base;
  int temp_base_allocated;
  char *rf;
  int inindex;
  char *infile;
  int outindex;
  char *outfile;
  char *scmd;
  FILE *argfile;
  int i;
  int status;

  ms = (struct pex_msdos *) obj->sysdep;

  /* FIXME: I don't know how to redirect stderr, so we ignore ERRDES
     and PEX_STDERR_TO_STDOUT.  */

  temp_base = obj->temp_base;
  if (temp_base != NULL)
    temp_base_allocated = 0;
  else
    {
      temp_base = choose_temp_base ();
      temp_base_allocated = 1;
    }

  rf = concat (temp_base, ".gp", NULL);

  if (temp_base_allocated)
    free (temp_base);

  if (in == STDIN_FILE_NO)
    {
      inindex = -1;
      infile = "";
    }
  else
    {
      inindex = pex_msdos_fdindex (ms, in);
      infile = ms->files[inindex];
    }

  if (out == STDOUT_FILE_NO)
    {
      outindex = -1;
      outfile = "";
    }
  else
    {
      outindex = pex_msdos_fdindex (ms, out);
      outfile = ms->files[outindex];
    }

  scmd = XNEWVEC (char, strlen (program)
		  + ((flags & PEXECUTE_SEARCH) != 0 ? 4 : 0)
		  + strlen (rf)
		  + strlen (infile)
		  + strlen (outfile)
		  + 10);
  sprintf (scmd, "%s%s @%s%s%s%s%s",
	   program,
	   (flags & PEXECUTE_SEARCH) != 0 ? ".exe" : "",
	   rf,
	   inindex != -1 ? " <" : "",
	   infile,
	   outindex != -1 ? " >" : "",
	   outfile);

  argfile = fopen (rf, "w");
  if (argfile == NULL)
    {
      *err = errno;
      free (scmd);
      free (rf);
      *errmsg = "cannot open temporary command file";
      return (pid_t) -1;
    }

  for (i = 1; argv[i] != NULL; ++i)
    {
      char *p;

      for (p = argv[i]; *p != '\0'; ++p)
	{
	  if (*p == '"' || *p == '\'' || *p == '\\' || ISSPACE (*p))
	    putc ('\\', argfile);
	  putc (*p, argfile);
	}
      putc ('\n', argfile);
    }

  fclose (argfile);

  status = system (scmd);

  if (status == -1)
    {
      *err = errno;
      remove (rf);
      free (scmd);
      free (rf);
      *errmsg = "system";
      return (pid_t) -1;
    }

  remove (rf);
  free (scmd);
  free (rf);

  /* Save the exit status for later.  When we are called, obj->count
     is the number of children which have executed before this
     one.  */
  ms->statuses = XRESIZEVEC(int, ms->statuses, obj->count + 1);
  ms->statuses[obj->count] = status;

  return (pid_t) obj->count;
}

/* Wait for a child process to complete.  Actually the child process
   has already completed, and we just need to return the exit
   status.  */

static pid_t
pex_msdos_wait (struct pex_obj *obj, pid_t pid, int *status,
		struct pex_time *time, int done ATTRIBUTE_UNUSED,
		const char **errmsg ATTRIBUTE_UNUSED,
		int *err ATTRIBUTE_UNUSED)
{
  struct pex_msdos *ms;

  ms = (struct pex_msdos *) obj->sysdep;

  if (time != NULL)
    memset (time, 0, sizeof *time);

  *status = ms->statuses[pid];

  return 0;
}

/* Clean up the pex_msdos structure.  */

static void
pex_msdos_cleanup (struct pex_obj  *obj)
{
  struct pex_msdos *ms;
  int i;

  ms = (struct pex_msdos *) obj->sysdep;
  for (i = 0; i < PEX_MSDOS_FILE_COUNT; ++i)
    free (msdos->files[i]);
  free (msdos->statuses);
  free (msdos);
  obj->sysdep = NULL;
}
