OSDN Git Service

* pipe.cc (fhandler_pipe::create): Avoid derefencing a NULL pointer.
[pf3gnuchains/pf3gnuchains4x.git] / winsup / cygwin / spawn.cc
1 /* spawn.cc
2
3    Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
4    2005, 2006, 2007, 2008, 2009, 2010, 2011 Red Hat, Inc.
5
6 This file is part of Cygwin.
7
8 This software is a copyrighted work licensed under the terms of the
9 Cygwin license.  Please consult the file "CYGWIN_LICENSE" for
10 details. */
11
12 #include "winsup.h"
13 #include <stdlib.h>
14 #include <unistd.h>
15 #include <process.h>
16 #include <sys/wait.h>
17 #include <wingdi.h>
18 #include <winuser.h>
19 #include <wchar.h>
20 #include <ctype.h>
21 #include "cygerrno.h"
22 #include <sys/cygwin.h>
23 #include "security.h"
24 #include "path.h"
25 #include "fhandler.h"
26 #include "dtable.h"
27 #include "sigproc.h"
28 #include "cygheap.h"
29 #include "child_info.h"
30 #include "pinfo.h"
31 #include "environ.h"
32 #include "cygtls.h"
33 #include "tls_pbuf.h"
34 #include "winf.h"
35 #include "ntdll.h"
36
37 static suffix_info NO_COPY exe_suffixes[] =
38 {
39   suffix_info ("", 1),
40   suffix_info (".exe", 1),
41   suffix_info (".com"),
42   suffix_info (NULL)
43 };
44
45 #if 0
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[] =
51 {
52   suffix_info (".dll"),
53   suffix_info ("", 1),
54   suffix_info (".exe", 1),
55   suffix_info (NULL)
56 };
57 #endif
58
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.
62
63    Returns (possibly NULL) suffix */
64
65 static const char *
66 perhaps_suffix (const char *prog, path_conv& buf, int& err, unsigned opt)
67 {
68   const char *ext;
69
70   err = 0;
71   debug_printf ("prog '%s'", prog);
72   buf.check (prog, PC_SYM_FOLLOW | PC_NULLEMPTY,
73              (opt & FE_DLL) ? stat_suffixes : exe_suffixes);
74
75   if (buf.isdir ())
76     {
77       err = EACCES;
78       ext = NULL;
79     }
80   else if (!buf.exists ())
81     {
82       err = ENOENT;
83       ext = NULL;
84     }
85   else if (buf.known_suffix)
86     ext = buf.get_win32 () + (buf.known_suffix - buf.get_win32 ());
87   else
88     ext = strchr (buf.get_win32 (), '\0');
89
90   debug_printf ("buf %s, suffix found '%s'", (char *) buf.get_win32 (), ext);
91   return ext;
92 }
93
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.
97
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.  */
101
102 const char * __stdcall
103 find_exec (const char *name, path_conv& buf, const char *mywinenv,
104            unsigned opt, const char **known_suffix)
105 {
106   const char *suffix = "";
107   debug_printf ("find_exec (%s)", name);
108   const char *retval;
109   tmp_pathbuf tp;
110   char *tmp = tp.c_get ();
111   const char *posix = (opt & FE_NATIVE) ? NULL : name;
112   bool has_slash = !!strpbrk (name, "/\\");
113   int err;
114
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
117      do this. */
118   if ((has_slash || opt & FE_CWD)
119       && (suffix = perhaps_suffix (name, buf, err, opt)) != NULL)
120     {
121       if (posix && !has_slash)
122         {
123           tmp[0] = '.';
124           tmp[1] = '/';
125           strcpy (tmp + 2, name);
126           posix = tmp;
127         }
128       retval = buf.get_win32 ();
129       goto out;
130     }
131
132   win_env *winpath;
133   const char *path;
134   const char *posix_path;
135
136   posix = (opt & FE_NATIVE) ? NULL : tmp;
137
138   if (strchr (mywinenv, '/'))
139     {
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))
144         goto errout;
145       path = s;
146       posix_path = mywinenv - 1;
147     }
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. */
153     goto errout;
154   else
155     posix_path = winpath->get_posix () - 1;
156
157   debug_printf ("%s%s", mywinenv, path);
158   /* Iterate over the specified path, looking for the file with and without
159      executable extensions. */
160   do
161     {
162       posix_path++;
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')))
167         continue;
168
169       *eotmp++ = '\\';
170       strcpy (eotmp, name);
171
172       debug_printf ("trying %s", tmp);
173
174       int err1;
175
176       if ((suffix = perhaps_suffix (tmp, buf, err1, opt)) != NULL)
177         {
178           if (buf.has_acls () && check_file_access (buf, X_OK, true))
179             continue;
180
181           if (posix == tmp)
182             {
183               eotmp = strccpy (tmp, &posix_path, ':');
184               if (eotmp == tmp)
185                 *eotmp++ = '.';
186               *eotmp++ = '/';
187               strcpy (eotmp, name);
188             }
189           retval = buf.get_win32 ();
190           goto out;
191         }
192     }
193   while (*path && *++path && (posix_path = strchr (posix_path, ':')));
194
195  errout:
196   posix = NULL;
197   /* Couldn't find anything in the given path.
198      Take the appropriate action based on null_if_not_found. */
199   if (opt & FE_NNF)
200     retval = NULL;
201   else if (!(opt & FE_NATIVE))
202     retval = name;
203   else
204     {
205       buf.check (name);
206       retval = buf.get_win32 ();
207     }
208
209  out:
210   if (posix)
211     retval = buf.set_path (posix);
212   debug_printf ("%s = find_exec (%s)", (char *) buf.get_win32 (), name);
213   if (known_suffix)
214     *known_suffix = suffix ?: strchr (buf.get_win32 (), '\0');
215   if (!retval && err)
216     set_errno (err);
217   return retval;
218 }
219
220 /* Utility for child_info_spawn::worker.  */
221
222 static HANDLE
223 handle (int fd, bool writing)
224 {
225   HANDLE h;
226   cygheap_fdget cfd (fd);
227
228   if (cfd < 0)
229     h = INVALID_HANDLE_VALUE;
230   else if (cfd->close_on_exec ())
231     h = INVALID_HANDLE_VALUE;
232   else if (!writing)
233     h = cfd->get_handle ();
234   else
235     h = cfd->get_output_handle ();
236
237   return h;
238 }
239
240 int
241 iscmd (const char *argv0, const char *what)
242 {
243   int n;
244   n = strlen (argv0) - strlen (what);
245   if (n >= 2 && argv0[1] != ':')
246     return 0;
247   return n >= 0 && strcasematch (argv0 + n, what) &&
248          (n == 0 || isdirsep (argv0[n - 1]));
249 }
250
251 struct pthread_cleanup
252 {
253   _sig_func_ptr oldint;
254   _sig_func_ptr oldquit;
255   sigset_t oldmask;
256   pthread_cleanup (): oldint (NULL), oldquit (NULL), oldmask ((sigset_t) -1) {}
257 };
258
259 static void
260 do_cleanup (void *args)
261 {
262 # define cleanup ((pthread_cleanup *) args)
263   if (cleanup->oldmask != (sigset_t) -1)
264     {
265       signal (SIGINT, cleanup->oldint);
266       signal (SIGQUIT, cleanup->oldquit);
267       sigprocmask (SIG_SETMASK, &(cleanup->oldmask), NULL);
268     }
269 # undef cleanup
270 }
271
272 NO_COPY child_info_spawn ch_spawn;
273
274 int
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)
278 {
279   bool rc;
280   pid_t cygpid;
281   int res = -1;
282
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);
287
288   if (prog_arg == NULL)
289     {
290       syscall_printf ("prog_arg is NULL");
291       set_errno (EFAULT);       /* As on Linux. */
292       return -1;
293     }
294   if (!prog_arg[0])
295     {
296       syscall_printf ("prog_arg is empty");
297       set_errno (ENOENT);       /* Per POSIX */
298       return -1;
299     }
300
301   syscall_printf ("mode = %d, prog_arg = %.9500s", mode, prog_arg);
302
303   /* FIXME: This is no error condition on Linux. */
304   if (argv == NULL)
305     {
306       syscall_printf ("argv is NULL");
307       set_errno (EINVAL);
308       return -1;
309     }
310
311   /* FIXME: There is a small race here and FIXME: not thread safe! */
312
313   pthread_cleanup cleanup;
314   if (mode == _P_SYSTEM)
315     {
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);
322     }
323   pthread_cleanup_push (do_cleanup, (void *) &cleanup);
324   av newargv;
325   linebuf one_line;
326   PWCHAR envblock = NULL;
327   path_conv real_path;
328   bool reset_sendsig = false;
329
330   tmp_pathbuf tp;
331   PWCHAR runpath = tp.w_get ();
332   int c_flags;
333   bool wascygexec;
334
335   bool null_app_name = false;
336   STARTUPINFOW si = {};
337   int looped = 0;
338   HANDLE orig_wr_proc_pipe = NULL;
339
340   myfault efault;
341   if (efault.faulted ())
342     {
343       if (get_errno () == ENOMEM)
344         set_errno (E2BIG);
345       else
346         set_errno (EFAULT);
347       res = -1;
348       goto out;
349     }
350
351   child_info_types chtype;
352   if (mode != _P_OVERLAY)
353     chtype = _CH_SPAWN;
354   else
355     chtype = _CH_EXEC;
356
357   moreinfo = cygheap_exec_info::alloc ();
358
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.  */
361
362   int ac;
363   for (ac = 0; argv[ac]; ac++)
364     /* nothing */;
365
366   newargv.set (ac, argv);
367
368   int err;
369   const char *ext;
370   if ((ext = perhaps_suffix (prog_arg, real_path, err, FE_NADA)) == NULL)
371     {
372       set_errno (err);
373       res = -1;
374       goto out;
375     }
376
377
378   wascygexec = real_path.iscygexec ();
379   res = newargv.fixup (prog_arg, real_path, ext, p_type_exec);
380
381   if (res)
382     goto out;
383
384   if (!real_path.iscygexec () && ::cygheap->cwd.get_error ())
385     {
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 ());
390       res = -1;
391       goto out;
392     }
393
394   if (ac == 3 && argv[1][0] == '/' && argv[1][1] == 'c' &&
395       (iscmd (argv[0], "command.com") || iscmd (argv[0], "cmd.exe")))
396     {
397       real_path.check (prog_arg);
398       one_line.add ("\"");
399       if (!real_path.error)
400         one_line.add (real_path.get_win32 ());
401       else
402         one_line.add (argv[0]);
403       one_line.add ("\"");
404       one_line.add (" ");
405       one_line.add (argv[1]);
406       one_line.add (" ");
407       one_line.add (argv[2]);
408       real_path.set_path (argv[0]);
409       null_app_name = true;
410     }
411   else
412     {
413       if (wascygexec)
414         newargv.dup_all ();
415       else if (!one_line.fromargv (newargv, real_path.get_win32 (),
416                                    real_path.iscygexec ()))
417         {
418           res = -1;
419           goto out;
420         }
421
422
423       newargv.all_calloced ();
424       moreinfo->argc = newargv.argc;
425       moreinfo->argv = newargv;
426
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;
432       else
433         VerifyHandle (moreinfo->myself_pinfo);
434     }
435   WCHAR wone_line[one_line.ix + 1];
436   if (one_line.ix)
437     sys_mbstowcs (wone_line, one_line.ix + 1, one_line.buf);
438   else
439     wone_line[0] = L'\0';
440
441   PROCESS_INFORMATION pi;
442   pi.hProcess = pi.hThread = NULL;
443   pi.dwProcessId = pi.dwThreadId = 0;
444
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);
450
451   si.cb = sizeof (si);
452
453   c_flags = GetPriorityClass (GetCurrentProcess ());
454   sigproc_printf ("priority class %d", c_flags);
455   c_flags |= CREATE_SEPARATE_WOW_VDM | CREATE_UNICODE_ENVIRONMENT;
456
457   if (mode == _P_DETACH)
458     c_flags |= DETACHED_PROCESS;
459   else
460     fhandler_console::need_invisible ();
461
462   if (mode != _P_OVERLAY)
463     myself->exec_sendsig = NULL;
464   else
465     {
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)
470         {
471           myself->exec_sendsig = myself->sendsig;
472           myself->exec_dwProcessId = myself->dwProcessId;
473           myself->sendsig = NULL;
474           reset_sendsig = true;
475         }
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);
485       else
486         system_printf ("duplicate to pid_handle failed, %E");
487     }
488
489   if (null_app_name)
490     runpath = NULL;
491   else
492     {
493       USHORT len = real_path.get_nt_native_path ()->Length / sizeof (WCHAR);
494       if (RtlEqualUnicodePathPrefix (real_path.get_nt_native_path (),
495                                      &ro_u_natp, FALSE))
496         {
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)
502             {
503               if (runpath[5] == ':')
504                 runpath += 4;
505               else if (len < MAX_PATH + 6)
506                 *(runpath += 6) = L'\\';
507             }
508         }
509       else if (len < NT_MAX_PATH - ro_u_globalroot.Length / sizeof (WCHAR))
510         {
511           UNICODE_STRING rpath;
512
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 ());
518         }
519       else
520         {
521           set_errno (ENAMETOOLONG);
522           res = -1;
523           goto out;
524         }
525     }
526   syscall_printf ("null_app_name %d (%W, %.9500W)", null_app_name,
527                   runpath, wone_line);
528
529   cygbench ("spawn-worker");
530
531   if (!real_path.iscygexec())
532     ::cygheap->fdtab.set_file_pointers_for_exec ();
533
534   moreinfo->envp = build_env (envp, envblock, moreinfo->envc,
535                               real_path.iscygexec ());
536   if (!moreinfo->envp || !envblock)
537     {
538       set_errno (E2BIG);
539       res = -1;
540       goto out;
541     }
542   set (chtype, real_path.iscygexec ());
543   __stdin = in__stdin;
544   __stdout = in__stdout;
545   record_children ();
546
547   si.lpReserved2 = (LPBYTE) this;
548   si.cbReserved2 = sizeof (*this);
549
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;
569   refresh_cygheap ();
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. */
575 loop:
576   ::cygheap->user.deimpersonate ();
577
578   if (!real_path.iscygexec () && mode == _P_OVERLAY)
579     myself->process_state |= PID_NOTCYGWIN;
580
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))
586     {
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 */
592                            c_flags,
593                            envblock,      /* environment */
594                            NULL,
595                            &si,
596                            &pi);
597     }
598   else
599     {
600       /* Give access to myself */
601       if (mode == _P_OVERLAY)
602         myself.set_acl();
603
604       WCHAR wstname[1024] = { L'\0' };
605       HWINSTA hwst_orig = NULL, hwst = NULL;
606       HDESK hdsk_orig = NULL, hdsk = NULL;
607       PSECURITY_ATTRIBUTES sa;
608       DWORD n;
609
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
618          been warned. */
619       if (!::cygheap->user.setuid_to_restricted
620           && wcscasecmp (wstname, L"WinSta0") != 0)
621         {
622           WCHAR sid[128];
623
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);
634           if (!hwst)
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,
639                                             GENERIC_ALL, sa)))
640             system_printf ("CreateDesktop failed, %E");
641           else
642             {
643               wcpcpy (wcpcpy (wstname, sid), L"\\Default");
644               si.lpDesktop = wstname;
645               debug_printf ("Desktop: %W", si.lpDesktop);
646             }
647         }
648
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 */
655                            c_flags,
656                            envblock,      /* environment */
657                            NULL,
658                            &si,
659                            &pi);
660       if (hwst)
661         {
662           SetProcessWindowStation (hwst_orig);
663           CloseWindowStation (hwst);
664         }
665       if (hdsk)
666         {
667           SetThreadDesktop (hdsk_orig);
668           CloseDesktop (hdsk);
669         }
670     }
671
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 ();
676
677   /* Set errno now so that debugging messages from it appear before our
678      final debugging message [this is a general rule for debugging
679      messages].  */
680   if (!rc)
681     {
682       __seterrno ();
683       syscall_printf ("CreateProcess failed, %E");
684       /* If this was a failed exec, restore the saved sendsig. */
685       if (reset_sendsig)
686         {
687           myself->sendsig = myself->exec_sendsig;
688           myself->exec_sendsig = NULL;
689         }
690       myself->process_state &= ~PID_NOTCYGWIN;
691       res = -1;
692       goto out;
693     }
694
695   if (iscygwin ())
696     strace.write_childpid (*this, pi.dwProcessId);
697
698   /* Fixup the parent data structures if needed and resume the child's
699      main thread. */
700   if (::cygheap->fdtab.need_fixup_before ())
701     ::cygheap->fdtab.fixup_before_exec (pi.dwProcessId);
702
703   if (mode != _P_OVERLAY)
704     cygpid = cygwin_pid (pi.dwProcessId);
705   else
706     cygpid = myself->pid;
707
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);
711
712   /* Name the handle similarly to proc_subproc. */
713   ProtectHandle1 (pi.hProcess, childhProc);
714
715   bool synced;
716   pid_t pid;
717   if (mode == _P_OVERLAY)
718     {
719       myself->dwProcessId = pi.dwProcessId;
720       strace.execing = 1;
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
728          this).
729
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)
736         {
737           if (!looped)
738             myself->sync_proc_pipe ();  /* Make sure that we own wr_proc_pipe
739                                            just in case we've been previously
740                                            execed. */
741           orig_wr_proc_pipe = myself->dup_proc_pipe (pi.hProcess);
742         }
743       pid = myself->pid;
744       if (!iscygwin ())
745         close_all_files ();
746     }
747   else
748     {
749       myself->set_has_pgid_children ();
750       ProtectHandle (pi.hThread);
751       pinfo child (cygpid,
752                    PID_IN_USE | (real_path.iscygexec () ? 0 : PID_NOTCYGWIN));
753       if (!child)
754         {
755           syscall_printf ("pinfo failed");
756           if (get_errno () != ENOMEM)
757             set_errno (EAGAIN);
758           res = -1;
759           goto out;
760         }
761       child->dwProcessId = pi.dwProcessId;
762       child.hProcess = pi.hProcess;
763
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))
775         {
776           /* FIXME: Child in strange state now */
777           CloseHandle (pi.hProcess);
778           ForceCloseHandle (pi.hThread);
779           res = -1;
780           goto out;
781         }
782       pid = child->pid;
783     }
784
785   /* Start the child running */
786   if (c_flags & CREATE_SUSPENDED)
787     {
788       ResumeThread (pi.hThread);
789       strace.write_childpid (*this, pi.dwProcessId);
790     }
791   ForceCloseHandle (pi.hThread);
792
793   sigproc_printf ("spawned windows pid %d", pi.dwProcessId);
794
795   if ((mode == _P_DETACH || mode == _P_NOWAIT) && !iscygwin ())
796     synced = false;
797   else
798     synced = sync (pi.dwProcessId, pi.hProcess, INFINITE);
799
800   switch (mode)
801     {
802     case _P_OVERLAY:
803       myself.hProcess = pi.hProcess;
804       if (!synced)
805         {
806           if (orig_wr_proc_pipe)
807             {
808               myself->wr_proc_pipe_owner = GetCurrentProcessId ();
809               myself->wr_proc_pipe = orig_wr_proc_pipe;
810             }
811           if (!proc_retry (pi.hProcess))
812             {
813               looped++;
814               goto loop;
815             }
816           close_all_files (true);
817         }
818       else
819         {
820           close_all_files (true);
821           if (!myself->wr_proc_pipe
822               && WaitForSingleObject (pi.hProcess, 0) == WAIT_TIMEOUT)
823             {
824               extern bool is_toplevel_proc;
825               is_toplevel_proc = true;
826               myself.remember (false);
827               wait_for_myself ();
828             }
829         }
830       this->cleanup ();
831       myself.exit (EXITCODE_NOSET);
832       break;
833     case _P_WAIT:
834     case _P_SYSTEM:
835       if (waitpid (cygpid, &res, 0) != cygpid)
836         res = -1;
837       break;
838     case _P_DETACH:
839       res = 0;  /* Lost all memory of this child. */
840       break;
841     case _P_NOWAIT:
842     case _P_NOWAITO:
843     case _P_VFORK:
844       res = cygpid;
845       break;
846     default:
847       break;
848     }
849
850 out:
851   this->cleanup ();
852   if (envblock)
853     free (envblock);
854   pthread_cleanup_pop (1);
855   return (int) res;
856 }
857
858 extern "C" int
859 cwait (int *result, int pid, int)
860 {
861   return waitpid (pid, result, 0);
862 }
863
864 /*
865 * Helper function for spawn runtime calls.
866 * Doesn't search the path.
867 */
868
869 extern "C" int
870 spawnve (int mode, const char *path, const char *const *argv,
871        const char *const *envp)
872 {
873   static char *const empty_env[] = { NULL };
874
875   int ret;
876 #ifdef NEWVFORK
877   vfork_save *vf = vfork_storage.val ();
878
879   if (vf != NULL && (vf->pid < 0) && mode == _P_OVERLAY)
880     mode = _P_NOWAIT;
881   else
882     vf = NULL;
883 #endif
884
885   syscall_printf ("spawnve (%s, %s, %x)", path, argv[0], envp);
886
887   if (!envp)
888     envp = empty_env;
889
890   switch (_P_MODE (mode))
891     {
892     case _P_OVERLAY:
893       ch_spawn.worker (path, argv, envp, mode);
894       /* Errno should be set by worker.  */
895       ret = -1;
896       break;
897     case _P_VFORK:
898     case _P_NOWAIT:
899     case _P_NOWAITO:
900     case _P_WAIT:
901     case _P_DETACH:
902     case _P_SYSTEM:
903       ret = ch_spawn.worker (path, argv, envp, mode);
904 #ifdef NEWVFORK
905       if (vf)
906         {
907           if (ret > 0)
908             {
909               debug_printf ("longjmping due to vfork");
910               vf->restore_pid (ret);
911             }
912         }
913 #endif
914       break;
915     default:
916       set_errno (EINVAL);
917       ret = -1;
918       break;
919     }
920   return ret;
921 }
922
923 /*
924 * spawn functions as implemented in the MS runtime library.
925 * Most of these based on (and copied from) newlib/libc/posix/execXX.c
926 */
927
928 extern "C" int
929 spawnl (int mode, const char *path, const char *arg0, ...)
930 {
931   int i;
932   va_list args;
933   const char *argv[256];
934
935   va_start (args, arg0);
936   argv[0] = arg0;
937   i = 1;
938
939   do
940       argv[i] = va_arg (args, const char *);
941   while (argv[i++] != NULL);
942
943   va_end (args);
944
945   return spawnve (mode, path, (char * const  *) argv, cur_environ ());
946 }
947
948 extern "C" int
949 spawnle (int mode, const char *path, const char *arg0, ...)
950 {
951   int i;
952   va_list args;
953   const char * const *envp;
954   const char *argv[256];
955
956   va_start (args, arg0);
957   argv[0] = arg0;
958   i = 1;
959
960   do
961     argv[i] = va_arg (args, const char *);
962   while (argv[i++] != NULL);
963
964   envp = va_arg (args, const char * const *);
965   va_end (args);
966
967   return spawnve (mode, path, (char * const *) argv, (char * const *) envp);
968 }
969
970 extern "C" int
971 spawnlp (int mode, const char *file, const char *arg0, ...)
972 {
973   int i;
974   va_list args;
975   const char *argv[256];
976   path_conv buf;
977
978   va_start (args, arg0);
979   argv[0] = arg0;
980   i = 1;
981
982   do
983       argv[i] = va_arg (args, const char *);
984   while (argv[i++] != NULL);
985
986   va_end (args);
987
988   return spawnve (mode | _P_PATH_TYPE_EXEC, find_exec (file, buf),
989                   (char * const *) argv, cur_environ ());
990 }
991
992 extern "C" int
993 spawnlpe (int mode, const char *file, const char *arg0, ...)
994 {
995   int i;
996   va_list args;
997   const char * const *envp;
998   const char *argv[256];
999   path_conv buf;
1000
1001   va_start (args, arg0);
1002   argv[0] = arg0;
1003   i = 1;
1004
1005   do
1006     argv[i] = va_arg (args, const char *);
1007   while (argv[i++] != NULL);
1008
1009   envp = va_arg (args, const char * const *);
1010   va_end (args);
1011
1012   return spawnve (mode | _P_PATH_TYPE_EXEC, find_exec (file, buf),
1013                   (char * const *) argv, envp);
1014 }
1015
1016 extern "C" int
1017 spawnv (int mode, const char *path, const char * const *argv)
1018 {
1019   return spawnve (mode, path, argv, cur_environ ());
1020 }
1021
1022 extern "C" int
1023 spawnvp (int mode, const char *file, const char * const *argv)
1024 {
1025   path_conv buf;
1026   return spawnve (mode | _P_PATH_TYPE_EXEC, find_exec (file, buf), argv,
1027                   cur_environ ());
1028 }
1029
1030 extern "C" int
1031 spawnvpe (int mode, const char *file, const char * const *argv,
1032           const char * const *envp)
1033 {
1034   path_conv buf;
1035   return spawnve (mode | _P_PATH_TYPE_EXEC, find_exec (file, buf), argv, envp);
1036 }
1037
1038 int
1039 av::fixup (const char *prog_arg, path_conv& real_path, const char *ext,
1040            bool p_type_exec)
1041 {
1042   const char *p;
1043   bool exeext = ascii_strcasematch (ext, ".exe");
1044   if ((exeext && real_path.iscygexec ()) || ascii_strcasematch (ext, ".bat"))
1045     return 0;
1046   if (!*ext && ((p = ext - 4) > real_path.get_win32 ())
1047       && (ascii_strcasematch (p, ".bat") || ascii_strcasematch (p, ".cmd")
1048           || ascii_strcasematch (p, ".btm")))
1049     return 0;
1050   while (1)
1051     {
1052       char *pgm = NULL;
1053       char *arg1 = NULL;
1054       char *ptr, *buf;
1055       OBJECT_ATTRIBUTES attr;
1056       IO_STATUS_BLOCK io;
1057       HANDLE h;
1058       NTSTATUS status;
1059       LARGE_INTEGER size;
1060
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))
1068         {
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)
1074             {
1075               real_path.set_cygexec (true);
1076               break;
1077             }
1078           goto err;
1079         }
1080       if (!GetFileSizeEx (h, &size))
1081         {
1082           NtClose (h);
1083           goto err;
1084         }
1085       if (size.QuadPart > wincap.allocation_granularity ())
1086         size.LowPart = wincap.allocation_granularity ();
1087
1088       HANDLE hm = CreateFileMapping (h, &sec_none_nih, PAGE_READONLY,
1089                                      0, 0, NULL);
1090       NtClose (h);
1091       if (!hm)
1092         {
1093           /* ERROR_FILE_INVALID indicates very likely an empty file. */
1094           if (GetLastError () == ERROR_FILE_INVALID)
1095             {
1096               debug_printf ("zero length file, treat as script.");
1097               goto just_shell;
1098             }
1099           goto err;
1100         }
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
1103          address. */
1104       buf = (char *) MapViewOfFile (hm, FILE_MAP_READ, 0, 0, size.LowPart);
1105       if (!buf)
1106         {
1107           CloseHandle (hm);
1108           goto err;
1109         }
1110
1111       {
1112         myfault efault;
1113         if (efault.faulted ())
1114           {
1115             UnmapViewOfFile (buf);
1116             CloseHandle (hm);
1117             real_path.set_cygexec (false);
1118             break;
1119           }
1120         if (buf[0] == 'M' && buf[1] == 'Z')
1121           {
1122             WORD subsys;
1123             unsigned off = (unsigned char) buf[0x18] | (((unsigned char) buf[0x19]) << 8);
1124             win16_exe = off < sizeof (IMAGE_DOS_HEADER);
1125             if (!win16_exe)
1126               real_path.set_cygexec (!!hook_or_detect_cygwin (buf, NULL,
1127                                                               subsys, hm));
1128             else
1129               real_path.set_cygexec (false);
1130             UnmapViewOfFile (buf);
1131             CloseHandle (hm);
1132             break;
1133           }
1134       }
1135       CloseHandle (hm);
1136
1137       debug_printf ("%s is possibly a script", real_path.get_win32 ());
1138
1139       ptr = buf;
1140       if (*ptr++ == '#' && *ptr++ == '!')
1141         {
1142           ptr += strspn (ptr, " \t");
1143           size_t len = strcspn (ptr, "\r\n");
1144           if (len)
1145             {
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'))
1151                   {
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
1156                        white space. */
1157                     *ptr = '\0';
1158                     char *newptr = ptr + 1;
1159                     newptr += strspn (newptr, " \t");
1160                     if (!*newptr)
1161                       break;
1162                     arg1 = newptr;
1163                     ptr = newptr - 1;
1164                   }
1165             }
1166         }
1167       UnmapViewOfFile (buf);
1168 just_shell:
1169       if (!pgm)
1170         {
1171           if (!p_type_exec)
1172             {
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);
1177               return -1;
1178             }
1179           if (ascii_strcasematch (ext, ".com"))
1180             break;
1181           pgm = (char *) "/bin/sh";
1182           arg1 = NULL;
1183         }
1184
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. */
1190
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);
1194
1195       /* pointers:
1196        * pgm    interpreter name
1197        * arg1   optional string
1198        */
1199       if (arg1)
1200         unshift (arg1);
1201
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);
1206     }
1207   return 0;
1208
1209 err:
1210   __seterrno ();
1211   return -1;
1212 }