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 /* We're adding the CREATE_BREAKAWAY_FROM_JOB flag here to workaround issues
456 with the "Program Compatibility Assistant (PCA) Service" observed on
457 Windows 7. For some reason, when starting long running sessions from
458 mintty, the affected svchost.exe process takes more and more memory and
459 at one point takes over the CPU. At this point the machine becomes
460 unresponsive. The only way to get back to normal is to stop the entire
461 mintty session, or to stop the PCA service. However, a process which
462 is controlled by PCA is part of a compatibility job, which allows child
463 processes to break away from the job. This helps to avoid this issue. */
464 c_flags |= CREATE_SEPARATE_WOW_VDM | CREATE_UNICODE_ENVIRONMENT
465 | CREATE_BREAKAWAY_FROM_JOB;
467 if (mode == _P_DETACH)
468 c_flags |= DETACHED_PROCESS;
470 fhandler_console::need_invisible ();
472 if (mode != _P_OVERLAY)
473 myself->exec_sendsig = NULL;
476 /* Reset sendsig so that any process which wants to send a signal
477 to this pid will wait for the new process to become active.
478 Save the old value in case the exec fails. */
479 if (!myself->exec_sendsig)
481 myself->exec_sendsig = myself->sendsig;
482 myself->exec_dwProcessId = myself->dwProcessId;
483 myself->sendsig = NULL;
484 reset_sendsig = true;
486 /* Save a copy of a handle to the current process around the first time we
487 exec so that the pid will not be reused. Why did I stop cygwin from
488 generating its own pids again? */
489 if (::cygheap->pid_handle)
490 /* already done previously */;
491 else if (DuplicateHandle (GetCurrentProcess (), GetCurrentProcess (),
492 GetCurrentProcess (), &::cygheap->pid_handle,
493 PROCESS_QUERY_INFORMATION, TRUE, 0))
494 ProtectHandleINH (::cygheap->pid_handle);
496 system_printf ("duplicate to pid_handle failed, %E");
503 USHORT len = real_path.get_nt_native_path ()->Length / sizeof (WCHAR);
504 if (RtlEqualUnicodePathPrefix (real_path.get_nt_native_path (),
507 runpath = real_path.get_wide_win32_path (runpath);
508 /* If the executable path length is < MAX_PATH, make sure the long
509 path win32 prefix is removed from the path to make subsequent
510 not long path aware native Win32 child processes happy. */
511 if (len < MAX_PATH + 4)
513 if (runpath[5] == ':')
515 else if (len < MAX_PATH + 6)
516 *(runpath += 6) = L'\\';
519 else if (len < NT_MAX_PATH - ro_u_globalroot.Length / sizeof (WCHAR))
521 UNICODE_STRING rpath;
523 RtlInitEmptyUnicodeString (&rpath, runpath,
524 (NT_MAX_PATH - 1) * sizeof (WCHAR));
525 RtlCopyUnicodeString (&rpath, &ro_u_globalroot);
526 RtlAppendUnicodeStringToString (&rpath,
527 real_path.get_nt_native_path ());
531 set_errno (ENAMETOOLONG);
536 syscall_printf ("null_app_name %d (%W, %.9500W)", null_app_name,
539 cygbench ("spawn-worker");
541 if (!real_path.iscygexec())
542 ::cygheap->fdtab.set_file_pointers_for_exec ();
544 moreinfo->envp = build_env (envp, envblock, moreinfo->envc,
545 real_path.iscygexec ());
546 if (!moreinfo->envp || !envblock)
552 set (chtype, real_path.iscygexec ());
554 __stdout = in__stdout;
557 si.lpReserved2 = (LPBYTE) this;
558 si.cbReserved2 = sizeof (*this);
560 /* Depends on set call above.
561 Some file types might need extra effort in the parent after CreateProcess
562 and before copying the datastructures to the child. So we have to start
563 the child in suspend state, unfortunately, to avoid a race condition. */
564 if (!newargv.win16_exe
565 && (!iscygwin () || mode != _P_OVERLAY
566 || ::cygheap->fdtab.need_fixup_before ()))
567 c_flags |= CREATE_SUSPENDED;
568 /* If a native application should be spawned, we test here if the spawning
569 process is running in a console and, if so, if it's a foreground or
570 background process. If it's a background process, we start the native
571 process with the CREATE_NEW_PROCESS_GROUP flag set. This lets the native
572 process ignore Ctrl-C by default. If we don't do that, pressing Ctrl-C
573 in a console will break native processes running in the background,
574 because the Ctrl-C event is sent to all processes in the console, unless
575 they ignore it explicitely. CREATE_NEW_PROCESS_GROUP does that for us. */
576 if (!iscygwin () && myself->ctty >= 0 && iscons_dev (myself->ctty)
577 && fhandler_console::tc_getpgid () != getpgrp ())
578 c_flags |= CREATE_NEW_PROCESS_GROUP;
580 /* When ruid != euid we create the new process under the current original
581 account and impersonate in child, this way maintaining the different
582 effective vs. real ids.
583 FIXME: If ruid != euid and ruid != saved_uid we currently give
584 up on ruid. The new process will have ruid == euid. */
586 ::cygheap->user.deimpersonate ();
588 if (!real_path.iscygexec () && mode == _P_OVERLAY)
589 myself->process_state |= PID_NOTCYGWIN;
591 if (!::cygheap->user.issetuid ()
592 || (::cygheap->user.saved_uid == ::cygheap->user.real_uid
593 && ::cygheap->user.saved_gid == ::cygheap->user.real_gid
594 && !::cygheap->user.groups.issetgroups ()
595 && !::cygheap->user.setuid_to_restricted))
597 rc = CreateProcessW (runpath, /* image name - with full path */
598 wone_line, /* what was passed to exec */
599 &sec_none_nih, /* process security attrs */
600 &sec_none_nih, /* thread security attrs */
601 TRUE, /* inherit handles from parent */
603 envblock, /* environment */
610 /* Give access to myself */
611 if (mode == _P_OVERLAY)
614 WCHAR wstname[1024] = { L'\0' };
615 HWINSTA hwst_orig = NULL, hwst = NULL;
616 HDESK hdsk_orig = NULL, hdsk = NULL;
617 PSECURITY_ATTRIBUTES sa;
620 hwst_orig = GetProcessWindowStation ();
621 hdsk_orig = GetThreadDesktop (GetCurrentThreadId ());
622 GetUserObjectInformationW (hwst_orig, UOI_NAME, wstname, 1024, &n);
623 /* Prior to Vista it was possible to start a service with the
624 "Interact with desktop" flag. This started the service in the
625 interactive window station of the console. A big security
626 risk, but we don't want to disable this behaviour for older
627 OSes because it's still heavily used by some users. They have
629 if (!::cygheap->user.setuid_to_restricted
630 && wcscasecmp (wstname, L"WinSta0") != 0)
634 sa = sec_user ((PSECURITY_ATTRIBUTES) alloca (1024),
635 ::cygheap->user.sid ());
636 /* We're creating a window station per user, not per logon session.
637 First of all we might not have a valid logon session for
638 the user (logon by create_token), and second, it doesn't
639 make sense in terms of security to create a new window
640 station for every logon of the same user. It just fills up
641 the system with window stations for no good reason. */
642 hwst = CreateWindowStationW (::cygheap->user.get_windows_id (sid), 0,
643 GENERIC_READ | GENERIC_WRITE, sa);
645 system_printf ("CreateWindowStation failed, %E");
646 else if (!SetProcessWindowStation (hwst))
647 system_printf ("SetProcessWindowStation failed, %E");
648 else if (!(hdsk = CreateDesktopW (L"Default", NULL, NULL, 0,
650 system_printf ("CreateDesktop failed, %E");
653 wcpcpy (wcpcpy (wstname, sid), L"\\Default");
654 si.lpDesktop = wstname;
655 debug_printf ("Desktop: %W", si.lpDesktop);
659 rc = CreateProcessAsUserW (::cygheap->user.primary_token (),
660 runpath, /* image name - with full path */
661 wone_line, /* what was passed to exec */
662 &sec_none_nih, /* process security attrs */
663 &sec_none_nih, /* thread security attrs */
664 TRUE, /* inherit handles from parent */
666 envblock, /* environment */
672 SetProcessWindowStation (hwst_orig);
673 CloseWindowStation (hwst);
677 SetThreadDesktop (hdsk_orig);
682 /* Restore impersonation. In case of _P_OVERLAY this isn't
683 allowed since it would overwrite child data. */
684 if (mode != _P_OVERLAY || !rc)
685 ::cygheap->user.reimpersonate ();
687 /* Set errno now so that debugging messages from it appear before our
688 final debugging message [this is a general rule for debugging
693 syscall_printf ("CreateProcess failed, %E");
694 /* If this was a failed exec, restore the saved sendsig. */
697 myself->sendsig = myself->exec_sendsig;
698 myself->exec_sendsig = NULL;
700 myself->process_state &= ~PID_NOTCYGWIN;
705 /* The CREATE_SUSPENDED case is handled below */
706 if (iscygwin () && !(c_flags & CREATE_SUSPENDED))
707 strace.write_childpid (pi.dwProcessId);
709 /* Fixup the parent data structures if needed and resume the child's
711 if (::cygheap->fdtab.need_fixup_before ())
712 ::cygheap->fdtab.fixup_before_exec (pi.dwProcessId);
714 if (mode != _P_OVERLAY)
715 cygpid = cygwin_pid (pi.dwProcessId);
717 cygpid = myself->pid;
719 /* We print the original program name here so the user can see that too. */
720 syscall_printf ("%d = child_info_spawn::worker(%s, %.9500s)",
721 rc ? cygpid : (unsigned int) -1, prog_arg, one_line.buf);
723 /* Name the handle similarly to proc_subproc. */
724 ProtectHandle1 (pi.hProcess, childhProc);
728 if (mode == _P_OVERLAY)
730 myself->dwProcessId = pi.dwProcessId;
732 myself.hProcess = hExeced = pi.hProcess;
733 real_path.get_wide_win32_path (myself->progname); // FIXME: race?
734 sigproc_printf ("new process name %W", myself->progname);
735 /* If wr_proc_pipe doesn't exist then this process was not started by a cygwin
736 process. So, we need to wait around until the process we've just "execed"
737 dies. Use our own wait facility to wait for our own pid to exit (there
738 is some minor special case code in proc_waiter and friends to accommodate
741 If wr_proc_pipe exists, then it should be duplicated to the child.
742 If the child has exited already, that's ok. The parent will pick up
743 on this fact when we exit. dup_proc_pipe will close our end of the pipe.
744 Note that wr_proc_pipe may also be == INVALID_HANDLE_VALUE. That will make
745 dup_proc_pipe essentially a no-op. */
746 if (!newargv.win16_exe && myself->wr_proc_pipe)
749 myself->sync_proc_pipe (); /* Make sure that we own wr_proc_pipe
750 just in case we've been previously
752 orig_wr_proc_pipe = myself->dup_proc_pipe (pi.hProcess);
760 myself->set_has_pgid_children ();
761 ProtectHandle (pi.hThread);
763 PID_IN_USE | (real_path.iscygexec () ? 0 : PID_NOTCYGWIN));
766 syscall_printf ("pinfo failed");
767 if (get_errno () != ENOMEM)
772 child->dwProcessId = pi.dwProcessId;
773 child.hProcess = pi.hProcess;
775 real_path.get_wide_win32_path (child->progname);
776 /* FIXME: This introduces an unreferenced, open handle into the child.
777 The purpose is to keep the pid shared memory open so that all of
778 the fields filled out by child.remember do not disappear and so there
779 is not a brief period during which the pid is not available.
780 However, we should try to find another way to do this eventually. */
781 DuplicateHandle (GetCurrentProcess (), child.shared_handle (),
782 pi.hProcess, NULL, 0, 0, DUPLICATE_SAME_ACCESS);
783 child->start_time = time (NULL); /* Register child's starting time. */
784 child->nice = myself->nice;
785 if (!child.remember (mode == _P_DETACH))
787 /* FIXME: Child in strange state now */
788 CloseHandle (pi.hProcess);
789 ForceCloseHandle (pi.hThread);
796 /* Start the child running */
797 if (c_flags & CREATE_SUSPENDED)
799 ResumeThread (pi.hThread);
801 strace.write_childpid (pi.dwProcessId);
803 ForceCloseHandle (pi.hThread);
805 sigproc_printf ("spawned windows pid %d", pi.dwProcessId);
807 if ((mode == _P_DETACH || mode == _P_NOWAIT) && !iscygwin ())
810 synced = sync (pi.dwProcessId, pi.hProcess, INFINITE);
815 myself.hProcess = pi.hProcess;
818 if (orig_wr_proc_pipe)
820 myself->wr_proc_pipe_owner = GetCurrentProcessId ();
821 myself->wr_proc_pipe = orig_wr_proc_pipe;
823 if (!proc_retry (pi.hProcess))
828 close_all_files (true);
832 close_all_files (true);
833 if (!myself->wr_proc_pipe
834 && WaitForSingleObject (pi.hProcess, 0) == WAIT_TIMEOUT)
836 extern bool is_toplevel_proc;
837 is_toplevel_proc = true;
838 myself.remember (false);
843 myself.exit (EXITCODE_NOSET);
847 if (waitpid (cygpid, &res, 0) != cygpid)
851 res = 0; /* Lost all memory of this child. */
866 pthread_cleanup_pop (1);
871 cwait (int *result, int pid, int)
873 return waitpid (pid, result, 0);
877 * Helper function for spawn runtime calls.
878 * Doesn't search the path.
882 spawnve (int mode, const char *path, const char *const *argv,
883 const char *const *envp)
885 static char *const empty_env[] = { NULL };
889 vfork_save *vf = vfork_storage.val ();
891 if (vf != NULL && (vf->pid < 0) && mode == _P_OVERLAY)
897 syscall_printf ("spawnve (%s, %s, %x)", path, argv[0], envp);
902 switch (_P_MODE (mode))
905 ch_spawn.worker (path, argv, envp, mode);
906 /* Errno should be set by worker. */
915 ret = ch_spawn.worker (path, argv, envp, mode);
921 debug_printf ("longjmping due to vfork");
922 vf->restore_pid (ret);
936 * spawn functions as implemented in the MS runtime library.
937 * Most of these based on (and copied from) newlib/libc/posix/execXX.c
941 spawnl (int mode, const char *path, const char *arg0, ...)
945 const char *argv[256];
947 va_start (args, arg0);
952 argv[i] = va_arg (args, const char *);
953 while (argv[i++] != NULL);
957 return spawnve (mode, path, (char * const *) argv, cur_environ ());
961 spawnle (int mode, const char *path, const char *arg0, ...)
965 const char * const *envp;
966 const char *argv[256];
968 va_start (args, arg0);
973 argv[i] = va_arg (args, const char *);
974 while (argv[i++] != NULL);
976 envp = va_arg (args, const char * const *);
979 return spawnve (mode, path, (char * const *) argv, (char * const *) envp);
983 spawnlp (int mode, const char *file, const char *arg0, ...)
987 const char *argv[256];
990 va_start (args, arg0);
995 argv[i] = va_arg (args, const char *);
996 while (argv[i++] != NULL);
1000 return spawnve (mode | _P_PATH_TYPE_EXEC, find_exec (file, buf),
1001 (char * const *) argv, cur_environ ());
1005 spawnlpe (int mode, const char *file, const char *arg0, ...)
1009 const char * const *envp;
1010 const char *argv[256];
1013 va_start (args, arg0);
1018 argv[i] = va_arg (args, const char *);
1019 while (argv[i++] != NULL);
1021 envp = va_arg (args, const char * const *);
1024 return spawnve (mode | _P_PATH_TYPE_EXEC, find_exec (file, buf),
1025 (char * const *) argv, envp);
1029 spawnv (int mode, const char *path, const char * const *argv)
1031 return spawnve (mode, path, argv, cur_environ ());
1035 spawnvp (int mode, const char *file, const char * const *argv)
1038 return spawnve (mode | _P_PATH_TYPE_EXEC, find_exec (file, buf), argv,
1043 spawnvpe (int mode, const char *file, const char * const *argv,
1044 const char * const *envp)
1047 return spawnve (mode | _P_PATH_TYPE_EXEC, find_exec (file, buf), argv, envp);
1051 av::fixup (const char *prog_arg, path_conv& real_path, const char *ext,
1055 bool exeext = ascii_strcasematch (ext, ".exe");
1056 if ((exeext && real_path.iscygexec ()) || ascii_strcasematch (ext, ".bat"))
1058 if (!*ext && ((p = ext - 4) > real_path.get_win32 ())
1059 && (ascii_strcasematch (p, ".bat") || ascii_strcasematch (p, ".cmd")
1060 || ascii_strcasematch (p, ".btm")))
1067 OBJECT_ATTRIBUTES attr;
1073 status = NtOpenFile (&h, SYNCHRONIZE | GENERIC_READ,
1074 real_path.get_object_attr (attr, sec_none_nih),
1075 &io, FILE_SHARE_VALID_FLAGS,
1076 FILE_SYNCHRONOUS_IO_NONALERT
1077 | FILE_OPEN_FOR_BACKUP_INTENT
1078 | FILE_NON_DIRECTORY_FILE);
1079 if (!NT_SUCCESS (status))
1081 /* File is not readable? Doesn't mean it's not executable.
1082 Test for executability and if so, just assume the file is
1083 a cygwin executable and go ahead. */
1084 if (status == STATUS_ACCESS_DENIED && real_path.has_acls ()
1085 && check_file_access (real_path, X_OK, true) == 0)
1087 real_path.set_cygexec (true);
1092 if (!GetFileSizeEx (h, &size))
1097 if (size.QuadPart > wincap.allocation_granularity ())
1098 size.LowPart = wincap.allocation_granularity ();
1100 HANDLE hm = CreateFileMapping (h, &sec_none_nih, PAGE_READONLY,
1105 /* ERROR_FILE_INVALID indicates very likely an empty file. */
1106 if (GetLastError () == ERROR_FILE_INVALID)
1108 debug_printf ("zero length file, treat as script.");
1113 /* Try to map the first 64K of the image. That's enough for the local
1114 tests, and it's enough for hook_or_detect_cygwin to compute the IAT
1116 buf = (char *) MapViewOfFile (hm, FILE_MAP_READ, 0, 0, size.LowPart);
1125 if (efault.faulted ())
1127 UnmapViewOfFile (buf);
1129 real_path.set_cygexec (false);
1132 if (buf[0] == 'M' && buf[1] == 'Z')
1135 unsigned off = (unsigned char) buf[0x18] | (((unsigned char) buf[0x19]) << 8);
1136 win16_exe = off < sizeof (IMAGE_DOS_HEADER);
1138 real_path.set_cygexec (!!hook_or_detect_cygwin (buf, NULL,
1141 real_path.set_cygexec (false);
1142 UnmapViewOfFile (buf);
1149 debug_printf ("%s is possibly a script", real_path.get_win32 ());
1152 if (*ptr++ == '#' && *ptr++ == '!')
1154 ptr += strspn (ptr, " \t");
1155 size_t len = strcspn (ptr, "\r\n");
1158 char *namebuf = (char *) alloca (len + 1);
1159 memcpy (namebuf, ptr, len);
1160 namebuf[len] = '\0';
1161 for (ptr = pgm = namebuf; *ptr; ptr++)
1162 if (!arg1 && (*ptr == ' ' || *ptr == '\t'))
1164 /* Null terminate the initial command and step over any
1165 additional white space. If we've hit the end of the
1166 line, exit the loop. Otherwise, we've found the first
1167 argument. Position the current pointer on the last known
1170 char *newptr = ptr + 1;
1171 newptr += strspn (newptr, " \t");
1179 UnmapViewOfFile (buf);
1185 /* Not called from exec[lv]p. Don't try to treat as script. */
1186 debug_printf ("%s is not a valid executable",
1187 real_path.get_win32 ());
1188 set_errno (ENOEXEC);
1191 if (ascii_strcasematch (ext, ".com"))
1193 pgm = (char *) "/bin/sh";
1197 /* Check if script is executable. Otherwise we start non-executable
1198 scripts successfully, which is incorrect behaviour. */
1199 if (real_path.has_acls ()
1200 && check_file_access (real_path, X_OK, true) < 0)
1201 return -1; /* errno is already set. */
1203 /* Replace argv[0] with the full path to the script if this is the
1204 first time through the loop. */
1205 replace0_maybe (prog_arg);
1208 * pgm interpreter name
1209 * arg1 optional string
1214 /* FIXME: This should not be using FE_NATIVE. It should be putting
1215 the posix path on the argv list. */
1216 find_exec (pgm, real_path, "PATH=", FE_NATIVE, &ext);
1217 unshift (real_path.get_win32 (), 1);