/* Auxiliary functions for the creation of subprocesses.  Native Windows API.
   Copyright (C) 2001, 2003-2019 Free Software Foundation, Inc.
   Written by Bruno Haible <bruno@clisp.org>, 2003.

   This program is free software: you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 3 of the License, or
   (at your option) any later version.

   This program 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 General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program.  If not, see <https://www.gnu.org/licenses/>.  */

#ifndef __KLIBC__
/* Get declarations of the native Windows API functions.  */
# define WIN32_LEAN_AND_MEAN
# include <windows.h>
#endif

/* Get _open_osfhandle().  */
#include <io.h>

#include <stdbool.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>

/* Get _get_osfhandle().  */
# if GNULIB_MSVC_NOTHROW
#  include "msvc-nothrow.h"
# else
#  include <io.h>
# endif

#include "cloexec.h"
#include "xalloc.h"

/* Duplicates a file handle, making the copy uninheritable.
   Returns -1 for a file handle that is equivalent to closed.  */
static int
dup_noinherit (int fd)
{
  fd = dup_cloexec (fd);
  if (fd < 0 && errno == EMFILE)
    error (EXIT_FAILURE, errno, _("_open_osfhandle failed"));

  return fd;
}

/* Returns a file descriptor equivalent to FD, except that the resulting file
   descriptor is none of STDIN_FILENO, STDOUT_FILENO, STDERR_FILENO.
   FD must be open and non-inheritable.  The result will be non-inheritable as
   well.
   If FD < 0, FD itself is returned.  */
static int
fd_safer_noinherit (int fd)
{
  if (STDIN_FILENO <= fd && fd <= STDERR_FILENO)
    {
      /* The recursion depth is at most 3.  */
      int nfd = fd_safer_noinherit (dup_noinherit (fd));
      int saved_errno = errno;
      close (fd);
      errno = saved_errno;
      return nfd;
    }
  return fd;
}

/* Duplicates a file handle, making the copy uninheritable and ensuring the
   result is none of STDIN_FILENO, STDOUT_FILENO, STDERR_FILENO.
   Returns -1 for a file handle that is equivalent to closed.  */
static int
dup_safer_noinherit (int fd)
{
  return fd_safer_noinherit (dup_noinherit (fd));
}

/* Undoes the effect of TEMPFD = dup_safer_noinherit (ORIGFD);  */
static void
undup_safer_noinherit (int tempfd, int origfd)
{
  if (tempfd >= 0)
    {
      if (dup2 (tempfd, origfd) < 0)
        error (EXIT_FAILURE, errno, _("cannot restore fd %d: dup2 failed"),
               origfd);
      close (tempfd);
    }
  else
    {
      /* origfd was closed or open to no handle at all.  Set it to a closed
         state.  This is (nearly) equivalent to the original state.  */
      close (origfd);
    }
}

/* Prepares an argument vector before calling spawn().
   Note that spawn() does not by itself call the command interpreter
     (getenv ("COMSPEC") != NULL ? getenv ("COMSPEC") :
      ({ OSVERSIONINFO v; v.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
         GetVersionEx(&v);
         v.dwPlatformId == VER_PLATFORM_WIN32_NT;
      }) ? "cmd.exe" : "command.com").
   Instead it simply concatenates the arguments, separated by ' ', and calls
   CreateProcess().  We must quote the arguments since Windows CreateProcess()
   interprets characters like ' ', '\t', '\\', '"' (but not '<' and '>') in a
   special way:
   - Space and tab are interpreted as delimiters. They are not treated as
     delimiters if they are surrounded by double quotes: "...".
   - Unescaped double quotes are removed from the input. Their only effect is
     that within double quotes, space and tab are treated like normal
     characters.
   - Backslashes not followed by double quotes are not special.
   - But 2*n+1 backslashes followed by a double quote become
     n backslashes followed by a double quote (n >= 0):
       \" -> "
       \\\" -> \"
       \\\\\" -> \\"
   - '*', '?' characters may get expanded through wildcard expansion in the
     callee: By default, in the callee, the initialization code before main()
     takes the result of GetCommandLine(), wildcard-expands it, and passes it
     to main(). The exceptions to this rule are:
       - programs that inspect GetCommandLine() and ignore argv,
       - mingw programs that have a global variable 'int _CRT_glob = 0;',
       - Cygwin programs, when invoked from a Cygwin program.
 */
#ifndef __KLIBC__
# define SHELL_SPECIAL_CHARS "\"\\ \001\002\003\004\005\006\007\010\011\012\013\014\015\016\017\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037*?"
# define SHELL_SPACE_CHARS " \001\002\003\004\005\006\007\010\011\012\013\014\015\016\017\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037"
#else
# define SHELL_SPECIAL_CHARS ""
# define SHELL_SPACE_CHARS ""
#endif
static char **
prepare_spawn (char **argv)
{
  size_t argc;
  char **new_argv;
  size_t i;

  /* Count number of arguments.  */
  for (argc = 0; argv[argc] != NULL; argc++)
    ;

  /* Allocate new argument vector.  */
  new_argv = XNMALLOC (1 + argc + 1, char *);

  /* Add an element upfront that can be used when argv[0] turns out to be a
     script, not a program.
     On Unix, this would be "/bin/sh". On native Windows, "sh" is actually
     "sh.exe".  We have to omit the directory part and rely on the search in
     PATH, because the mingw "mount points" are not visible inside Windows
     CreateProcess().  */
  *new_argv++ = "sh.exe";

  /* Put quoted arguments into the new argument vector.  */
  for (i = 0; i < argc; i++)
    {
      const char *string = argv[i];

      if (string[0] == '\0')
        new_argv[i] = xstrdup ("\"\"");
      else if (strpbrk (string, SHELL_SPECIAL_CHARS) != NULL)
        {
          bool quote_around = (strpbrk (string, SHELL_SPACE_CHARS) != NULL);
          size_t length;
          unsigned int backslashes;
          const char *s;
          char *quoted_string;
          char *p;

          length = 0;
          backslashes = 0;
          if (quote_around)
            length++;
          for (s = string; *s != '\0'; s++)
            {
              char c = *s;
              if (c == '"')
                length += backslashes + 1;
              length++;
              if (c == '\\')
                backslashes++;
              else
                backslashes = 0;
            }
          if (quote_around)
            length += backslashes + 1;

          quoted_string = (char *) xmalloc (length + 1);

          p = quoted_string;
          backslashes = 0;
          if (quote_around)
            *p++ = '"';
          for (s = string; *s != '\0'; s++)
            {
              char c = *s;
              if (c == '"')
                {
                  unsigned int j;
                  for (j = backslashes + 1; j > 0; j--)
                    *p++ = '\\';
                }
              *p++ = c;
              if (c == '\\')
                backslashes++;
              else
                backslashes = 0;
            }
          if (quote_around)
            {
              unsigned int j;
              for (j = backslashes; j > 0; j--)
                *p++ = '\\';
              *p++ = '"';
            }
          *p = '\0';

          new_argv[i] = quoted_string;
        }
      else
        new_argv[i] = (char *) string;
    }
  new_argv[argc] = NULL;

  return new_argv;
}
