3 Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
4 2005, 2006, 2007, 2008, 2009, 2010, 2011 Red Hat, Inc.
6 This file is part of Cygwin.
8 This software is a copyrighted work licensed under the terms of the
9 Cygwin license. Please consult the file "CYGWIN_LICENSE" for
22 #include <sys/cygwin.h>
29 #include "child_info.h"
37 static suffix_info NO_COPY exe_suffixes[] =
40 suffix_info (".exe", 1),
46 /* CV, 2009-11-05: Used to be used when searching for DLLs in calls to
47 dlopen(). However, dlopen() on other platforms never adds a suffix by
48 its own. Therefore we use stat_suffixes now, which only adds a .exe
49 suffix for symmetry. */
50 static suffix_info dll_suffixes[] =
54 suffix_info (".exe", 1),
59 /* Add .exe to PROG if not already present and see if that exists.
60 If not, return PROG (converted from posix to win32 rules if necessary).
61 The result is always BUF.
63 Returns (possibly NULL) suffix */
66 perhaps_suffix (const char *prog, path_conv& buf, int& err, unsigned opt)
71 debug_printf ("prog '%s'", prog);
72 buf.check (prog, PC_SYM_FOLLOW | PC_NULLEMPTY,
73 (opt & FE_DLL) ? stat_suffixes : exe_suffixes);
80 else if (!buf.exists ())
85 else if (buf.known_suffix)
86 ext = buf.get_win32 () + (buf.known_suffix - buf.get_win32 ());
88 ext = strchr (buf.get_win32 (), '\0');
90 debug_printf ("buf %s, suffix found '%s'", (char *) buf.get_win32 (), ext);
94 /* Find an executable name, possibly by appending known executable
95 suffixes to it. The win32-translated name is placed in 'buf'.
96 Any found suffix is returned in known_suffix.
98 If the file is not found and !null_if_not_found then the win32 version
99 of name is placed in buf and returned. Otherwise the contents of buf
100 is undefined and NULL is returned. */
102 const char * __stdcall
103 find_exec (const char *name, path_conv& buf, const char *mywinenv,
104 unsigned opt, const char **known_suffix)
106 const char *suffix = "";
107 debug_printf ("find_exec (%s)", name);
110 char *tmp = tp.c_get ();
111 const char *posix = (opt & FE_NATIVE) ? NULL : name;
112 bool has_slash = !!strpbrk (name, "/\\");
115 /* Check to see if file can be opened as is first.
116 Win32 systems always check . first, but PATH may not be set up to
118 if ((has_slash || opt & FE_CWD)
119 && (suffix = perhaps_suffix (name, buf, err, opt)) != NULL)
121 if (posix && !has_slash)
125 strcpy (tmp + 2, name);
128 retval = buf.get_win32 ();
134 const char *posix_path;
136 posix = (opt & FE_NATIVE) ? NULL : tmp;
138 if (strchr (mywinenv, '/'))
140 /* it's not really an environment variable at all */
141 int n = cygwin_conv_path_list (CCP_POSIX_TO_WIN_A, mywinenv, NULL, 0);
142 char *s = (char *) alloca (n);
143 if (cygwin_conv_path_list (CCP_POSIX_TO_WIN_A, mywinenv, s, n))
146 posix_path = mywinenv - 1;
148 else if (has_slash || strchr (name, '\\') || isdrive (name)
149 || !(winpath = getwinenv (mywinenv))
150 || !(path = winpath->get_native ()) || *path == '\0')
151 /* Return the error condition if this is an absolute path or if there
152 is no PATH to search. */
155 posix_path = winpath->get_posix () - 1;
157 debug_printf ("%s%s", mywinenv, path);
158 /* Iterate over the specified path, looking for the file with and without
159 executable extensions. */
163 char *eotmp = strccpy (tmp, &path, ';');
164 /* An empty path or '.' means the current directory, but we've
165 already tried that. */
166 if (opt & FE_CWD && (tmp[0] == '\0' || (tmp[0] == '.' && tmp[1] == '\0')))
170 strcpy (eotmp, name);
172 debug_printf ("trying %s", tmp);
176 if ((suffix = perhaps_suffix (tmp, buf, err1, opt)) != NULL)
178 if (buf.has_acls () && check_file_access (buf, X_OK, true))
183 eotmp = strccpy (tmp, &posix_path, ':');
187 strcpy (eotmp, name);
189 retval = buf.get_win32 ();
193 while (*path && *++path && (posix_path = strchr (posix_path, ':')));
197 /* Couldn't find anything in the given path.
198 Take the appropriate action based on null_if_not_found. */
201 else if (!(opt & FE_NATIVE))
206 retval = buf.get_win32 ();
211 retval = buf.set_path (posix);
212 debug_printf ("%s = find_exec (%s)", (char *) buf.get_win32 (), name);
214 *known_suffix = suffix ?: strchr (buf.get_win32 (), '\0');
220 /* Utility for child_info_spawn::worker. */
223 handle (int fd, bool writing)
226 cygheap_fdget cfd (fd);
229 h = INVALID_HANDLE_VALUE;
230 else if (cfd->close_on_exec ())
231 h = INVALID_HANDLE_VALUE;
233 h = cfd->get_handle ();
235 h = cfd->get_output_handle ();
241 iscmd (const char *argv0, const char *what)
244 n = strlen (argv0) - strlen (what);
245 if (n >= 2 && argv0[1] != ':')
247 return n >= 0 && strcasematch (argv0 + n, what) &&
248 (n == 0 || isdirsep (argv0[n - 1]));
251 struct pthread_cleanup
253 _sig_func_ptr oldint;
254 _sig_func_ptr oldquit;
256 pthread_cleanup (): oldint (NULL), oldquit (NULL), oldmask ((sigset_t) -1) {}
260 do_cleanup (void *args)
262 # define cleanup ((pthread_cleanup *) args)
263 if (cleanup->oldmask != (sigset_t) -1)
265 signal (SIGINT, cleanup->oldint);
266 signal (SIGQUIT, cleanup->oldquit);
267 sigprocmask (SIG_SETMASK, &(cleanup->oldmask), NULL);
272 NO_COPY child_info_spawn ch_spawn;
275 child_info_spawn::worker (const char *prog_arg, const char *const *argv,
276 const char *const envp[], int mode,
277 int in__stdin, int in__stdout)
283 /* Check if we have been called from exec{lv}p or spawn{lv}p and mask
284 mode to keep only the spawn mode. */
285 bool p_type_exec = !!(mode & _P_PATH_TYPE_EXEC);
286 mode = _P_MODE (mode);
288 if (prog_arg == NULL)
290 syscall_printf ("prog_arg is NULL");
291 set_errno (EFAULT); /* As on Linux. */
296 syscall_printf ("prog_arg is empty");
297 set_errno (ENOENT); /* Per POSIX */
301 syscall_printf ("mode = %d, prog_arg = %.9500s", mode, prog_arg);
303 /* FIXME: This is no error condition on Linux. */
306 syscall_printf ("argv is NULL");
311 /* FIXME: There is a small race here and FIXME: not thread safe! */
313 pthread_cleanup cleanup;
314 if (mode == _P_SYSTEM)
316 sigset_t child_block;
317 cleanup.oldint = signal (SIGINT, SIG_IGN);
318 cleanup.oldquit = signal (SIGQUIT, SIG_IGN);
319 sigemptyset (&child_block);
320 sigaddset (&child_block, SIGCHLD);
321 sigprocmask (SIG_BLOCK, &child_block, &cleanup.oldmask);
323 pthread_cleanup_push (do_cleanup, (void *) &cleanup);
326 PWCHAR envblock = NULL;
328 bool reset_sendsig = false;
331 PWCHAR runpath = tp.w_get ();
335 bool null_app_name = false;
336 STARTUPINFOW si = {};
338 HANDLE orig_wr_proc_pipe = NULL;
341 if (efault.faulted ())
343 if (get_errno () == ENOMEM)
351 child_info_types chtype;
352 if (mode != _P_OVERLAY)
357 moreinfo = cygheap_exec_info::alloc ();
359 /* CreateProcess takes one long string that is the command line (sigh).
360 We need to quote any argument that has whitespace or embedded "'s. */
363 for (ac = 0; argv[ac]; ac++)
366 newargv.set (ac, argv);
370 if ((ext = perhaps_suffix (prog_arg, real_path, err, FE_NADA)) == NULL)
378 wascygexec = real_path.iscygexec ();
379 res = newargv.fixup (prog_arg, real_path, ext, p_type_exec);
384 if (!real_path.iscygexec () && ::cygheap->cwd.get_error ())
386 small_printf ("Error: Current working directory %s.\n"
387 "Can't start native Windows application from here.\n\n",
388 ::cygheap->cwd.get_error_desc ());
389 set_errno (::cygheap->cwd.get_error ());
394 if (ac == 3 && argv[1][0] == '/' && argv[1][1] == 'c' &&
395 (iscmd (argv[0], "command.com") || iscmd (argv[0], "cmd.exe")))
397 real_path.check (prog_arg);
399 if (!real_path.error)
400 one_line.add (real_path.get_win32 ());
402 one_line.add (argv[0]);
405 one_line.add (argv[1]);
407 one_line.add (argv[2]);
408 real_path.set_path (argv[0]);
409 null_app_name = true;
415 else if (!one_line.fromargv (newargv, real_path.get_win32 (),
416 real_path.iscygexec ()))
423 newargv.all_calloced ();
424 moreinfo->argc = newargv.argc;
425 moreinfo->argv = newargv;
427 if (mode != _P_OVERLAY ||
428 !DuplicateHandle (GetCurrentProcess (), myself.shared_handle (),
429 GetCurrentProcess (), &moreinfo->myself_pinfo,
430 0, TRUE, DUPLICATE_SAME_ACCESS))
431 moreinfo->myself_pinfo = NULL;
433 VerifyHandle (moreinfo->myself_pinfo);
435 WCHAR wone_line[one_line.ix + 1];
437 sys_mbstowcs (wone_line, one_line.ix + 1, one_line.buf);
439 wone_line[0] = L'\0';
441 PROCESS_INFORMATION pi;
442 pi.hProcess = pi.hThread = NULL;
443 pi.dwProcessId = pi.dwThreadId = 0;
445 /* Set up needed handles for stdio */
446 si.dwFlags = STARTF_USESTDHANDLES;
447 si.hStdInput = handle ((in__stdin < 0 ? 0 : in__stdin), false);
448 si.hStdOutput = handle ((in__stdout < 0 ? 1 : in__stdout), true);
449 si.hStdError = handle (2, true);
453 c_flags = GetPriorityClass (GetCurrentProcess ());
454 sigproc_printf ("priority class %d", c_flags);
455 c_flags |= CREATE_SEPARATE_WOW_VDM | CREATE_UNICODE_ENVIRONMENT;
457 if (mode == _P_DETACH)
458 c_flags |= DETACHED_PROCESS;
460 fhandler_console::need_invisible ();
462 if (mode != _P_OVERLAY)
463 myself->exec_sendsig = NULL;
466 /* Reset sendsig so that any process which wants to send a signal
467 to this pid will wait for the new process to become active.
468 Save the old value in case the exec fails. */
469 if (!myself->exec_sendsig)
471 myself->exec_sendsig = myself->sendsig;
472 myself->exec_dwProcessId = myself->dwProcessId;
473 myself->sendsig = NULL;
474 reset_sendsig = true;
476 /* Save a copy of a handle to the current process around the first time we
477 exec so that the pid will not be reused. Why did I stop cygwin from
478 generating its own pids again? */
479 if (::cygheap->pid_handle)
480 /* already done previously */;
481 else if (DuplicateHandle (GetCurrentProcess (), GetCurrentProcess (),
482 GetCurrentProcess (), &::cygheap->pid_handle,
483 PROCESS_QUERY_INFORMATION, TRUE, 0))
484 ProtectHandleINH (::cygheap->pid_handle);
486 system_printf ("duplicate to pid_handle failed, %E");
493 USHORT len = real_path.get_nt_native_path ()->Length / sizeof (WCHAR);
494 if (RtlEqualUnicodePathPrefix (real_path.get_nt_native_path (),
497 runpath = real_path.get_wide_win32_path (runpath);
498 /* If the executable path length is < MAX_PATH, make sure the long
499 path win32 prefix is removed from the path to make subsequent
500 not long path aware native Win32 child processes happy. */
501 if (len < MAX_PATH + 4)
503 if (runpath[5] == ':')
505 else if (len < MAX_PATH + 6)
506 *(runpath += 6) = L'\\';
509 else if (len < NT_MAX_PATH - ro_u_globalroot.Length / sizeof (WCHAR))
511 UNICODE_STRING rpath;
513 RtlInitEmptyUnicodeString (&rpath, runpath,
514 (NT_MAX_PATH - 1) * sizeof (WCHAR));
515 RtlCopyUnicodeString (&rpath, &ro_u_globalroot);
516 RtlAppendUnicodeStringToString (&rpath,
517 real_path.get_nt_native_path ());
521 set_errno (ENAMETOOLONG);
526 syscall_printf ("null_app_name %d (%W, %.9500W)", null_app_name,
529 cygbench ("spawn-worker");
531 if (!real_path.iscygexec())
532 ::cygheap->fdtab.set_file_pointers_for_exec ();
534 moreinfo->envp = build_env (envp, envblock, moreinfo->envc,
535 real_path.iscygexec ());
536 if (!moreinfo->envp || !envblock)
542 set (chtype, real_path.iscygexec ());
544 __stdout = in__stdout;
547 si.lpReserved2 = (LPBYTE) this;
548 si.cbReserved2 = sizeof (*this);
550 /* Depends on set call above.
551 Some file types might need extra effort in the parent after CreateProcess
552 and before copying the datastructures to the child. So we have to start
553 the child in suspend state, unfortunately, to avoid a race condition. */
554 if (!newargv.win16_exe
555 && (!iscygwin () || mode != _P_OVERLAY
556 || ::cygheap->fdtab.need_fixup_before ()))
557 c_flags |= CREATE_SUSPENDED;
558 /* If a native application should be spawned, we test here if the spawning
559 process is running in a console and, if so, if it's a foreground or
560 background process. If it's a background process, we start the native
561 process with the CREATE_NEW_PROCESS_GROUP flag set. This lets the native
562 process ignore Ctrl-C by default. If we don't do that, pressing Ctrl-C
563 in a console will break native processes running in the background,
564 because the Ctrl-C event is sent to all processes in the console, unless
565 they ignore it explicitely. CREATE_NEW_PROCESS_GROUP does that for us. */
566 if (!iscygwin () && myself->ctty >= 0 && iscons_dev (myself->ctty)
567 && fhandler_console::tc_getpgid () != getpgrp ())
568 c_flags |= CREATE_NEW_PROCESS_GROUP;
570 /* When ruid != euid we create the new process under the current original
571 account and impersonate in child, this way maintaining the different
572 effective vs. real ids.
573 FIXME: If ruid != euid and ruid != saved_uid we currently give
574 up on ruid. The new process will have ruid == euid. */
576 ::cygheap->user.deimpersonate ();
578 if (!real_path.iscygexec () && mode == _P_OVERLAY)
579 myself->process_state |= PID_NOTCYGWIN;
581 if (!::cygheap->user.issetuid ()
582 || (::cygheap->user.saved_uid == ::cygheap->user.real_uid
583 && ::cygheap->user.saved_gid == ::cygheap->user.real_gid
584 && !::cygheap->user.groups.issetgroups ()
585 && !::cygheap->user.setuid_to_restricted))
587 rc = CreateProcessW (runpath, /* image name - with full path */
588 wone_line, /* what was passed to exec */
589 &sec_none_nih, /* process security attrs */
590 &sec_none_nih, /* thread security attrs */
591 TRUE, /* inherit handles from parent */
593 envblock, /* environment */
600 /* Give access to myself */
601 if (mode == _P_OVERLAY)
604 WCHAR wstname[1024] = { L'\0' };
605 HWINSTA hwst_orig = NULL, hwst = NULL;
606 HDESK hdsk_orig = NULL, hdsk = NULL;
607 PSECURITY_ATTRIBUTES sa;
610 hwst_orig = GetProcessWindowStation ();
611 hdsk_orig = GetThreadDesktop (GetCurrentThreadId ());
612 GetUserObjectInformationW (hwst_orig, UOI_NAME, wstname, 1024, &n);
613 /* Prior to Vista it was possible to start a service with the
614 "Interact with desktop" flag. This started the service in the
615 interactive window station of the console. A big security
616 risk, but we don't want to disable this behaviour for older
617 OSes because it's still heavily used by some users. They have
619 if (!::cygheap->user.setuid_to_restricted
620 && wcscasecmp (wstname, L"WinSta0") != 0)
624 sa = sec_user ((PSECURITY_ATTRIBUTES) alloca (1024),
625 ::cygheap->user.sid ());
626 /* We're creating a window station per user, not per logon session.
627 First of all we might not have a valid logon session for
628 the user (logon by create_token), and second, it doesn't
629 make sense in terms of security to create a new window
630 station for every logon of the same user. It just fills up
631 the system with window stations for no good reason. */
632 hwst = CreateWindowStationW (::cygheap->user.get_windows_id (sid), 0,
633 GENERIC_READ | GENERIC_WRITE, sa);
635 system_printf ("CreateWindowStation failed, %E");
636 else if (!SetProcessWindowStation (hwst))
637 system_printf ("SetProcessWindowStation failed, %E");
638 else if (!(hdsk = CreateDesktopW (L"Default", NULL, NULL, 0,
640 system_printf ("CreateDesktop failed, %E");
643 wcpcpy (wcpcpy (wstname, sid), L"\\Default");
644 si.lpDesktop = wstname;
645 debug_printf ("Desktop: %W", si.lpDesktop);
649 rc = CreateProcessAsUserW (::cygheap->user.primary_token (),
650 runpath, /* image name - with full path */
651 wone_line, /* what was passed to exec */
652 &sec_none_nih, /* process security attrs */
653 &sec_none_nih, /* thread security attrs */
654 TRUE, /* inherit handles from parent */
656 envblock, /* environment */
662 SetProcessWindowStation (hwst_orig);
663 CloseWindowStation (hwst);
667 SetThreadDesktop (hdsk_orig);
672 /* Restore impersonation. In case of _P_OVERLAY this isn't
673 allowed since it would overwrite child data. */
674 if (mode != _P_OVERLAY || !rc)
675 ::cygheap->user.reimpersonate ();
677 /* Set errno now so that debugging messages from it appear before our
678 final debugging message [this is a general rule for debugging
683 syscall_printf ("CreateProcess failed, %E");
684 /* If this was a failed exec, restore the saved sendsig. */
687 myself->sendsig = myself->exec_sendsig;
688 myself->exec_sendsig = NULL;
690 myself->process_state &= ~PID_NOTCYGWIN;
695 /* The CREATE_SUSPENDED case is handled below */
696 if (iscygwin () && !(c_flags & CREATE_SUSPENDED))
697 strace.write_childpid (pi.dwProcessId);
699 /* Fixup the parent data structures if needed and resume the child's
701 if (::cygheap->fdtab.need_fixup_before ())
702 ::cygheap->fdtab.fixup_before_exec (pi.dwProcessId);
704 if (mode != _P_OVERLAY)
705 cygpid = cygwin_pid (pi.dwProcessId);
707 cygpid = myself->pid;
709 /* We print the original program name here so the user can see that too. */
710 syscall_printf ("%d = child_info_spawn::worker (%s, %.9500s)",
711 rc ? cygpid : (unsigned int) -1, prog_arg, one_line.buf);
713 /* Name the handle similarly to proc_subproc. */
714 ProtectHandle1 (pi.hProcess, childhProc);
718 if (mode == _P_OVERLAY)
720 myself->dwProcessId = pi.dwProcessId;
722 myself.hProcess = hExeced = pi.hProcess;
723 real_path.get_wide_win32_path (myself->progname); // FIXME: race?
724 sigproc_printf ("new process name %W", myself->progname);
725 /* If wr_proc_pipe doesn't exist then this process was not started by a cygwin
726 process. So, we need to wait around until the process we've just "execed"
727 dies. Use our own wait facility to wait for our own pid to exit (there
728 is some minor special case code in proc_waiter and friends to accommodate
731 If wr_proc_pipe exists, then it should be duplicated to the child.
732 If the child has exited already, that's ok. The parent will pick up
733 on this fact when we exit. dup_proc_pipe will close our end of the pipe.
734 Note that wr_proc_pipe may also be == INVALID_HANDLE_VALUE. That will make
735 dup_proc_pipe essentially a no-op. */
736 if (!newargv.win16_exe && myself->wr_proc_pipe)
739 myself->sync_proc_pipe (); /* Make sure that we own wr_proc_pipe
740 just in case we've been previously
742 orig_wr_proc_pipe = myself->dup_proc_pipe (pi.hProcess);
750 myself->set_has_pgid_children ();
751 ProtectHandle (pi.hThread);
753 PID_IN_USE | (real_path.iscygexec () ? 0 : PID_NOTCYGWIN));
756 syscall_printf ("pinfo failed");
757 if (get_errno () != ENOMEM)
762 child->dwProcessId = pi.dwProcessId;
763 child.hProcess = pi.hProcess;
765 real_path.get_wide_win32_path (child->progname);
766 /* FIXME: This introduces an unreferenced, open handle into the child.
767 The purpose is to keep the pid shared memory open so that all of
768 the fields filled out by child.remember do not disappear and so there
769 is not a brief period during which the pid is not available.
770 However, we should try to find another way to do this eventually. */
771 DuplicateHandle (GetCurrentProcess (), child.shared_handle (),
772 pi.hProcess, NULL, 0, 0, DUPLICATE_SAME_ACCESS);
773 child->start_time = time (NULL); /* Register child's starting time. */
774 child->nice = myself->nice;
775 if (!child.remember (mode == _P_DETACH))
777 /* FIXME: Child in strange state now */
778 CloseHandle (pi.hProcess);
779 ForceCloseHandle (pi.hThread);
786 /* Start the child running */
787 if (c_flags & CREATE_SUSPENDED)
789 ResumeThread (pi.hThread);
791 strace.write_childpid (pi.dwProcessId);
793 ForceCloseHandle (pi.hThread);
795 sigproc_printf ("spawned windows pid %d", pi.dwProcessId);
797 if ((mode == _P_DETACH || mode == _P_NOWAIT) && !iscygwin ())
800 synced = sync (pi.dwProcessId, pi.hProcess, INFINITE);
805 myself.hProcess = pi.hProcess;
808 if (orig_wr_proc_pipe)
810 myself->wr_proc_pipe_owner = GetCurrentProcessId ();
811 myself->wr_proc_pipe = orig_wr_proc_pipe;
813 if (!proc_retry (pi.hProcess))
818 close_all_files (true);
822 close_all_files (true);
823 if (!myself->wr_proc_pipe
824 && WaitForSingleObject (pi.hProcess, 0) == WAIT_TIMEOUT)
826 extern bool is_toplevel_proc;
827 is_toplevel_proc = true;
828 myself.remember (false);
833 myself.exit (EXITCODE_NOSET);
837 if (waitpid (cygpid, &res, 0) != cygpid)
841 res = 0; /* Lost all memory of this child. */
856 pthread_cleanup_pop (1);
861 cwait (int *result, int pid, int)
863 return waitpid (pid, result, 0);
867 * Helper function for spawn runtime calls.
868 * Doesn't search the path.
872 spawnve (int mode, const char *path, const char *const *argv,
873 const char *const *envp)
875 static char *const empty_env[] = { NULL };
879 vfork_save *vf = vfork_storage.val ();
881 if (vf != NULL && (vf->pid < 0) && mode == _P_OVERLAY)
887 syscall_printf ("spawnve (%s, %s, %x)", path, argv[0], envp);
892 switch (_P_MODE (mode))
895 ch_spawn.worker (path, argv, envp, mode);
896 /* Errno should be set by worker. */
905 ret = ch_spawn.worker (path, argv, envp, mode);
911 debug_printf ("longjmping due to vfork");
912 vf->restore_pid (ret);
926 * spawn functions as implemented in the MS runtime library.
927 * Most of these based on (and copied from) newlib/libc/posix/execXX.c
931 spawnl (int mode, const char *path, const char *arg0, ...)
935 const char *argv[256];
937 va_start (args, arg0);
942 argv[i] = va_arg (args, const char *);
943 while (argv[i++] != NULL);
947 return spawnve (mode, path, (char * const *) argv, cur_environ ());
951 spawnle (int mode, const char *path, const char *arg0, ...)
955 const char * const *envp;
956 const char *argv[256];
958 va_start (args, arg0);
963 argv[i] = va_arg (args, const char *);
964 while (argv[i++] != NULL);
966 envp = va_arg (args, const char * const *);
969 return spawnve (mode, path, (char * const *) argv, (char * const *) envp);
973 spawnlp (int mode, const char *file, const char *arg0, ...)
977 const char *argv[256];
980 va_start (args, arg0);
985 argv[i] = va_arg (args, const char *);
986 while (argv[i++] != NULL);
990 return spawnve (mode | _P_PATH_TYPE_EXEC, find_exec (file, buf),
991 (char * const *) argv, cur_environ ());
995 spawnlpe (int mode, const char *file, const char *arg0, ...)
999 const char * const *envp;
1000 const char *argv[256];
1003 va_start (args, arg0);
1008 argv[i] = va_arg (args, const char *);
1009 while (argv[i++] != NULL);
1011 envp = va_arg (args, const char * const *);
1014 return spawnve (mode | _P_PATH_TYPE_EXEC, find_exec (file, buf),
1015 (char * const *) argv, envp);
1019 spawnv (int mode, const char *path, const char * const *argv)
1021 return spawnve (mode, path, argv, cur_environ ());
1025 spawnvp (int mode, const char *file, const char * const *argv)
1028 return spawnve (mode | _P_PATH_TYPE_EXEC, find_exec (file, buf), argv,
1033 spawnvpe (int mode, const char *file, const char * const *argv,
1034 const char * const *envp)
1037 return spawnve (mode | _P_PATH_TYPE_EXEC, find_exec (file, buf), argv, envp);
1041 av::fixup (const char *prog_arg, path_conv& real_path, const char *ext,
1045 bool exeext = ascii_strcasematch (ext, ".exe");
1046 if ((exeext && real_path.iscygexec ()) || ascii_strcasematch (ext, ".bat"))
1048 if (!*ext && ((p = ext - 4) > real_path.get_win32 ())
1049 && (ascii_strcasematch (p, ".bat") || ascii_strcasematch (p, ".cmd")
1050 || ascii_strcasematch (p, ".btm")))
1057 OBJECT_ATTRIBUTES attr;
1063 status = NtOpenFile (&h, SYNCHRONIZE | GENERIC_READ,
1064 real_path.get_object_attr (attr, sec_none_nih),
1065 &io, FILE_SHARE_VALID_FLAGS,
1066 FILE_SYNCHRONOUS_IO_NONALERT
1067 | FILE_OPEN_FOR_BACKUP_INTENT
1068 | FILE_NON_DIRECTORY_FILE);
1069 if (!NT_SUCCESS (status))
1071 /* File is not readable? Doesn't mean it's not executable.
1072 Test for executability and if so, just assume the file is
1073 a cygwin executable and go ahead. */
1074 if (status == STATUS_ACCESS_DENIED && real_path.has_acls ()
1075 && check_file_access (real_path, X_OK, true) == 0)
1077 real_path.set_cygexec (true);
1082 if (!GetFileSizeEx (h, &size))
1087 if (size.QuadPart > wincap.allocation_granularity ())
1088 size.LowPart = wincap.allocation_granularity ();
1090 HANDLE hm = CreateFileMapping (h, &sec_none_nih, PAGE_READONLY,
1095 /* ERROR_FILE_INVALID indicates very likely an empty file. */
1096 if (GetLastError () == ERROR_FILE_INVALID)
1098 debug_printf ("zero length file, treat as script.");
1103 /* Try to map the first 64K of the image. That's enough for the local
1104 tests, and it's enough for hook_or_detect_cygwin to compute the IAT
1106 buf = (char *) MapViewOfFile (hm, FILE_MAP_READ, 0, 0, size.LowPart);
1115 if (efault.faulted ())
1117 UnmapViewOfFile (buf);
1119 real_path.set_cygexec (false);
1122 if (buf[0] == 'M' && buf[1] == 'Z')
1125 unsigned off = (unsigned char) buf[0x18] | (((unsigned char) buf[0x19]) << 8);
1126 win16_exe = off < sizeof (IMAGE_DOS_HEADER);
1128 real_path.set_cygexec (!!hook_or_detect_cygwin (buf, NULL,
1131 real_path.set_cygexec (false);
1132 UnmapViewOfFile (buf);
1139 debug_printf ("%s is possibly a script", real_path.get_win32 ());
1142 if (*ptr++ == '#' && *ptr++ == '!')
1144 ptr += strspn (ptr, " \t");
1145 size_t len = strcspn (ptr, "\r\n");
1148 char *namebuf = (char *) alloca (len + 1);
1149 memcpy (namebuf, ptr, len);
1150 namebuf[len] = '\0';
1151 for (ptr = pgm = namebuf; *ptr; ptr++)
1152 if (!arg1 && (*ptr == ' ' || *ptr == '\t'))
1154 /* Null terminate the initial command and step over any
1155 additional white space. If we've hit the end of the
1156 line, exit the loop. Otherwise, we've found the first
1157 argument. Position the current pointer on the last known
1160 char *newptr = ptr + 1;
1161 newptr += strspn (newptr, " \t");
1169 UnmapViewOfFile (buf);
1175 /* Not called from exec[lv]p. Don't try to treat as script. */
1176 debug_printf ("%s is not a valid executable",
1177 real_path.get_win32 ());
1178 set_errno (ENOEXEC);
1181 if (ascii_strcasematch (ext, ".com"))
1183 pgm = (char *) "/bin/sh";
1187 /* Check if script is executable. Otherwise we start non-executable
1188 scripts successfully, which is incorrect behaviour. */
1189 if (real_path.has_acls ()
1190 && check_file_access (real_path, X_OK, true) < 0)
1191 return -1; /* errno is already set. */
1193 /* Replace argv[0] with the full path to the script if this is the
1194 first time through the loop. */
1195 replace0_maybe (prog_arg);
1198 * pgm interpreter name
1199 * arg1 optional string
1204 /* FIXME: This should not be using FE_NATIVE. It should be putting
1205 the posix path on the argv list. */
1206 find_exec (pgm, real_path, "PATH=", FE_NATIVE, &ext);
1207 unshift (real_path.get_win32 (), 1);