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;
696 strace.write_childpid (*this, pi.dwProcessId);
698 /* Fixup the parent data structures if needed and resume the child's
700 if (::cygheap->fdtab.need_fixup_before ())
701 ::cygheap->fdtab.fixup_before_exec (pi.dwProcessId);
703 if (mode != _P_OVERLAY)
704 cygpid = cygwin_pid (pi.dwProcessId);
706 cygpid = myself->pid;
708 /* We print the original program name here so the user can see that too. */
709 syscall_printf ("%d = child_info_spawn::worker (%s, %.9500s)",
710 rc ? cygpid : (unsigned int) -1, prog_arg, one_line.buf);
712 /* Name the handle similarly to proc_subproc. */
713 ProtectHandle1 (pi.hProcess, childhProc);
717 if (mode == _P_OVERLAY)
719 myself->dwProcessId = pi.dwProcessId;
721 myself.hProcess = hExeced = pi.hProcess;
722 real_path.get_wide_win32_path (myself->progname); // FIXME: race?
723 sigproc_printf ("new process name %W", myself->progname);
724 /* If wr_proc_pipe doesn't exist then this process was not started by a cygwin
725 process. So, we need to wait around until the process we've just "execed"
726 dies. Use our own wait facility to wait for our own pid to exit (there
727 is some minor special case code in proc_waiter and friends to accommodate
730 If wr_proc_pipe exists, then it should be duplicated to the child.
731 If the child has exited already, that's ok. The parent will pick up
732 on this fact when we exit. dup_proc_pipe will close our end of the pipe.
733 Note that wr_proc_pipe may also be == INVALID_HANDLE_VALUE. That will make
734 dup_proc_pipe essentially a no-op. */
735 if (!newargv.win16_exe && myself->wr_proc_pipe)
738 myself->sync_proc_pipe (); /* Make sure that we own wr_proc_pipe
739 just in case we've been previously
741 orig_wr_proc_pipe = myself->dup_proc_pipe (pi.hProcess);
749 myself->set_has_pgid_children ();
750 ProtectHandle (pi.hThread);
752 PID_IN_USE | (real_path.iscygexec () ? 0 : PID_NOTCYGWIN));
755 syscall_printf ("pinfo failed");
756 if (get_errno () != ENOMEM)
761 child->dwProcessId = pi.dwProcessId;
762 child.hProcess = pi.hProcess;
764 real_path.get_wide_win32_path (child->progname);
765 /* FIXME: This introduces an unreferenced, open handle into the child.
766 The purpose is to keep the pid shared memory open so that all of
767 the fields filled out by child.remember do not disappear and so there
768 is not a brief period during which the pid is not available.
769 However, we should try to find another way to do this eventually. */
770 DuplicateHandle (GetCurrentProcess (), child.shared_handle (),
771 pi.hProcess, NULL, 0, 0, DUPLICATE_SAME_ACCESS);
772 child->start_time = time (NULL); /* Register child's starting time. */
773 child->nice = myself->nice;
774 if (!child.remember (mode == _P_DETACH))
776 /* FIXME: Child in strange state now */
777 CloseHandle (pi.hProcess);
778 ForceCloseHandle (pi.hThread);
785 /* Start the child running */
786 if (c_flags & CREATE_SUSPENDED)
788 ResumeThread (pi.hThread);
789 strace.write_childpid (*this, pi.dwProcessId);
791 ForceCloseHandle (pi.hThread);
793 sigproc_printf ("spawned windows pid %d", pi.dwProcessId);
795 if ((mode == _P_DETACH || mode == _P_NOWAIT) && !iscygwin ())
798 synced = sync (pi.dwProcessId, pi.hProcess, INFINITE);
803 myself.hProcess = pi.hProcess;
806 if (orig_wr_proc_pipe)
808 myself->wr_proc_pipe_owner = GetCurrentProcessId ();
809 myself->wr_proc_pipe = orig_wr_proc_pipe;
811 if (!proc_retry (pi.hProcess))
816 close_all_files (true);
820 close_all_files (true);
821 if (!myself->wr_proc_pipe
822 && WaitForSingleObject (pi.hProcess, 0) == WAIT_TIMEOUT)
824 extern bool is_toplevel_proc;
825 is_toplevel_proc = true;
826 myself.remember (false);
831 myself.exit (EXITCODE_NOSET);
835 if (waitpid (cygpid, &res, 0) != cygpid)
839 res = 0; /* Lost all memory of this child. */
854 pthread_cleanup_pop (1);
859 cwait (int *result, int pid, int)
861 return waitpid (pid, result, 0);
865 * Helper function for spawn runtime calls.
866 * Doesn't search the path.
870 spawnve (int mode, const char *path, const char *const *argv,
871 const char *const *envp)
873 static char *const empty_env[] = { NULL };
877 vfork_save *vf = vfork_storage.val ();
879 if (vf != NULL && (vf->pid < 0) && mode == _P_OVERLAY)
885 syscall_printf ("spawnve (%s, %s, %x)", path, argv[0], envp);
890 switch (_P_MODE (mode))
893 ch_spawn.worker (path, argv, envp, mode);
894 /* Errno should be set by worker. */
903 ret = ch_spawn.worker (path, argv, envp, mode);
909 debug_printf ("longjmping due to vfork");
910 vf->restore_pid (ret);
924 * spawn functions as implemented in the MS runtime library.
925 * Most of these based on (and copied from) newlib/libc/posix/execXX.c
929 spawnl (int mode, const char *path, const char *arg0, ...)
933 const char *argv[256];
935 va_start (args, arg0);
940 argv[i] = va_arg (args, const char *);
941 while (argv[i++] != NULL);
945 return spawnve (mode, path, (char * const *) argv, cur_environ ());
949 spawnle (int mode, const char *path, const char *arg0, ...)
953 const char * const *envp;
954 const char *argv[256];
956 va_start (args, arg0);
961 argv[i] = va_arg (args, const char *);
962 while (argv[i++] != NULL);
964 envp = va_arg (args, const char * const *);
967 return spawnve (mode, path, (char * const *) argv, (char * const *) envp);
971 spawnlp (int mode, const char *file, const char *arg0, ...)
975 const char *argv[256];
978 va_start (args, arg0);
983 argv[i] = va_arg (args, const char *);
984 while (argv[i++] != NULL);
988 return spawnve (mode | _P_PATH_TYPE_EXEC, find_exec (file, buf),
989 (char * const *) argv, cur_environ ());
993 spawnlpe (int mode, const char *file, const char *arg0, ...)
997 const char * const *envp;
998 const char *argv[256];
1001 va_start (args, arg0);
1006 argv[i] = va_arg (args, const char *);
1007 while (argv[i++] != NULL);
1009 envp = va_arg (args, const char * const *);
1012 return spawnve (mode | _P_PATH_TYPE_EXEC, find_exec (file, buf),
1013 (char * const *) argv, envp);
1017 spawnv (int mode, const char *path, const char * const *argv)
1019 return spawnve (mode, path, argv, cur_environ ());
1023 spawnvp (int mode, const char *file, const char * const *argv)
1026 return spawnve (mode | _P_PATH_TYPE_EXEC, find_exec (file, buf), argv,
1031 spawnvpe (int mode, const char *file, const char * const *argv,
1032 const char * const *envp)
1035 return spawnve (mode | _P_PATH_TYPE_EXEC, find_exec (file, buf), argv, envp);
1039 av::fixup (const char *prog_arg, path_conv& real_path, const char *ext,
1043 bool exeext = ascii_strcasematch (ext, ".exe");
1044 if ((exeext && real_path.iscygexec ()) || ascii_strcasematch (ext, ".bat"))
1046 if (!*ext && ((p = ext - 4) > real_path.get_win32 ())
1047 && (ascii_strcasematch (p, ".bat") || ascii_strcasematch (p, ".cmd")
1048 || ascii_strcasematch (p, ".btm")))
1055 OBJECT_ATTRIBUTES attr;
1061 status = NtOpenFile (&h, SYNCHRONIZE | GENERIC_READ,
1062 real_path.get_object_attr (attr, sec_none_nih),
1063 &io, FILE_SHARE_VALID_FLAGS,
1064 FILE_SYNCHRONOUS_IO_NONALERT
1065 | FILE_OPEN_FOR_BACKUP_INTENT
1066 | FILE_NON_DIRECTORY_FILE);
1067 if (!NT_SUCCESS (status))
1069 /* File is not readable? Doesn't mean it's not executable.
1070 Test for executability and if so, just assume the file is
1071 a cygwin executable and go ahead. */
1072 if (status == STATUS_ACCESS_DENIED && real_path.has_acls ()
1073 && check_file_access (real_path, X_OK, true) == 0)
1075 real_path.set_cygexec (true);
1080 if (!GetFileSizeEx (h, &size))
1085 if (size.QuadPart > wincap.allocation_granularity ())
1086 size.LowPart = wincap.allocation_granularity ();
1088 HANDLE hm = CreateFileMapping (h, &sec_none_nih, PAGE_READONLY,
1093 /* ERROR_FILE_INVALID indicates very likely an empty file. */
1094 if (GetLastError () == ERROR_FILE_INVALID)
1096 debug_printf ("zero length file, treat as script.");
1101 /* Try to map the first 64K of the image. That's enough for the local
1102 tests, and it's enough for hook_or_detect_cygwin to compute the IAT
1104 buf = (char *) MapViewOfFile (hm, FILE_MAP_READ, 0, 0, size.LowPart);
1113 if (efault.faulted ())
1115 UnmapViewOfFile (buf);
1117 real_path.set_cygexec (false);
1120 if (buf[0] == 'M' && buf[1] == 'Z')
1123 unsigned off = (unsigned char) buf[0x18] | (((unsigned char) buf[0x19]) << 8);
1124 win16_exe = off < sizeof (IMAGE_DOS_HEADER);
1126 real_path.set_cygexec (!!hook_or_detect_cygwin (buf, NULL,
1129 real_path.set_cygexec (false);
1130 UnmapViewOfFile (buf);
1137 debug_printf ("%s is possibly a script", real_path.get_win32 ());
1140 if (*ptr++ == '#' && *ptr++ == '!')
1142 ptr += strspn (ptr, " \t");
1143 size_t len = strcspn (ptr, "\r\n");
1146 char *namebuf = (char *) alloca (len + 1);
1147 memcpy (namebuf, ptr, len);
1148 namebuf[len] = '\0';
1149 for (ptr = pgm = namebuf; *ptr; ptr++)
1150 if (!arg1 && (*ptr == ' ' || *ptr == '\t'))
1152 /* Null terminate the initial command and step over any
1153 additional white space. If we've hit the end of the
1154 line, exit the loop. Otherwise, we've found the first
1155 argument. Position the current pointer on the last known
1158 char *newptr = ptr + 1;
1159 newptr += strspn (newptr, " \t");
1167 UnmapViewOfFile (buf);
1173 /* Not called from exec[lv]p. Don't try to treat as script. */
1174 debug_printf ("%s is not a valid executable",
1175 real_path.get_win32 ());
1176 set_errno (ENOEXEC);
1179 if (ascii_strcasematch (ext, ".com"))
1181 pgm = (char *) "/bin/sh";
1185 /* Check if script is executable. Otherwise we start non-executable
1186 scripts successfully, which is incorrect behaviour. */
1187 if (real_path.has_acls ()
1188 && check_file_access (real_path, X_OK, true) < 0)
1189 return -1; /* errno is already set. */
1191 /* Replace argv[0] with the full path to the script if this is the
1192 first time through the loop. */
1193 replace0_maybe (prog_arg);
1196 * pgm interpreter name
1197 * arg1 optional string
1202 /* FIXME: This should not be using FE_NATIVE. It should be putting
1203 the posix path on the argv list. */
1204 find_exec (pgm, real_path, "PATH=", FE_NATIVE, &ext);
1205 unshift (real_path.get_win32 (), 1);