/*
 * msvcrt.dll spawn/exec functions
 *
 * Copyright 1996,1998 Marcus Meissner
 * Copyright 1996 Jukka Iivonen
 * Copyright 1997,2000 Uwe Bonnes
 * Copyright 2000 Jon Griffiths
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library 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
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 *
 * FIXME:
 * -File handles need some special handling. Sometimes children get
 *  open file handles, sometimes not. The docs are confusing
 * -No check for maximum path/argument/environment size is done
 */
#include "config.h"

#include <stdarg.h>

#include "msvcrt.h"
#include "wine/debug.h"

WINE_DEFAULT_DEBUG_CHANNEL(msvcrt);

/* INTERNAL: Spawn a child process */
static int msvcrt_spawn(int flags, const char* exe, char* cmdline, char* env)
{
  STARTUPINFOA si;
  PROCESS_INFORMATION pi;

  if (sizeof(HANDLE) != sizeof(int))
    WARN("This call is unsuitable for your architecture\n");

  if ((unsigned)flags > MSVCRT__P_DETACH)
  {
    *MSVCRT__errno() = MSVCRT_EINVAL;
    return -1;
  }

  memset(&si, 0, sizeof(si));
  si.cb = sizeof(si);
  msvcrt_create_io_inherit_block(&si);
  if (!CreateProcessA(exe, cmdline, NULL, NULL, TRUE,
                     flags == MSVCRT__P_DETACH ? DETACHED_PROCESS : 0,
                     env, NULL, &si, &pi))
  {
    msvcrt_set_errno(GetLastError());
    MSVCRT_free(si.lpReserved2);
    return -1;
  }

  MSVCRT_free(si.lpReserved2);
  switch(flags)
  {
  case MSVCRT__P_WAIT:
    WaitForSingleObject(pi.hProcess, INFINITE);
    GetExitCodeProcess(pi.hProcess,&pi.dwProcessId);
    CloseHandle(pi.hProcess);
    CloseHandle(pi.hThread);
    return (int)pi.dwProcessId;
  case MSVCRT__P_DETACH:
    CloseHandle(pi.hProcess);
    pi.hProcess = 0;
    /* fall through */
  case MSVCRT__P_NOWAIT:
  case MSVCRT__P_NOWAITO:
    CloseHandle(pi.hThread);
    return (int)pi.hProcess;
  case  MSVCRT__P_OVERLAY:
    MSVCRT__exit(0);
  }
  return -1; /* can't reach here */
}

/* INTERNAL: Convert argv list to a single 'delim'-separated string, with an
 * extra '\0' to terminate it
 */
static char* msvcrt_argvtos(const char* const* arg, char delim)
{
  const char* const* a;
  long size;
  char* p;
  char* ret;

  if (!arg && !delim)
  {
      /* Return NULL for an empty environment list */
      return NULL;
  }

  /* get length */
  a = arg;
  size = 0;
  while (*a)
  {
    size += strlen(*a) + 1;
    a++;
  }

  ret = (char*)MSVCRT_malloc(size + 1);
  if (!ret)
    return NULL;

  /* fill string */
  a = arg;
  p = ret;
  while (*a)
  {
    int len = strlen(*a);
    memcpy(p,*a,len);
    p += len;
    *p++ = delim;
    a++;
  }
  if (delim && p > ret) p[-1] = 0;
  else *p = 0;
  return ret;
}

/* INTERNAL: Convert va_list to a single 'delim'-separated string, with an
 * extra '\0' to terminate it
 */
static char* msvcrt_valisttos(const char* arg0, va_list alist, char delim)
{
  va_list alist2;
  long size;
  const char *arg;
  char* p;
  char *ret;

#ifdef HAVE_VA_COPY
  va_copy(alist2,alist);
#else
# ifdef HAVE___VA_COPY
  __va_copy(alist2,alist);
# else
  alist2 = alist;
# endif
#endif

  if (!arg0 && !delim)
  {
      /* Return NULL for an empty environment list */
      return NULL;
  }

  /* get length */
  arg = arg0;
  size = 0;
  do {
      size += strlen(arg) + 1;
      arg = va_arg(alist, char*);
  } while (arg != NULL);

  ret = (char*)MSVCRT_malloc(size + 1);
  if (!ret)
    return NULL;

  /* fill string */
  arg = arg0;
  p = ret;
  do {
      int len = strlen(arg);
      memcpy(p,arg,len);
      p += len;
      *p++ = delim;
      arg = va_arg(alist2, char*);
  } while (arg != NULL);
  if (delim && p > ret) p[-1] = 0;
  else *p = 0;
  return ret;
}

/*********************************************************************
 *		_cwait (MSVCRT.@)
 */
int _cwait(int *status, int pid, int action)
{
  HANDLE hPid = (HANDLE)pid;
  int doserrno;

  action = action; /* Remove warning */

  if (!WaitForSingleObject(hPid, INFINITE))
  {
    if (status)
    {
      DWORD stat;
      GetExitCodeProcess(hPid, &stat);
      *status = (int)stat;
    }
    return (int)pid;
  }
  doserrno = GetLastError();

  if (doserrno == ERROR_INVALID_HANDLE)
  {
    *MSVCRT__errno() =  MSVCRT_ECHILD;
    *MSVCRT___doserrno() = doserrno;
  }
  else
    msvcrt_set_errno(doserrno);

  return status ? *status = -1 : -1;
}

/*********************************************************************
 *		_execl (MSVCRT.@)
 *
 * Like on Windows, this function does not handle arguments with spaces
 * or double-quotes.
 */
int _execl(const char* name, const char* arg0, ...)
{
  va_list ap;
  char * args;
  int ret;

  va_start(ap, arg0);
  args = msvcrt_valisttos(arg0, ap, ' ');
  va_end(ap);

  ret = msvcrt_spawn(MSVCRT__P_OVERLAY, name, args, NULL);
  MSVCRT_free(args);

  return ret;
}

/*********************************************************************
 *		_execle (MSVCRT.@)
 */
int _execle(const char* name, const char* arg0, ...)
{
    FIXME("stub\n");
    return -1;
}

/*********************************************************************
 *		_execlp (MSVCRT.@)
 *
 * Like on Windows, this function does not handle arguments with spaces
 * or double-quotes.
 */
int _execlp(const char* name, const char* arg0, ...)
{
  va_list ap;
  char * args;
  int ret;
  char fullname[MAX_PATH];

  _searchenv(name, "PATH", fullname);

  va_start(ap, arg0);
  args = msvcrt_valisttos(arg0, ap, ' ');
  va_end(ap);

  ret = msvcrt_spawn(MSVCRT__P_OVERLAY, fullname[0] ? fullname : name, args, NULL);
  MSVCRT_free(args);

  return ret;
}

/*********************************************************************
 *		_execlpe (MSVCRT.@)
 */
int _execlpe(const char* name, const char* arg0, ...)
{
    FIXME("stub\n");
    return -1;
}

/*********************************************************************
 *		_execv (MSVCRT.@)
 *
 * Like on Windows, this function does not handle arguments with spaces
 * or double-quotes.
 */
int _execv(const char* name, char* const* argv)
{
  return _spawnve(MSVCRT__P_OVERLAY, name, (const char* const*) argv, NULL);
}

/*********************************************************************
 *		_execve (MSVCRT.@)
 *
 * Like on Windows, this function does not handle arguments with spaces
 * or double-quotes.
 */
int _execve(const char* name, char* const* argv, const char* const* envv)
{
  return _spawnve(MSVCRT__P_OVERLAY, name, (const char* const*) argv, envv);
}

/*********************************************************************
 *		_execvpe (MSVCRT.@)
 *
 * Like on Windows, this function does not handle arguments with spaces
 * or double-quotes.
 */
int _execvpe(const char* name, char* const* argv, const char* const* envv)
{
  char fullname[MAX_PATH];

  _searchenv(name, "PATH", fullname);
  return _spawnve(MSVCRT__P_OVERLAY, fullname[0] ? fullname : name,
                  (const char* const*) argv, envv);
}

/*********************************************************************
 *		_execvp (MSVCRT.@)
 *
 * Like on Windows, this function does not handle arguments with spaces
 * or double-quotes.
 */
int _execvp(const char* name, char* const* argv)
{
  return _execvpe(name, argv, NULL);
}

/*********************************************************************
 *		_spawnl (MSVCRT.@)
 *
 * Like on Windows, this function does not handle arguments with spaces
 * or double-quotes.
 */
int _spawnl(int flags, const char* name, const char* arg0, ...)
{
  va_list ap;
  char * args;
  int ret;

  va_start(ap, arg0);
  args = msvcrt_valisttos(arg0, ap, ' ');
  va_end(ap);

  ret = msvcrt_spawn(flags, name, args, NULL);
  MSVCRT_free(args);

  return ret;
}

/*********************************************************************
 *		_spawnle (MSVCRT.@)
 */
int _spawnle(int flags, const char* name, const char* arg0, ...)
{
    va_list ap;
    char *args, *envs = NULL;
    const char * const *envp;
    int ret;

    va_start(ap, arg0);
    args = msvcrt_valisttos(arg0, ap, ' ');
    va_end(ap);

    va_start(ap, arg0);
    while (va_arg( ap, char * ) != NULL) /*nothing*/;
    envp = va_arg( ap, const char * const * );
    if (envp) envs = msvcrt_argvtos(envp, 0);
    va_end(ap);

    ret = msvcrt_spawn(flags, name, args, envs);

    MSVCRT_free(args);
    if (envs) MSVCRT_free(envs);
    return ret;
}


/*********************************************************************
 *		_spawnlp (MSVCRT.@)
 *
 * Like on Windows, this function does not handle arguments with spaces
 * or double-quotes.
 */
int _spawnlp(int flags, const char* name, const char* arg0, ...)
{
  va_list ap;
  char * args;
  int ret;
  char fullname[MAX_PATH];

  _searchenv(name, "PATH", fullname);

  va_start(ap, arg0);
  args = msvcrt_valisttos(arg0, ap, ' ');
  va_end(ap);

  ret = msvcrt_spawn(flags, fullname[0] ? fullname : name, args, NULL);
  MSVCRT_free(args);

  return ret;
}

/*********************************************************************
 *		_spawnlpe (MSVCRT.@)
 */
int _spawnlpe(int flags, const char* name, const char* arg0, ...)
{
    va_list ap;
    char *args, *envs = NULL;
    const char * const *envp;
    int ret;
    char fullname[MAX_PATH];

    _searchenv(name, "PATH", fullname);

    va_start(ap, arg0);
    args = msvcrt_valisttos(arg0, ap, ' ');
    va_end(ap);

    va_start(ap, arg0);
    while (va_arg( ap, char * ) != NULL) /*nothing*/;
    envp = va_arg( ap, const char * const * );
    if (envp) envs = msvcrt_argvtos(envp, 0);
    va_end(ap);

    ret = msvcrt_spawn(flags, fullname[0] ? fullname : name, args, envs);

    MSVCRT_free(args);
    if (envs) MSVCRT_free(envs);
    return ret;
}

/*********************************************************************
 *		_spawnve (MSVCRT.@)
 *
 * Like on Windows, this function does not handle arguments with spaces
 * or double-quotes.
 */
int _spawnve(int flags, const char* name, const char* const* argv,
                            const char* const* envv)
{
  char * args = msvcrt_argvtos(argv,' ');
  char * envs = msvcrt_argvtos(envv,0);
  const char *fullname = name;
  int ret = -1;

  FIXME(":not translating name %s to locate program\n",fullname);
  TRACE(":call (%s), params (%s), env (%s)\n",debugstr_a(name),debugstr_a(args),
   envs?"Custom":"Null");

  if (args)
  {
    ret = msvcrt_spawn(flags, fullname, args, envs);
    MSVCRT_free(args);
  }
  if (envs)
    MSVCRT_free(envs);

  return ret;
}

/*********************************************************************
 *		_spawnv (MSVCRT.@)
 *
 * Like on Windows, this function does not handle arguments with spaces
 * or double-quotes.
 */
int _spawnv(int flags, const char* name, const char* const* argv)
{
  return _spawnve(flags, name, argv, NULL);
}

/*********************************************************************
 *		_spawnvpe (MSVCRT.@)
 *
 * Like on Windows, this function does not handle arguments with spaces
 * or double-quotes.
 */
int _spawnvpe(int flags, const char* name, const char* const* argv,
                            const char* const* envv)
{
  char fullname[MAX_PATH];
  _searchenv(name, "PATH", fullname);
  return _spawnve(flags, fullname[0] ? fullname : name, argv, envv);
}

/*********************************************************************
 *		_spawnvp (MSVCRT.@)
 *
 * Like on Windows, this function does not handle arguments with spaces
 * or double-quotes.
 */
int _spawnvp(int flags, const char* name, const char* const* argv)
{
  return _spawnvpe(flags, name, argv, NULL);
}

/*********************************************************************
 *		_popen (MSVCRT.@)
 * FIXME: convert to _wpopen and call that from here instead?  But it
 * would have to convert the command back to ANSI to call msvcrt_spawn,
 * less than ideal.
 */
MSVCRT_FILE* MSVCRT__popen(const char* command, const char* mode)
{
  static const char wcmd[] = "wcmd", cmdFlag[] = " /C ", comSpec[] = "COMSPEC";
  MSVCRT_FILE *ret;
  BOOL readPipe = TRUE;
  int textmode, fds[2], fdToDup, fdToOpen, fdStdHandle = -1, fdStdErr = -1;
  const char *p;
  char *cmdcopy;
  DWORD comSpecLen;

  TRACE("(command=%s, mode=%s)\n", debugstr_a(command), debugstr_a(mode));

  if (!command || !mode)
    return NULL;

  textmode = *__p__fmode() & (MSVCRT__O_BINARY | MSVCRT__O_TEXT);
  for (p = mode; *p; p++)
  {
    switch (*p)
    {
      case 'W':
      case 'w':
        readPipe = FALSE;
        break;
      case 'B':
      case 'b':
        textmode |= MSVCRT__O_BINARY;
        textmode &= ~MSVCRT__O_TEXT;
        break;
      case 'T':
      case 't':
        textmode |= MSVCRT__O_TEXT;
        textmode &= ~MSVCRT__O_BINARY;
        break;
    }
  }
  textmode |= MSVCRT__O_NOINHERIT;
  if (_pipe(fds, 0, textmode) == -1)
    return NULL;

  fdToDup = readPipe ? 1 : 0;
  fdToOpen = readPipe ? 0 : 1;

  if ((fdStdHandle = _dup(fdToDup)) == -1)
    goto error;
  if (_dup2(fds[fdToDup], fdToDup) != 0)
    goto error;
  if (readPipe)
  {
    if ((fdStdErr = _dup(MSVCRT_STDERR_FILENO)) == -1)
      goto error;
    if (_dup2(fds[fdToDup], MSVCRT_STDERR_FILENO) != 0)
      goto error;
  }

  _close(fds[fdToDup]);

  comSpecLen = GetEnvironmentVariableA(comSpec, NULL, 0);
  if (!comSpecLen)
    comSpecLen = strlen(wcmd) + 1;
  cmdcopy = HeapAlloc(GetProcessHeap(), 0, comSpecLen + strlen(cmdFlag)
   + strlen(command));
  if (!GetEnvironmentVariableA(comSpec, cmdcopy, comSpecLen))
    strcpy(cmdcopy, wcmd);
  strcat(cmdcopy, cmdFlag);
  strcat(cmdcopy, command);
  if (msvcrt_spawn(MSVCRT__P_NOWAIT, NULL, cmdcopy, NULL) == -1)
  {
    _close(fds[fdToOpen]);
    ret = NULL;
  }
  else
  {
    ret = MSVCRT__fdopen(fds[fdToOpen], mode);
    if (!ret)
      _close(fds[fdToOpen]);
  }
  HeapFree(GetProcessHeap(), 0, cmdcopy);
  _dup2(fdStdHandle, fdToDup);
  _close(fdStdHandle);
  if (readPipe)
  {
    _dup2(fdStdErr, MSVCRT_STDERR_FILENO);
    _close(fdStdErr);
  }
  return ret;

error:
  if (fdStdHandle != -1) _close(fdStdHandle);
  if (fdStdErr != -1)    _close(fdStdErr);
  _close(fds[0]);
  _close(fds[1]);
  return NULL;
}

/*********************************************************************
 *		_wpopen (MSVCRT.@)
 */
MSVCRT_FILE* MSVCRT__wpopen(const MSVCRT_wchar_t* command, const MSVCRT_wchar_t* mode)
{
  FIXME("(command=%s, mode=%s): stub\n", debugstr_w(command), debugstr_w(mode));
  return NULL;
}

/*********************************************************************
 *		_pclose (MSVCRT.@)
 */
int MSVCRT__pclose(MSVCRT_FILE* file)
{
  return MSVCRT_fclose(file);
}

/*********************************************************************
 *		system (MSVCRT.@)
 */
int MSVCRT_system(const char* cmd)
{
    char* cmdcopy;
    int res;

    /* Make a writable copy for CreateProcess */
    cmdcopy=_strdup(cmd);
    /* FIXME: should probably launch cmd interpreter in COMSPEC */
    res=msvcrt_spawn(MSVCRT__P_WAIT, NULL, cmdcopy, NULL);
    MSVCRT_free(cmdcopy);
    return res;
}

/*********************************************************************
 *		_loaddll (MSVCRT.@)
 */
int _loaddll(const char* dllname)
{
  return (int)LoadLibraryA(dllname);
}

/*********************************************************************
 *		_unloaddll (MSVCRT.@)
 */
int _unloaddll(int dll)
{
  if (FreeLibrary((HMODULE)dll))
    return 0;
  else
  {
    int err = GetLastError();
    msvcrt_set_errno(err);
    return err;
  }
}

/*********************************************************************
 *		_getdllprocaddr (MSVCRT.@)
 */
void *_getdllprocaddr(int dll, const char *name, int ordinal)
{
    if (name)
    {
        if (ordinal != -1) return NULL;
        return GetProcAddress( (HMODULE)dll, name );
    }
    if (HIWORD(ordinal)) return NULL;
    return GetProcAddress( (HMODULE)dll, (LPCSTR)(ULONG_PTR)ordinal );
}
