Welcome to mirror list, hosted at ThFree Co, Russian Federation.

cygwin.com/git/newlib-cygwin.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'winsup/cygwin/spawn.cc')
-rw-r--r--winsup/cygwin/spawn.cc980
1 files changed, 0 insertions, 980 deletions
diff --git a/winsup/cygwin/spawn.cc b/winsup/cygwin/spawn.cc
deleted file mode 100644
index 510031911..000000000
--- a/winsup/cygwin/spawn.cc
+++ /dev/null
@@ -1,980 +0,0 @@
-/* spawn.cc
-
- Copyright 1996, 1997, 1998, 1999, 2000 Cygnus Solutions.
-
-This file is part of Cygwin.
-
-This software is a copyrighted work licensed under the terms of the
-Cygwin license. Please consult the file "CYGWIN_LICENSE" for
-details. */
-
-#include <stdlib.h>
-#include <stdarg.h>
-#include <unistd.h>
-#include <process.h>
-#include <sys/wait.h>
-#include <errno.h>
-#include <limits.h>
-#include "winsup.h"
-#include <ctype.h>
-#include "paths.h"
-
-extern BOOL allow_ntsec;
-
-#define LINE_BUF_CHUNK (MAX_PATH * 2)
-
-suffix_info std_suffixes[] =
-{
- suffix_info (".exe", 1), suffix_info ("", 1),
- suffix_info (".com"), suffix_info (".cmd"),
- suffix_info (".bat"), suffix_info (".dll"),
- suffix_info (NULL)
-};
-
-/* Add .exe to PROG if not already present and see if that exists.
- If not, return PROG (converted from posix to win32 rules if necessary).
- The result is always BUF.
-
- Returns (possibly NULL) suffix */
-
-static const char *
-perhaps_suffix (const char *prog, char *buf)
-{
- char *ext;
-
- debug_printf ("prog '%s'", prog);
- path_conv temp (prog, SYMLINK_FOLLOW, 1, std_suffixes);
- strcpy (buf, temp.get_win32 ());
-
- if (temp.file_attributes () & FILE_ATTRIBUTE_DIRECTORY)
- ext = NULL;
- else if (temp.known_suffix)
- ext = buf + (temp.known_suffix - temp.get_win32 ());
- else
- ext = strchr (buf, '\0');
-
- debug_printf ("buf %s, suffix found '%s'", buf, ext);
- return ext;
-}
-
-/* Find an executable name, possibly by appending known executable
- suffixes to it. The win32-translated name is placed in 'buf'.
- Any found suffix is returned in known_suffix.
-
- If the file is not found and !null_if_not_found then the win32 version
- of name is placed in buf and returned. Otherwise the contents of buf
- is undefined and NULL is returned. */
-
-const char * __stdcall
-find_exec (const char *name, char *buf, const char *mywinenv,
- int null_if_notfound, const char **known_suffix)
-{
- const char *suffix = "";
- debug_printf ("find_exec (%s)", name);
- char *retval = buf;
-
- /* Check to see if file can be opened as is first.
- Win32 systems always check . first, but PATH may not be set up to
- do this. */
- if ((suffix = perhaps_suffix (name, buf)) != NULL)
- goto out;
-
- win_env *winpath;
- const char *path;
- char tmp[MAX_PATH];
-
- /* Return the error condition if this is an absolute path or if there
- is no PATH to search. */
- if (strchr (name, '/') || strchr (name, '\\') ||
- isalpha (name[0]) && name[1] == ':' ||
- !(winpath = getwinenv (mywinenv)) ||
- !(path = winpath->get_native ()) ||
- *path == '\0')
- goto errout;
-
- debug_printf ("%s%s", mywinenv, path);
-
- /* Iterate over the specified path, looking for the file with and
- without executable extensions. */
- do
- {
- char *eotmp = strccpy (tmp, &path, ';');
- /* An empty path or '.' means the current directory, but we've
- already tried that. */
- if (tmp[0] == '\0' || (tmp[0] == '.' && tmp[1] == '\0'))
- continue;
-
- *eotmp++ = '\\';
- strcpy (eotmp, name);
-
- debug_printf ("trying %s", tmp);
-
- if ((suffix = perhaps_suffix (tmp, buf)) != NULL)
- goto out;
- }
- while (*path && *++path);
-
-errout:
- /* Couldn't find anything in the given path.
- Take the appropriate action based on null_if_not_found. */
- if (null_if_notfound)
- retval = NULL;
- else
- strcpy (buf, path_conv (name).get_win32 ());
-
-out:
- debug_printf ("%s = find_exec (%s)", buf, name);
- if (known_suffix)
- *known_suffix = suffix ?: strchr (buf, '\0');
- return retval;
-}
-
-/* Utility for spawn_guts. */
-
-static HANDLE
-handle (int n, int direction)
-{
- fhandler_base *fh = dtable[n];
-
- if (!fh)
- return INVALID_HANDLE_VALUE;
- if (fh->get_close_on_exec ())
- return INVALID_HANDLE_VALUE;
- if (direction == 0)
- return fh->get_handle ();
- return fh->get_output_handle ();
-}
-
-/* Cover function for CreateProcess.
-
- This function is used by both the routines that search $PATH and those
- that do not. This should work out ok as according to the documentation,
- CreateProcess only searches $PATH if PROG has no directory elements.
-
- Spawning doesn't fit well with Posix's fork/exec (one can argue the merits
- of either but that's beside the point). If we're exec'ing we want to
- record the child pid for fork. If we're spawn'ing we don't want to do
- this. It is up to the caller to handle both cases.
-
- The result is the process id. The handle of the created process is
- stored in H.
-*/
-
-HANDLE NO_COPY hExeced = NULL;
-DWORD NO_COPY exec_exit = 0;
-
-int
-iscmd (const char *argv0, const char *what)
-{
- int n;
- n = strlen (argv0) - strlen (what);
- if (n >= 2 && argv0[1] != ':')
- return 0;
- return n >= 0 && strcasecmp (argv0 + n, what) == 0 &&
- (n == 0 || isdirsep (argv0[n - 1]));
-}
-
-class linebuf
-{
-public:
- size_t ix;
- char *buf;
- size_t alloced;
- linebuf () : ix (0), buf (NULL), alloced (0)
- {
- }
- ~linebuf () {/* if (buf) free (buf);*/}
- void add (const char *what, int len);
- void add (const char *what) {add (what, strlen (what));}
- void prepend (const char *what, int len);
-};
-
-void
-linebuf::add (const char *what, int len)
-{
- size_t newix;
- if ((newix = ix + len) >= alloced || !buf)
- {
- alloced += LINE_BUF_CHUNK + newix;
- buf = (char *) realloc (buf, alloced + 1);
- }
- memcpy (buf + ix, what, len);
- ix = newix;
- buf[ix] = '\0';
-}
-
-void
-linebuf::prepend (const char *what, int len)
-{
- int buflen;
- size_t newix;
- if ((newix = ix + len) >= alloced)
- {
- alloced += LINE_BUF_CHUNK + newix;
- buf = (char *) realloc (buf, alloced + 1);
- buf[ix] = '\0';
- }
- if ((buflen = strlen (buf)))
- memmove (buf + len, buf, buflen + 1);
- else
- buf[newix] = '\0';
- memcpy (buf, what, len);
- ix = newix;
-}
-
-int __stdcall
-spawn_guts (HANDLE hToken, const char * prog_arg, const char *const *argv,
- const char *const envp[], pinfo *child, int mode)
-{
- int i;
- BOOL rc;
- int argc;
-
- hExeced = NULL;
-
- MALLOC_CHECK;
-
- if (prog_arg == NULL)
- {
- syscall_printf ("prog_arg is NULL");
- set_errno(EINVAL);
- return -1;
- }
-
- syscall_printf ("spawn_guts (%.132s)", prog_arg);
-
- if (argv == NULL)
- {
- syscall_printf ("argv is NULL");
- set_errno(EINVAL);
- return (-1);
- }
-
- /* CreateProcess takes one long string that is the command line (sigh).
- We need to quote any argument that has whitespace or embedded "'s. */
-
- for (argc = 0; argv[argc]; argc++)
- /* nothing */;
-
- char *real_path;
- char real_path_buf[MAX_PATH];
-
- linebuf one_line;
-
- if (argc == 3 && argv[1][0] == '/' && argv[1][1] == 'c' &&
- (iscmd (argv[0], "command.com") || iscmd (argv[0], "cmd.exe")))
- {
- one_line.add (argv[0]);
- one_line.add (" ");
- one_line.add (argv[1]);
- one_line.add (" ");
- real_path = NULL;
- one_line.add (argv[2]);
- strcpy (real_path_buf, argv[0]);
- goto skip_arg_parsing;
- }
-
- MALLOC_CHECK;
-
- real_path = real_path_buf;
-
- const char *saved_prog_arg;
- const char *newargv0, **firstarg;
- const char *ext;
-
- if ((ext = perhaps_suffix (prog_arg, real_path)) == NULL)
- {
- set_errno (ENOENT);
- return -1;
- }
-
- MALLOC_CHECK;
- saved_prog_arg = prog_arg;
- newargv0 = argv[0];
- firstarg = &newargv0;
-
- /* If the file name ends in either .exe, .com, .bat, or .cmd we assume
- that it is NOT a script file */
- while (*ext == '\0')
- {
- HANDLE hnd = CreateFileA (real_path,
- GENERIC_READ,
- FILE_SHARE_READ | FILE_SHARE_WRITE,
- &sec_none_nih,
- OPEN_EXISTING,
- FILE_ATTRIBUTE_NORMAL,
- 0);
- if (hnd == INVALID_HANDLE_VALUE)
- {
- __seterrno ();
- return -1;
- }
-
- DWORD done;
-
- char buf[2 * MAX_PATH + 1];
- buf[0] = buf[1] = buf[2] = buf[sizeof(buf) - 1] = '\0';
- if (! ReadFile (hnd, buf, sizeof (buf) - 1, &done, 0))
- {
- CloseHandle (hnd);
- __seterrno ();
- return -1;
- }
-
- CloseHandle (hnd);
-
- if (buf[0] == 'M' && buf[1] == 'Z')
- break;
-
- debug_printf ("%s is a script", prog_arg);
-
- char *ptr, *pgm, *arg1;
-
- if (buf[0] != '#' || buf[1] != '!')
- {
- strcpy (buf, "sh"); /* shell script without magic */
- pgm = buf;
- ptr = buf + 2;
- arg1 = NULL;
- }
- else
- {
- pgm = buf + 2;
- pgm += strspn (pgm, " \t");
- for (ptr = pgm, arg1 = NULL;
- *ptr && *ptr != '\r' && *ptr != '\n';
- ptr++)
- if (!arg1 && (*ptr == ' ' || *ptr == '\t'))
- {
- /* Null terminate the initial command and step over
- any additional white space. If we've hit the
- end of the line, exit the loop. Otherwise, position
- we've found the first argument. Position the current
- pointer on the last known white space. */
- *ptr = '\0';
- char *newptr = ptr + 1;
- newptr += strspn (newptr, " \t");
- if (!*newptr || *newptr == '\r' || *newptr == '\n')
- break;
- arg1 = newptr;
- ptr = newptr - 1;
- }
-
-
- *ptr = '\0';
- }
-
- char buf2[MAX_PATH + 1];
-
- /* pointers:
- * pgm interpreter name
- * arg1 optional string
- * ptr end of string
- */
-
- if (!arg1)
- one_line.prepend (" ", 1);
- else
- {
- one_line.prepend ("\" ", 2);
- one_line.prepend (arg1, strlen (arg1));
- one_line.prepend (" \"", 2);
- }
-
- find_exec (pgm, real_path, "PATH=", 0, &ext);
- cygwin_conv_to_posix_path (real_path, buf2);
- one_line.prepend (buf2, strlen (buf2));
-
- /* If script had absolute path, add it to script name now!
- * This is necessary if script has been found via PATH.
- * For example, /usr/local/bin/tkman started as "tkman":
- * #!/usr/local/bin/wish -f
- * ...
- * We should run /usr/local/bin/wish -f /usr/local/bin/tkman,
- * but not /usr/local/bin/wish -f tkman!
- * We don't modify anything, if script has qulified path.
- */
- if (firstarg)
- *firstarg = saved_prog_arg;
-
- debug_printf ("prog_arg '%s', copy '%s'", prog_arg, one_line.buf);
- firstarg = NULL;
- }
-
- for (; *argv; argv++)
- {
- char *p = NULL;
- const char *a = newargv0 ?: *argv;
-
- MALLOC_CHECK;
-
- newargv0 = NULL;
- int len = strlen (a);
- if (len != 0 && !(p = strpbrk (a, " \t\n\r\"")))
- one_line.add (a, len);
- else
- {
- one_line.add ("\"", 1);
- for (; p; a = p, p = strchr (p, '"'))
- {
- one_line.add (a, ++p - a);
- if (p[-1] == '"')
- one_line.add ("\"", 1);
- }
- if (*a)
- one_line.add (a);
- one_line.add ("\"", 1);
- }
- MALLOC_CHECK;
- one_line.add (" ", 1);
- MALLOC_CHECK;
- }
-
- MALLOC_CHECK;
- if (one_line.ix)
- one_line.buf[one_line.ix - 1] = '\0';
- else
- one_line.add ("", 1);
- MALLOC_CHECK;
-
-skip_arg_parsing:
- PROCESS_INFORMATION pi = {0};
-
- STARTUPINFO si = {0};
- si.lpReserved = NULL;
- si.lpDesktop = NULL;
- si.dwFlags = STARTF_USESTDHANDLES;
- si.hStdInput = handle (0, 0); /* Get input handle */
- si.hStdOutput = handle (1, 1); /* Get output handle */
- si.hStdError = handle (2, 1); /* Get output handle */
- si.cb = sizeof (si);
-
- /* Pass fd table to a child */
-
- MALLOC_CHECK;
- int len = dtable.linearize_fd_array (0, 0);
- MALLOC_CHECK;
- if (len == -1)
- {
- system_printf ("FATAL error in linearize_fd_array");
- return -1;
- }
- int titlelen = 1 + (old_title && mode == _P_OVERLAY ? strlen (old_title) : 0);
- si.cbReserved2 = len + titlelen + sizeof(child_info);
- si.lpReserved2 = (LPBYTE) alloca (si.cbReserved2);
-
-# define ciresrv ((child_info *)si.lpReserved2)
- HANDLE spr = NULL;
- DWORD chtype;
- if (mode != _P_OVERLAY)
- chtype = PROC_SPAWN;
- else
- {
- spr = CreateEvent(&sec_all, TRUE, FALSE, NULL);
- ProtectHandle (spr);
- chtype = PROC_EXEC;
- }
-
- init_child_info (chtype, ciresrv, child->pid, spr);
-
- LPBYTE resrv = si.lpReserved2 + sizeof *ciresrv;
-# undef ciresrv
-
- if (dtable.linearize_fd_array (resrv, len) < 0)
- {
- system_printf ("FATAL error in second linearize_fd_array");
- return -1;
- }
-
- if (titlelen > 1)
- strcpy ((char *) resrv + len, old_title);
- else
- resrv[len] = '\0';
-
- /* We print the translated program and arguments here so the user can see
- what was done to it. */
- syscall_printf ("spawn_guts (%s, %.132s)", real_path, one_line.buf);
-
- int flags = CREATE_DEFAULT_ERROR_MODE | CREATE_SUSPENDED |
- GetPriorityClass (hMainProc);
-
- if (mode == _P_DETACH || !set_console_state_for_spawn ())
- flags |= DETACHED_PROCESS;
-
- MALLOC_CHECK;
- /* Build windows style environment list */
- char *envblock = winenv (envp);
- MALLOC_CHECK;
-
- /* Preallocated buffer for `sec_user' call */
- char sa_buf[1024];
-
- if (hToken)
- {
- /* allow the child to interact with our window station/desktop */
- HANDLE hwst, hdsk;
- SECURITY_INFORMATION dsi = DACL_SECURITY_INFORMATION;
- DWORD n;
- char wstname[1024];
- char dskname[1024];
-
- hwst = GetProcessWindowStation();
- SetUserObjectSecurity(hwst, &dsi, get_null_sd ());
- GetUserObjectInformation(hwst, UOI_NAME, wstname, 1024, &n);
- hdsk = GetThreadDesktop(GetCurrentThreadId());
- SetUserObjectSecurity(hdsk, &dsi, get_null_sd ());
- GetUserObjectInformation(hdsk, UOI_NAME, dskname, 1024, &n);
- strcat (wstname, "\\");
- strcat (wstname, dskname);
- si.lpDesktop = wstname;
- /* force the new process to reread /etc/passwd and /etc/group */
- child->uid = USHRT_MAX;
- child->username[0] = '\0';
-
- char tu[1024];
- PSID sid = NULL;
- DWORD ret_len;
- if (GetTokenInformation (hToken, TokenUser,
- (LPVOID) &tu, sizeof tu,
- &ret_len))
- sid = ((TOKEN_USER *) &tu)->User.Sid;
- else
- system_printf ("GetTokenInformation: %E");
-
- rc = CreateProcessAsUser (hToken,
- real_path, /* image name - with full path */
- one_line.buf, /* what was passed to exec */
- /* process security attrs */
- allow_ntsec && sid ? sec_user (sa_buf, sid)
- : &sec_all_nih,
- /* thread security attrs */
- allow_ntsec && sid ? sec_user (sa_buf, sid)
- : &sec_all_nih,
- TRUE, /* inherit handles from parent */
- flags,
- envblock,/* environment */
- 0, /* use current drive/directory */
- &si,
- &pi);
- }
- else
- rc = CreateProcessA (real_path, /* image name - with full path */
- one_line.buf, /* what was passed to exec */
- /* process security attrs */
- allow_ntsec ? sec_user (sa_buf) : &sec_all_nih,
- /* thread security attrs */
- allow_ntsec ? sec_user (sa_buf) : &sec_all_nih,
- TRUE, /* inherit handles from parent */
- flags,
- envblock,/* environment */
- 0, /* use current drive/directory */
- &si,
- &pi);
-
- MALLOC_CHECK;
- free (envblock);
- MALLOC_CHECK;
-
- /* Set errno now so that debugging messages from it appear before our
- final debugging message [this is a general rule for debugging
- messages]. */
- if (!rc)
- __seterrno ();
-
- MALLOC_CHECK;
- /* Name the handle similarly to proc_subproc. */
- ProtectHandle1 (pi.hProcess, childhProc);
- ProtectHandle (pi.hThread);
- MALLOC_CHECK;
-
- /* We print the original program name here so the user can see that too. */
- syscall_printf ("%d = spawn_guts (%s, %.132s)",
- rc ? pi.dwProcessId : (unsigned int) -1,
- prog_arg, one_line.buf);
-
- if (!rc)
- {
- if (spr)
- ForceCloseHandle (spr);
- return -1;
- }
-
- /* Set up child's signal handlers */
- for (i = 0; i < NSIG; i++)
- {
- child->getsig(i).sa_mask = 0;
- if (myself->getsig(i).sa_handler != SIG_IGN || (mode != _P_OVERLAY))
- child->getsig(i).sa_handler = SIG_DFL;
- }
-
- if (mode == _P_OVERLAY)
- {
- close_all_files ();
- strcpy (child->progname, real_path_buf);
- proc_terminate ();
- hExeced = pi.hProcess;
- }
- else
- {
- child->dwProcessId = pi.dwProcessId;
- child->hProcess = pi.hProcess;
- child->process_state |= PID_INITIALIZING;
- proc_register (child);
- }
-
- sigproc_printf ("spawned windows pid %d", pi.dwProcessId);
- /* Start the child running */
- ResumeThread (pi.hThread);
- ForceCloseHandle (pi.hThread);
-
- if (hToken)
- CloseHandle (hToken);
-
- DWORD res;
-
- if (mode == _P_OVERLAY)
- {
- BOOL exited;
-
- HANDLE waitbuf[3] = {pi.hProcess, signal_arrived, spr};
- int nwait = 3;
-
- SetThreadPriority (GetCurrentThread (), THREAD_PRIORITY_HIGHEST);
- res = 0;
- DWORD timeout = INFINITE;
- exec_exit = 1;
- exited = FALSE;
- MALLOC_CHECK;
- waitfor:
- switch (WaitForMultipleObjects (nwait, waitbuf, FALSE, timeout))
- {
- case WAIT_TIMEOUT:
- syscall_printf ("WFMO timed out after signal");
- if (WaitForSingleObject (pi.hProcess, 0) != WAIT_OBJECT_0)
- {
- sigproc_printf ("subprocess still alive after signal");
- res = exec_exit;
- }
- else
- {
- sigproc_printf ("subprocess exited after signal");
- case WAIT_OBJECT_0:
- sigproc_printf ("subprocess exited");
- if (!GetExitCodeProcess (pi.hProcess, &res))
- res = exec_exit;
- exited = TRUE;
- }
- if (nwait > 2)
- if (WaitForSingleObject (spr, 1) == WAIT_OBJECT_0)
- res |= EXIT_REPARENTING;
- else if (!(res & EXIT_REPARENTING))
- {
- MALLOC_CHECK;
- close_all_files ();
- MALLOC_CHECK;
- }
- break;
- case WAIT_OBJECT_0 + 1:
- sigproc_printf ("signal arrived");
- timeout = 10;
- goto waitfor;
- case WAIT_OBJECT_0 + 2:
- res = EXIT_REPARENTING;
- MALLOC_CHECK;
- ForceCloseHandle (spr);
- MALLOC_CHECK;
- if (!parent_alive)
- {
- nwait = 1;
- sigproc_terminate ();
- goto waitfor;
- }
- break;
- case WAIT_FAILED:
- DWORD r;
- system_printf ("wait failed: nwait %d, pid %d, winpid %d, %E",
- nwait, myself->pid, myself->dwProcessId);
- system_printf ("waitbuf[0] %p %d", waitbuf[0],
- GetHandleInformation (waitbuf[0], &r));
- system_printf ("waitbuf[1] %p = %d", waitbuf[1],
- GetHandleInformation (waitbuf[1], &r));
- set_errno (ECHILD);
- return -1;
- }
-
- if (nwait > 2)
- ForceCloseHandle (spr);
-
- sigproc_printf ("res = %x", res);
-
- if (res & EXIT_REPARENTING)
- {
- /* Try to reparent child process.
- * Make handles to child available to parent process and exit with
- * EXIT_REPARENTING status. Wait() syscall in parent will then wait
- * for newly created child.
- */
- if (my_parent_is_alive ())
- {
- pinfo *parent = procinfo (myself->ppid);
- sigproc_printf ("parent = %p", parent);
- HANDLE hP = OpenProcess (PROCESS_ALL_ACCESS, FALSE,
- parent->dwProcessId);
- sigproc_printf ("parent's handle = %d", hP);
- if (hP == NULL && GetLastError () == ERROR_INVALID_PARAMETER)
- res = 1;
- else if (hP)
- {
- ProtectHandle (hP);
- res = DuplicateHandle (hMainProc, pi.hProcess, hP,
- &myself->hProcess, 0, FALSE,
- DUPLICATE_SAME_ACCESS);
- sigproc_printf ("Dup hP %d", res);
- ForceCloseHandle (hP);
- }
- if (!res)
- {
- system_printf ("Reparent failed, parent handle %p, %E", hP);
- system_printf ("my dwProcessId %d, myself->dwProcessId %d",
- GetCurrentProcessId(), myself->dwProcessId);
- system_printf ("myself->process_state %x",
- myself->process_state);
- system_printf ("myself->hProcess %x", myself->hProcess);
- }
- }
- res = EXIT_REPARENTING;
- ForceCloseHandle1 (hExeced, childhProc);
- hExeced = INVALID_HANDLE_VALUE;
- }
- else if (exited)
- {
- ForceCloseHandle1 (hExeced, childhProc);
- hExeced = INVALID_HANDLE_VALUE; // stop do_exit from attempting to terminate child
- }
-
- MALLOC_CHECK;
- do_exit (res | EXIT_NOCLOSEALL);
- }
-
- if (mode == _P_WAIT)
- {
- waitpid (child->pid, (int *) &res, 0);
- }
- else if (mode == _P_DETACH)
- {
- /* Lose all memory of this child. */
- res = 0;
- }
- else if ((mode == _P_NOWAIT) || (mode == _P_NOWAITO))
- {
- res = child->pid;
- }
-
- return (int) res;
-}
-
-extern "C"
-int
-cwait (int *result, int pid, int)
-{
- return waitpid (pid, result, 0);
-}
-
-/*
- * Helper function for spawn runtime calls.
- * Doesn't search the path.
- */
-
-extern "C" int
-_spawnve (HANDLE hToken, int mode, const char *path, const char *const *argv,
- const char *const *envp)
-{
- pinfo *child;
- int ret;
- vfork_save *vf = vfork_storage.val ();
-
- if (vf != NULL && (vf->pid < 0) && mode == _P_OVERLAY)
- mode = _P_NOWAIT;
- else
- vf = NULL;
-
- syscall_printf ("_spawnve (%s, %s, %x)", path, argv[0], envp);
-
- switch (mode)
- {
- case _P_OVERLAY:
- /* We do not pass _P_SEARCH_PATH here. execve doesn't search PATH.*/
- /* Just act as an exec if _P_OVERLAY set. */
- spawn_guts (hToken, path, argv, envp, myself, mode);
- /* Errno should be set by spawn_guts. */
- ret = -1;
- break;
- case _P_NOWAIT:
- case _P_NOWAITO:
- case _P_WAIT:
- case _P_DETACH:
- child = cygwin_shared->p.allocate_pid ();
- if (!child)
- {
- set_errno (EAGAIN);
- syscall_printf ("-1 = spawnve (), process table full");
- return -1;
- }
- strcpy (child->progname, path);
- child->ppid = myself->pid;
- child->uid = myself->uid;
- child->gid = myself->gid;
- child->pgid = myself->pgid;
- child->sid = myself->sid;
- child->ctty = myself->ctty;
- child->umask = myself->umask;
- child->process_state |= PID_INITIALIZING;
- memcpy (child->username, myself->username, MAX_USER_NAME);
- child->psid = myself->psid;
- memcpy (child->sidbuf, myself->sidbuf, 40);
- memcpy (child->logsrv, myself->logsrv, 256);
- memcpy (child->domain, myself->domain, MAX_COMPUTERNAME_LENGTH+1);
- subproc_init ();
- ret = spawn_guts (hToken, path, argv, envp, child, mode);
- if (ret == -1)
- child->process_state = PID_NOT_IN_USE;
-
- if (vf)
- {
- vf->pid = child->pid;
- longjmp (vf->j, 1);
- }
- break;
- default:
- set_errno (EINVAL);
- ret = -1;
- break;
- }
- return ret;
-}
-
-/*
- * spawn functions as implemented in the MS runtime library.
- * Most of these based on (and copied from) newlib/libc/posix/execXX.c
- */
-
-extern "C"
-int
-spawnl (int mode, const char *path, const char *arg0, ...)
-{
- int i;
- va_list args;
- const char *argv[256];
-
- va_start (args, arg0);
- argv[0] = arg0;
- i = 1;
-
- do
- argv[i] = va_arg (args, const char *);
- while (argv[i++] != NULL);
-
- va_end (args);
-
- return _spawnve (NULL, mode, path, (char * const *) argv,
- *user_data->envptr);
-}
-
-extern "C"
-int
-spawnle (int mode, const char *path, const char *arg0, ...)
-{
- int i;
- va_list args;
- const char * const *envp;
- const char *argv[256];
-
- va_start (args, arg0);
- argv[0] = arg0;
- i = 1;
-
- do
- argv[i] = va_arg (args, const char *);
- while (argv[i++] != NULL);
-
- envp = va_arg (args, const char * const *);
- va_end (args);
-
- return _spawnve (NULL, mode, path, (char * const *) argv,
- (char * const *) envp);
-}
-
-extern "C"
-int
-spawnlp (int mode, const char *path, const char *arg0, ...)
-{
- int i;
- va_list args;
- const char *argv[256];
-
- va_start (args, arg0);
- argv[0] = arg0;
- i = 1;
-
- do
- argv[i] = va_arg (args, const char *);
- while (argv[i++] != NULL);
-
- va_end (args);
-
- return spawnvpe (mode, path, (char * const *) argv, *user_data->envptr);
-}
-
-extern "C"
-int
-spawnlpe (int mode, const char *path, const char *arg0, ...)
-{
- int i;
- va_list args;
- const char * const *envp;
- const char *argv[256];
-
- va_start (args, arg0);
- argv[0] = arg0;
- i = 1;
-
- do
- argv[i] = va_arg (args, const char *);
- while (argv[i++] != NULL);
-
- envp = va_arg (args, const char * const *);
- va_end (args);
-
- return spawnvpe (mode, path, (char * const *) argv, envp);
-}
-
-extern "C"
-int
-spawnv (int mode, const char *path, const char * const *argv)
-{
- return _spawnve (NULL, mode, path, argv, *user_data->envptr);
-}
-
-extern "C"
-int
-spawnve (int mode, const char *path, char * const *argv,
- const char * const *envp)
-{
- return _spawnve (NULL, mode, path, argv, envp);
-}
-
-extern "C"
-int
-spawnvp (int mode, const char *path, const char * const *argv)
-{
- return spawnvpe (mode, path, argv, *user_data->envptr);
-}
-
-extern "C"
-int
-spawnvpe (int mode, const char *file, const char * const *argv,
- const char * const *envp)
-{
- char buf[MAXNAMLEN];
- return _spawnve (NULL, mode, find_exec (file, buf), argv, envp);
-}