OSDN Git Service

* path.cc (conv_path_list): Take cygwin_conv_path_t as third parameter.
[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   /* The CREATE_SUSPENDED case is handled below */
696   if (iscygwin () && !(c_flags & CREATE_SUSPENDED))
697     strace.write_childpid (pi.dwProcessId);
698
699   /* Fixup the parent data structures if needed and resume the child's
700      main thread. */
701   if (::cygheap->fdtab.need_fixup_before ())
702     ::cygheap->fdtab.fixup_before_exec (pi.dwProcessId);
703
704   if (mode != _P_OVERLAY)
705     cygpid = cygwin_pid (pi.dwProcessId);
706   else
707     cygpid = myself->pid;
708
709   /* We print the original program name here so the user can see that too.  */
710   syscall_printf ("%d = child_info_spawn::worker (%s, %.9500s)",
711                   rc ? cygpid : (unsigned int) -1, prog_arg, one_line.buf);
712
713   /* Name the handle similarly to proc_subproc. */
714   ProtectHandle1 (pi.hProcess, childhProc);
715
716   bool synced;
717   pid_t pid;
718   if (mode == _P_OVERLAY)
719     {
720       myself->dwProcessId = pi.dwProcessId;
721       strace.execing = 1;
722       myself.hProcess = hExeced = pi.hProcess;
723       real_path.get_wide_win32_path (myself->progname); // FIXME: race?
724       sigproc_printf ("new process name %W", myself->progname);
725       /* If wr_proc_pipe doesn't exist then this process was not started by a cygwin
726          process.  So, we need to wait around until the process we've just "execed"
727          dies.  Use our own wait facility to wait for our own pid to exit (there
728          is some minor special case code in proc_waiter and friends to accommodate
729          this).
730
731          If wr_proc_pipe exists, then it should be duplicated to the child.
732          If the child has exited already, that's ok.  The parent will pick up
733          on this fact when we exit.  dup_proc_pipe will close our end of the pipe.
734          Note that wr_proc_pipe may also be == INVALID_HANDLE_VALUE.  That will make
735          dup_proc_pipe essentially a no-op.  */
736       if (!newargv.win16_exe && myself->wr_proc_pipe)
737         {
738           if (!looped)
739             myself->sync_proc_pipe ();  /* Make sure that we own wr_proc_pipe
740                                            just in case we've been previously
741                                            execed. */
742           orig_wr_proc_pipe = myself->dup_proc_pipe (pi.hProcess);
743         }
744       pid = myself->pid;
745       if (!iscygwin ())
746         close_all_files ();
747     }
748   else
749     {
750       myself->set_has_pgid_children ();
751       ProtectHandle (pi.hThread);
752       pinfo child (cygpid,
753                    PID_IN_USE | (real_path.iscygexec () ? 0 : PID_NOTCYGWIN));
754       if (!child)
755         {
756           syscall_printf ("pinfo failed");
757           if (get_errno () != ENOMEM)
758             set_errno (EAGAIN);
759           res = -1;
760           goto out;
761         }
762       child->dwProcessId = pi.dwProcessId;
763       child.hProcess = pi.hProcess;
764
765       real_path.get_wide_win32_path (child->progname);
766       /* FIXME: This introduces an unreferenced, open handle into the child.
767          The purpose is to keep the pid shared memory open so that all of
768          the fields filled out by child.remember do not disappear and so there
769          is not a brief period during which the pid is not available.
770          However, we should try to find another way to do this eventually. */
771       DuplicateHandle (GetCurrentProcess (), child.shared_handle (),
772                        pi.hProcess, NULL, 0, 0, DUPLICATE_SAME_ACCESS);
773       child->start_time = time (NULL); /* Register child's starting time. */
774       child->nice = myself->nice;
775       if (!child.remember (mode == _P_DETACH))
776         {
777           /* FIXME: Child in strange state now */
778           CloseHandle (pi.hProcess);
779           ForceCloseHandle (pi.hThread);
780           res = -1;
781           goto out;
782         }
783       pid = child->pid;
784     }
785
786   /* Start the child running */
787   if (c_flags & CREATE_SUSPENDED)
788     {
789       ResumeThread (pi.hThread);
790       if (iscygwin ())
791         strace.write_childpid (pi.dwProcessId);
792     }
793   ForceCloseHandle (pi.hThread);
794
795   sigproc_printf ("spawned windows pid %d", pi.dwProcessId);
796
797   if ((mode == _P_DETACH || mode == _P_NOWAIT) && !iscygwin ())
798     synced = false;
799   else
800     synced = sync (pi.dwProcessId, pi.hProcess, INFINITE);
801
802   switch (mode)
803     {
804     case _P_OVERLAY:
805       myself.hProcess = pi.hProcess;
806       if (!synced)
807         {
808           if (orig_wr_proc_pipe)
809             {
810               myself->wr_proc_pipe_owner = GetCurrentProcessId ();
811               myself->wr_proc_pipe = orig_wr_proc_pipe;
812             }
813           if (!proc_retry (pi.hProcess))
814             {
815               looped++;
816               goto loop;
817             }
818           close_all_files (true);
819         }
820       else
821         {
822           close_all_files (true);
823           if (!myself->wr_proc_pipe
824               && WaitForSingleObject (pi.hProcess, 0) == WAIT_TIMEOUT)
825             {
826               extern bool is_toplevel_proc;
827               is_toplevel_proc = true;
828               myself.remember (false);
829               wait_for_myself ();
830             }
831         }
832       this->cleanup ();
833       myself.exit (EXITCODE_NOSET);
834       break;
835     case _P_WAIT:
836     case _P_SYSTEM:
837       if (waitpid (cygpid, &res, 0) != cygpid)
838         res = -1;
839       break;
840     case _P_DETACH:
841       res = 0;  /* Lost all memory of this child. */
842       break;
843     case _P_NOWAIT:
844     case _P_NOWAITO:
845     case _P_VFORK:
846       res = cygpid;
847       break;
848     default:
849       break;
850     }
851
852 out:
853   this->cleanup ();
854   if (envblock)
855     free (envblock);
856   pthread_cleanup_pop (1);
857   return (int) res;
858 }
859
860 extern "C" int
861 cwait (int *result, int pid, int)
862 {
863   return waitpid (pid, result, 0);
864 }
865
866 /*
867 * Helper function for spawn runtime calls.
868 * Doesn't search the path.
869 */
870
871 extern "C" int
872 spawnve (int mode, const char *path, const char *const *argv,
873        const char *const *envp)
874 {
875   static char *const empty_env[] = { NULL };
876
877   int ret;
878 #ifdef NEWVFORK
879   vfork_save *vf = vfork_storage.val ();
880
881   if (vf != NULL && (vf->pid < 0) && mode == _P_OVERLAY)
882     mode = _P_NOWAIT;
883   else
884     vf = NULL;
885 #endif
886
887   syscall_printf ("spawnve (%s, %s, %x)", path, argv[0], envp);
888
889   if (!envp)
890     envp = empty_env;
891
892   switch (_P_MODE (mode))
893     {
894     case _P_OVERLAY:
895       ch_spawn.worker (path, argv, envp, mode);
896       /* Errno should be set by worker.  */
897       ret = -1;
898       break;
899     case _P_VFORK:
900     case _P_NOWAIT:
901     case _P_NOWAITO:
902     case _P_WAIT:
903     case _P_DETACH:
904     case _P_SYSTEM:
905       ret = ch_spawn.worker (path, argv, envp, mode);
906 #ifdef NEWVFORK
907       if (vf)
908         {
909           if (ret > 0)
910             {
911               debug_printf ("longjmping due to vfork");
912               vf->restore_pid (ret);
913             }
914         }
915 #endif
916       break;
917     default:
918       set_errno (EINVAL);
919       ret = -1;
920       break;
921     }
922   return ret;
923 }
924
925 /*
926 * spawn functions as implemented in the MS runtime library.
927 * Most of these based on (and copied from) newlib/libc/posix/execXX.c
928 */
929
930 extern "C" int
931 spawnl (int mode, const char *path, const char *arg0, ...)
932 {
933   int i;
934   va_list args;
935   const char *argv[256];
936
937   va_start (args, arg0);
938   argv[0] = arg0;
939   i = 1;
940
941   do
942       argv[i] = va_arg (args, const char *);
943   while (argv[i++] != NULL);
944
945   va_end (args);
946
947   return spawnve (mode, path, (char * const  *) argv, cur_environ ());
948 }
949
950 extern "C" int
951 spawnle (int mode, const char *path, const char *arg0, ...)
952 {
953   int i;
954   va_list args;
955   const char * const *envp;
956   const char *argv[256];
957
958   va_start (args, arg0);
959   argv[0] = arg0;
960   i = 1;
961
962   do
963     argv[i] = va_arg (args, const char *);
964   while (argv[i++] != NULL);
965
966   envp = va_arg (args, const char * const *);
967   va_end (args);
968
969   return spawnve (mode, path, (char * const *) argv, (char * const *) envp);
970 }
971
972 extern "C" int
973 spawnlp (int mode, const char *file, const char *arg0, ...)
974 {
975   int i;
976   va_list args;
977   const char *argv[256];
978   path_conv buf;
979
980   va_start (args, arg0);
981   argv[0] = arg0;
982   i = 1;
983
984   do
985       argv[i] = va_arg (args, const char *);
986   while (argv[i++] != NULL);
987
988   va_end (args);
989
990   return spawnve (mode | _P_PATH_TYPE_EXEC, find_exec (file, buf),
991                   (char * const *) argv, cur_environ ());
992 }
993
994 extern "C" int
995 spawnlpe (int mode, const char *file, const char *arg0, ...)
996 {
997   int i;
998   va_list args;
999   const char * const *envp;
1000   const char *argv[256];
1001   path_conv buf;
1002
1003   va_start (args, arg0);
1004   argv[0] = arg0;
1005   i = 1;
1006
1007   do
1008     argv[i] = va_arg (args, const char *);
1009   while (argv[i++] != NULL);
1010
1011   envp = va_arg (args, const char * const *);
1012   va_end (args);
1013
1014   return spawnve (mode | _P_PATH_TYPE_EXEC, find_exec (file, buf),
1015                   (char * const *) argv, envp);
1016 }
1017
1018 extern "C" int
1019 spawnv (int mode, const char *path, const char * const *argv)
1020 {
1021   return spawnve (mode, path, argv, cur_environ ());
1022 }
1023
1024 extern "C" int
1025 spawnvp (int mode, const char *file, const char * const *argv)
1026 {
1027   path_conv buf;
1028   return spawnve (mode | _P_PATH_TYPE_EXEC, find_exec (file, buf), argv,
1029                   cur_environ ());
1030 }
1031
1032 extern "C" int
1033 spawnvpe (int mode, const char *file, const char * const *argv,
1034           const char * const *envp)
1035 {
1036   path_conv buf;
1037   return spawnve (mode | _P_PATH_TYPE_EXEC, find_exec (file, buf), argv, envp);
1038 }
1039
1040 int
1041 av::fixup (const char *prog_arg, path_conv& real_path, const char *ext,
1042            bool p_type_exec)
1043 {
1044   const char *p;
1045   bool exeext = ascii_strcasematch (ext, ".exe");
1046   if ((exeext && real_path.iscygexec ()) || ascii_strcasematch (ext, ".bat"))
1047     return 0;
1048   if (!*ext && ((p = ext - 4) > real_path.get_win32 ())
1049       && (ascii_strcasematch (p, ".bat") || ascii_strcasematch (p, ".cmd")
1050           || ascii_strcasematch (p, ".btm")))
1051     return 0;
1052   while (1)
1053     {
1054       char *pgm = NULL;
1055       char *arg1 = NULL;
1056       char *ptr, *buf;
1057       OBJECT_ATTRIBUTES attr;
1058       IO_STATUS_BLOCK io;
1059       HANDLE h;
1060       NTSTATUS status;
1061       LARGE_INTEGER size;
1062
1063       status = NtOpenFile (&h, SYNCHRONIZE | GENERIC_READ,
1064                            real_path.get_object_attr (attr, sec_none_nih),
1065                            &io, FILE_SHARE_VALID_FLAGS,
1066                            FILE_SYNCHRONOUS_IO_NONALERT
1067                            | FILE_OPEN_FOR_BACKUP_INTENT
1068                            | FILE_NON_DIRECTORY_FILE);
1069       if (!NT_SUCCESS (status))
1070         {
1071           /* File is not readable?  Doesn't mean it's not executable.
1072              Test for executability and if so, just assume the file is
1073              a cygwin executable and go ahead. */
1074           if (status == STATUS_ACCESS_DENIED && real_path.has_acls ()
1075               && check_file_access (real_path, X_OK, true) == 0)
1076             {
1077               real_path.set_cygexec (true);
1078               break;
1079             }
1080           goto err;
1081         }
1082       if (!GetFileSizeEx (h, &size))
1083         {
1084           NtClose (h);
1085           goto err;
1086         }
1087       if (size.QuadPart > wincap.allocation_granularity ())
1088         size.LowPart = wincap.allocation_granularity ();
1089
1090       HANDLE hm = CreateFileMapping (h, &sec_none_nih, PAGE_READONLY,
1091                                      0, 0, NULL);
1092       NtClose (h);
1093       if (!hm)
1094         {
1095           /* ERROR_FILE_INVALID indicates very likely an empty file. */
1096           if (GetLastError () == ERROR_FILE_INVALID)
1097             {
1098               debug_printf ("zero length file, treat as script.");
1099               goto just_shell;
1100             }
1101           goto err;
1102         }
1103       /* Try to map the first 64K of the image.  That's enough for the local
1104          tests, and it's enough for hook_or_detect_cygwin to compute the IAT
1105          address. */
1106       buf = (char *) MapViewOfFile (hm, FILE_MAP_READ, 0, 0, size.LowPart);
1107       if (!buf)
1108         {
1109           CloseHandle (hm);
1110           goto err;
1111         }
1112
1113       {
1114         myfault efault;
1115         if (efault.faulted ())
1116           {
1117             UnmapViewOfFile (buf);
1118             CloseHandle (hm);
1119             real_path.set_cygexec (false);
1120             break;
1121           }
1122         if (buf[0] == 'M' && buf[1] == 'Z')
1123           {
1124             WORD subsys;
1125             unsigned off = (unsigned char) buf[0x18] | (((unsigned char) buf[0x19]) << 8);
1126             win16_exe = off < sizeof (IMAGE_DOS_HEADER);
1127             if (!win16_exe)
1128               real_path.set_cygexec (!!hook_or_detect_cygwin (buf, NULL,
1129                                                               subsys, hm));
1130             else
1131               real_path.set_cygexec (false);
1132             UnmapViewOfFile (buf);
1133             CloseHandle (hm);
1134             break;
1135           }
1136       }
1137       CloseHandle (hm);
1138
1139       debug_printf ("%s is possibly a script", real_path.get_win32 ());
1140
1141       ptr = buf;
1142       if (*ptr++ == '#' && *ptr++ == '!')
1143         {
1144           ptr += strspn (ptr, " \t");
1145           size_t len = strcspn (ptr, "\r\n");
1146           if (len)
1147             {
1148               char *namebuf = (char *) alloca (len + 1);
1149               memcpy (namebuf, ptr, len);
1150               namebuf[len] = '\0';
1151               for (ptr = pgm = namebuf; *ptr; ptr++)
1152                 if (!arg1 && (*ptr == ' ' || *ptr == '\t'))
1153                   {
1154                     /* Null terminate the initial command and step over any
1155                        additional white space.  If we've hit the end of the
1156                        line, exit the loop.  Otherwise, we've found the first
1157                        argument. Position the current pointer on the last known
1158                        white space. */
1159                     *ptr = '\0';
1160                     char *newptr = ptr + 1;
1161                     newptr += strspn (newptr, " \t");
1162                     if (!*newptr)
1163                       break;
1164                     arg1 = newptr;
1165                     ptr = newptr - 1;
1166                   }
1167             }
1168         }
1169       UnmapViewOfFile (buf);
1170 just_shell:
1171       if (!pgm)
1172         {
1173           if (!p_type_exec)
1174             {
1175               /* Not called from exec[lv]p.  Don't try to treat as script. */
1176               debug_printf ("%s is not a valid executable",
1177                             real_path.get_win32 ());
1178               set_errno (ENOEXEC);
1179               return -1;
1180             }
1181           if (ascii_strcasematch (ext, ".com"))
1182             break;
1183           pgm = (char *) "/bin/sh";
1184           arg1 = NULL;
1185         }
1186
1187       /* Check if script is executable.  Otherwise we start non-executable
1188          scripts successfully, which is incorrect behaviour. */
1189       if (real_path.has_acls ()
1190           && check_file_access (real_path, X_OK, true) < 0)
1191         return -1;      /* errno is already set. */
1192
1193       /* Replace argv[0] with the full path to the script if this is the
1194          first time through the loop. */
1195       replace0_maybe (prog_arg);
1196
1197       /* pointers:
1198        * pgm    interpreter name
1199        * arg1   optional string
1200        */
1201       if (arg1)
1202         unshift (arg1);
1203
1204       /* FIXME: This should not be using FE_NATIVE.  It should be putting
1205          the posix path on the argv list. */
1206       find_exec (pgm, real_path, "PATH=", FE_NATIVE, &ext);
1207       unshift (real_path.get_win32 (), 1);
1208     }
1209   return 0;
1210
1211 err:
1212   __seterrno ();
1213   return -1;
1214 }