1169695Skan/* Utilities to execute a program in a subprocess (possibly linked by pipes
2169695Skan   with other subprocesses), and wait for it.  Generic Win32 specialization.
3169695Skan   Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005
4169695Skan   Free Software Foundation, Inc.
5169695Skan
6169695SkanThis file is part of the libiberty library.
7169695SkanLibiberty is free software; you can redistribute it and/or
8169695Skanmodify it under the terms of the GNU Library General Public
9169695SkanLicense as published by the Free Software Foundation; either
10169695Skanversion 2 of the License, or (at your option) any later version.
11169695Skan
12169695SkanLibiberty is distributed in the hope that it will be useful,
13169695Skanbut WITHOUT ANY WARRANTY; without even the implied warranty of
14169695SkanMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15169695SkanLibrary General Public License for more details.
16169695Skan
17169695SkanYou should have received a copy of the GNU Library General Public
18169695SkanLicense along with libiberty; see the file COPYING.LIB.  If not,
19169695Skanwrite to the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor,
20169695SkanBoston, MA 02110-1301, USA.  */
21169695Skan
22169695Skan#include "pex-common.h"
23169695Skan
24169695Skan#include <windows.h>
25169695Skan
26169695Skan#ifdef HAVE_STDLIB_H
27169695Skan#include <stdlib.h>
28169695Skan#endif
29169695Skan#ifdef HAVE_STRING_H
30169695Skan#include <string.h>
31169695Skan#endif
32169695Skan#ifdef HAVE_UNISTD_H
33169695Skan#include <unistd.h>
34169695Skan#endif
35169695Skan#ifdef HAVE_SYS_WAIT_H
36169695Skan#include <sys/wait.h>
37169695Skan#endif
38169695Skan
39169695Skan#include <assert.h>
40169695Skan#include <process.h>
41169695Skan#include <io.h>
42169695Skan#include <fcntl.h>
43169695Skan#include <signal.h>
44169695Skan#include <sys/stat.h>
45169695Skan#include <errno.h>
46169695Skan#include <ctype.h>
47169695Skan
48169695Skan/* mingw32 headers may not define the following.  */
49169695Skan
50169695Skan#ifndef _P_WAIT
51169695Skan#  define _P_WAIT	0
52169695Skan#  define _P_NOWAIT	1
53169695Skan#  define _P_OVERLAY	2
54169695Skan#  define _P_NOWAITO	3
55169695Skan#  define _P_DETACH	4
56169695Skan
57169695Skan#  define WAIT_CHILD		0
58169695Skan#  define WAIT_GRANDCHILD	1
59169695Skan#endif
60169695Skan
61169695Skan#define MINGW_NAME "Minimalist GNU for Windows"
62169695Skan#define MINGW_NAME_LEN (sizeof(MINGW_NAME) - 1)
63169695Skan
64169695Skanextern char *stpcpy (char *dst, const char *src);
65169695Skan
66169695Skan/* Ensure that the executable pathname uses Win32 backslashes. This
67169695Skan   is not necessary on NT, but on W9x, forward slashes causes
68169695Skan   failure of spawn* and exec* functions (and probably any function
69169695Skan   that calls CreateProcess) *iff* the executable pathname (argv[0])
70169695Skan   is a quoted string.  And quoting is necessary in case a pathname
71169695Skan   contains embedded white space.  You can't win.  */
72169695Skanstatic void
73169695Skanbackslashify (char *s)
74169695Skan{
75169695Skan  while ((s = strchr (s, '/')) != NULL)
76169695Skan    *s = '\\';
77169695Skan  return;
78169695Skan}
79169695Skan
80169695Skanstatic int pex_win32_open_read (struct pex_obj *, const char *, int);
81169695Skanstatic int pex_win32_open_write (struct pex_obj *, const char *, int);
82169695Skanstatic long pex_win32_exec_child (struct pex_obj *, int, const char *,
83169695Skan				  char * const *, char * const *,
84169695Skan                                  int, int, int, int,
85169695Skan				  const char **, int *);
86169695Skanstatic int pex_win32_close (struct pex_obj *, int);
87169695Skanstatic int pex_win32_wait (struct pex_obj *, long, int *,
88169695Skan			   struct pex_time *, int, const char **, int *);
89169695Skanstatic int pex_win32_pipe (struct pex_obj *, int *, int);
90169695Skanstatic FILE *pex_win32_fdopenr (struct pex_obj *, int, int);
91169695Skanstatic FILE *pex_win32_fdopenw (struct pex_obj *, int, int);
92169695Skan
93169695Skan/* The list of functions we pass to the common routines.  */
94169695Skan
95169695Skanconst struct pex_funcs funcs =
96169695Skan{
97169695Skan  pex_win32_open_read,
98169695Skan  pex_win32_open_write,
99169695Skan  pex_win32_exec_child,
100169695Skan  pex_win32_close,
101169695Skan  pex_win32_wait,
102169695Skan  pex_win32_pipe,
103169695Skan  pex_win32_fdopenr,
104169695Skan  pex_win32_fdopenw,
105169695Skan  NULL /* cleanup */
106169695Skan};
107169695Skan
108169695Skan/* Return a newly initialized pex_obj structure.  */
109169695Skan
110169695Skanstruct pex_obj *
111169695Skanpex_init (int flags, const char *pname, const char *tempbase)
112169695Skan{
113169695Skan  return pex_init_common (flags, pname, tempbase, &funcs);
114169695Skan}
115169695Skan
116169695Skan/* Open a file for reading.  */
117169695Skan
118169695Skanstatic int
119169695Skanpex_win32_open_read (struct pex_obj *obj ATTRIBUTE_UNUSED, const char *name,
120169695Skan		     int binary)
121169695Skan{
122169695Skan  return _open (name, _O_RDONLY | (binary ? _O_BINARY : _O_TEXT));
123169695Skan}
124169695Skan
125169695Skan/* Open a file for writing.  */
126169695Skan
127169695Skanstatic int
128169695Skanpex_win32_open_write (struct pex_obj *obj ATTRIBUTE_UNUSED, const char *name,
129169695Skan		      int binary)
130169695Skan{
131169695Skan  /* Note that we can't use O_EXCL here because gcc may have already
132169695Skan     created the temporary file via make_temp_file.  */
133169695Skan  return _open (name,
134169695Skan		(_O_WRONLY | _O_CREAT | _O_TRUNC
135169695Skan		 | (binary ? _O_BINARY : _O_TEXT)),
136169695Skan		_S_IREAD | _S_IWRITE);
137169695Skan}
138169695Skan
139169695Skan/* Close a file.  */
140169695Skan
141169695Skanstatic int
142169695Skanpex_win32_close (struct pex_obj *obj ATTRIBUTE_UNUSED, int fd)
143169695Skan{
144169695Skan  return _close (fd);
145169695Skan}
146169695Skan
147169695Skan#ifdef USE_MINGW_MSYS
148169695Skanstatic const char *mingw_keys[] = {"SOFTWARE", "Microsoft", "Windows", "CurrentVersion", "Uninstall", NULL};
149169695Skan
150169695Skan/* Tack the executable on the end of a (possibly slash terminated) buffer
151169695Skan   and convert everything to \. */
152169695Skanstatic const char *
153169695Skantack_on_executable (char *buf, const char *executable)
154169695Skan{
155169695Skan  char *p = strchr (buf, '\0');
156169695Skan  if (p > buf && (p[-1] == '\\' || p[-1] == '/'))
157169695Skan    p[-1] = '\0';
158169695Skan  backslashify (strcat (buf, executable));
159169695Skan  return buf;
160169695Skan}
161169695Skan
162169695Skan/* Walk down a registry hierarchy until the end.  Return the key. */
163169695Skanstatic HKEY
164169695Skanopenkey (HKEY hStart, const char *keys[])
165169695Skan{
166169695Skan  HKEY hKey, hTmp;
167169695Skan  for (hKey = hStart; *keys; keys++)
168169695Skan    {
169169695Skan      LONG res;
170169695Skan      hTmp = hKey;
171169695Skan      res = RegOpenKey (hTmp, *keys, &hKey);
172169695Skan
173169695Skan      if (hTmp != HKEY_LOCAL_MACHINE)
174169695Skan	RegCloseKey (hTmp);
175169695Skan
176169695Skan      if (res != ERROR_SUCCESS)
177169695Skan	return NULL;
178169695Skan    }
179169695Skan  return hKey;
180169695Skan}
181169695Skan
182169695Skan/* Return the "mingw root" as derived from the mingw uninstall information. */
183169695Skanstatic const char *
184169695Skanmingw_rootify (const char *executable)
185169695Skan{
186169695Skan  HKEY hKey, hTmp;
187169695Skan  DWORD maxlen;
188169695Skan  char *namebuf, *foundbuf;
189169695Skan  DWORD i;
190169695Skan  LONG res;
191169695Skan
192169695Skan  /* Open the uninstall "directory". */
193169695Skan  hKey = openkey (HKEY_LOCAL_MACHINE, mingw_keys);
194169695Skan
195169695Skan  /* Not found. */
196169695Skan  if (!hKey)
197169695Skan    return executable;
198169695Skan
199169695Skan  /* Need to enumerate all of the keys here looking for one the most recent
200169695Skan     one for MinGW. */
201169695Skan  if (RegQueryInfoKey (hKey, NULL, NULL, NULL, NULL, &maxlen, NULL, NULL,
202169695Skan		       NULL, NULL, NULL, NULL) != ERROR_SUCCESS)
203169695Skan    {
204169695Skan      RegCloseKey (hKey);
205169695Skan      return executable;
206169695Skan    }
207169695Skan  namebuf = XNEWVEC (char, ++maxlen);
208169695Skan  foundbuf = XNEWVEC (char, maxlen);
209169695Skan  foundbuf[0] = '\0';
210169695Skan  if (!namebuf || !foundbuf)
211169695Skan    {
212169695Skan      RegCloseKey (hKey);
213169695Skan      if (namebuf)
214169695Skan	free (namebuf);
215169695Skan      if (foundbuf)
216169695Skan	free (foundbuf);
217169695Skan      return executable;
218169695Skan    }
219169695Skan
220169695Skan  /* Look through all of the keys for one that begins with Minimal GNU...
221169695Skan     Try to get the latest version by doing a string compare although that
222169695Skan     string never really works with version number sorting. */
223169695Skan  for (i = 0; RegEnumKey (hKey, i, namebuf, maxlen) == ERROR_SUCCESS; i++)
224169695Skan    {
225169695Skan      int match = strcasecmp (namebuf, MINGW_NAME);
226169695Skan      if (match < 0)
227169695Skan	continue;
228169695Skan      if (match > 0 && strncasecmp (namebuf, MINGW_NAME, MINGW_NAME_LEN) > 0)
229169695Skan	continue;
230169695Skan      if (strcasecmp (namebuf, foundbuf) > 0)
231169695Skan	strcpy (foundbuf, namebuf);
232169695Skan    }
233169695Skan  free (namebuf);
234169695Skan
235169695Skan  /* If foundbuf is empty, we didn't find anything.  Punt. */
236169695Skan  if (!foundbuf[0])
237169695Skan    {
238169695Skan      free (foundbuf);
239169695Skan      RegCloseKey (hKey);
240169695Skan      return executable;
241169695Skan    }
242169695Skan
243169695Skan  /* Open the key that we wanted */
244169695Skan  res = RegOpenKey (hKey, foundbuf, &hTmp);
245169695Skan  RegCloseKey (hKey);
246169695Skan  free (foundbuf);
247169695Skan
248169695Skan  /* Don't know why this would fail, but you gotta check */
249169695Skan  if (res != ERROR_SUCCESS)
250169695Skan    return executable;
251169695Skan
252169695Skan  maxlen = 0;
253169695Skan  /* Get the length of the value pointed to by InstallLocation */
254169695Skan  if (RegQueryValueEx (hTmp, "InstallLocation", 0, NULL, NULL,
255169695Skan		       &maxlen) != ERROR_SUCCESS || maxlen == 0)
256169695Skan    {
257169695Skan      RegCloseKey (hTmp);
258169695Skan      return executable;
259169695Skan    }
260169695Skan
261169695Skan  /* Allocate space for the install location */
262169695Skan  foundbuf = XNEWVEC (char, maxlen + strlen (executable));
263169695Skan  if (!foundbuf)
264169695Skan    {
265169695Skan      free (foundbuf);
266169695Skan      RegCloseKey (hTmp);
267169695Skan    }
268169695Skan
269169695Skan  /* Read the install location into the buffer */
270169695Skan  res = RegQueryValueEx (hTmp, "InstallLocation", 0, NULL, (LPBYTE) foundbuf,
271169695Skan			 &maxlen);
272169695Skan  RegCloseKey (hTmp);
273169695Skan  if (res != ERROR_SUCCESS)
274169695Skan    {
275169695Skan      free (foundbuf);
276169695Skan      return executable;
277169695Skan    }
278169695Skan
279169695Skan  /* Concatenate the install location and the executable, turn all slashes
280169695Skan     to backslashes, and return that. */
281169695Skan  return tack_on_executable (foundbuf, executable);
282169695Skan}
283169695Skan
284169695Skan/* Read the install location of msys from it's installation file and
285169695Skan   rootify the executable based on that. */
286169695Skanstatic const char *
287169695Skanmsys_rootify (const char *executable)
288169695Skan{
289169695Skan  size_t bufsize = 64;
290169695Skan  size_t execlen = strlen (executable) + 1;
291169695Skan  char *buf;
292169695Skan  DWORD res = 0;
293169695Skan  for (;;)
294169695Skan    {
295169695Skan      buf = XNEWVEC (char, bufsize + execlen);
296169695Skan      if (!buf)
297169695Skan	break;
298169695Skan      res = GetPrivateProfileString ("InstallSettings", "InstallPath", NULL,
299169695Skan				     buf, bufsize, "msys.ini");
300169695Skan      if (!res)
301169695Skan	break;
302169695Skan      if (strlen (buf) < bufsize)
303169695Skan	break;
304169695Skan      res = 0;
305169695Skan      free (buf);
306169695Skan      bufsize *= 2;
307169695Skan      if (bufsize > 65536)
308169695Skan	{
309169695Skan	  buf = NULL;
310169695Skan	  break;
311169695Skan	}
312169695Skan    }
313169695Skan
314169695Skan  if (res)
315169695Skan    return tack_on_executable (buf, executable);
316169695Skan
317169695Skan  /* failed */
318169695Skan  if (buf)
319169695Skan    free (buf);
320169695Skan  return executable;
321169695Skan}
322169695Skan#endif
323169695Skan
324169695Skan/* Return a Windows command-line from ARGV.  It is the caller's
325169695Skan   responsibility to free the string returned.  */
326169695Skan
327169695Skanstatic char *
328169695Skanargv_to_cmdline (char *const *argv)
329169695Skan{
330169695Skan  char *cmdline;
331169695Skan  char *p;
332169695Skan  size_t cmdline_len;
333169695Skan  int i, j, k;
334169695Skan
335169695Skan  cmdline_len = 0;
336169695Skan  for (i = 0; argv[i]; i++)
337169695Skan    {
338169695Skan      /* We quote every last argument.  This simplifies the problem;
339169695Skan	 we need only escape embedded double-quotes and immediately
340169695Skan	 preceeding backslash characters.  A sequence of backslach characters
341169695Skan	 that is not follwed by a double quote character will not be
342169695Skan	 escaped.  */
343169695Skan      for (j = 0; argv[i][j]; j++)
344169695Skan	{
345169695Skan	  if (argv[i][j] == '"')
346169695Skan	    {
347169695Skan	      /* Escape preceeding backslashes.  */
348169695Skan	      for (k = j - 1; k >= 0 && argv[i][k] == '\\'; k--)
349169695Skan		cmdline_len++;
350169695Skan	      /* Escape the qote character.  */
351169695Skan	      cmdline_len++;
352169695Skan	    }
353169695Skan	}
354169695Skan      /* Trailing backslashes also need to be escaped because they will be
355169695Skan         followed by the terminating quote.  */
356169695Skan      for (k = j - 1; k >= 0 && argv[i][k] == '\\'; k--)
357169695Skan	cmdline_len++;
358169695Skan      cmdline_len += j;
359169695Skan      cmdline_len += 3;  /* for leading and trailing quotes and space */
360169695Skan    }
361169695Skan  cmdline = xmalloc (cmdline_len);
362169695Skan  p = cmdline;
363169695Skan  for (i = 0; argv[i]; i++)
364169695Skan    {
365169695Skan      *p++ = '"';
366169695Skan      for (j = 0; argv[i][j]; j++)
367169695Skan	{
368169695Skan	  if (argv[i][j] == '"')
369169695Skan	    {
370169695Skan	      for (k = j - 1; k >= 0 && argv[i][k] == '\\'; k--)
371169695Skan		*p++ = '\\';
372169695Skan	      *p++ = '\\';
373169695Skan	    }
374169695Skan	  *p++ = argv[i][j];
375169695Skan	}
376169695Skan      for (k = j - 1; k >= 0 && argv[i][k] == '\\'; k--)
377169695Skan	*p++ = '\\';
378169695Skan      *p++ = '"';
379169695Skan      *p++ = ' ';
380169695Skan    }
381169695Skan  p[-1] = '\0';
382169695Skan  return cmdline;
383169695Skan}
384169695Skan
385169695Skanstatic const char *const
386169695Skanstd_suffixes[] = {
387169695Skan  ".com",
388169695Skan  ".exe",
389169695Skan  ".bat",
390169695Skan  ".cmd",
391169695Skan  0
392169695Skan};
393169695Skanstatic const char *const
394169695Skanno_suffixes[] = {
395169695Skan  "",
396169695Skan  0
397169695Skan};
398169695Skan
399169695Skan/* Returns the full path to PROGRAM.  If SEARCH is true, look for
400169695Skan   PROGRAM in each directory in PATH.  */
401169695Skan
402169695Skanstatic char *
403169695Skanfind_executable (const char *program, BOOL search)
404169695Skan{
405169695Skan  char *full_executable;
406169695Skan  char *e;
407169695Skan  size_t fe_len;
408169695Skan  const char *path = 0;
409169695Skan  const char *const *ext;
410169695Skan  const char *p, *q;
411169695Skan  size_t proglen = strlen (program);
412169695Skan  int has_extension = !!strchr (program, '.');
413169695Skan  int has_slash = (strchr (program, '/') || strchr (program, '\\'));
414169695Skan  HANDLE h;
415169695Skan
416169695Skan  if (has_slash)
417169695Skan    search = FALSE;
418169695Skan
419169695Skan  if (search)
420169695Skan    path = getenv ("PATH");
421169695Skan  if (!path)
422169695Skan    path = "";
423169695Skan
424169695Skan  fe_len = 0;
425169695Skan  for (p = path; *p; p = q)
426169695Skan    {
427169695Skan      q = p;
428169695Skan      while (*q != ';' && *q != '\0')
429169695Skan	q++;
430169695Skan      if ((size_t)(q - p) > fe_len)
431169695Skan	fe_len = q - p;
432169695Skan      if (*q == ';')
433169695Skan	q++;
434169695Skan    }
435169695Skan  fe_len = fe_len + 1 + proglen + (has_extension ? 1 : 5);
436169695Skan  full_executable = xmalloc (fe_len);
437169695Skan
438169695Skan  p = path;
439169695Skan  do
440169695Skan    {
441169695Skan      q = p;
442169695Skan      while (*q != ';' && *q != '\0')
443169695Skan	q++;
444169695Skan
445169695Skan      e = full_executable;
446169695Skan      memcpy (e, p, q - p);
447169695Skan      e += (q - p);
448169695Skan      if (q - p)
449169695Skan	*e++ = '\\';
450169695Skan      strcpy (e, program);
451169695Skan
452169695Skan      if (*q == ';')
453169695Skan	q++;
454169695Skan
455169695Skan      for (e = full_executable; *e; e++)
456169695Skan	if (*e == '/')
457169695Skan	  *e = '\\';
458169695Skan
459169695Skan      /* At this point, e points to the terminating NUL character for
460169695Skan         full_executable.  */
461169695Skan      for (ext = has_extension ? no_suffixes : std_suffixes; *ext; ext++)
462169695Skan	{
463169695Skan	  /* Remove any current extension.  */
464169695Skan	  *e = '\0';
465169695Skan	  /* Add the new one.  */
466169695Skan	  strcat (full_executable, *ext);
467169695Skan
468169695Skan	  /* Attempt to open this file.  */
469169695Skan	  h = CreateFile (full_executable, GENERIC_READ,
470169695Skan			  FILE_SHARE_READ | FILE_SHARE_WRITE,
471169695Skan			  0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
472169695Skan	  if (h != INVALID_HANDLE_VALUE)
473169695Skan	    goto found;
474169695Skan	}
475169695Skan      p = q;
476169695Skan    }
477169695Skan  while (*p);
478169695Skan  free (full_executable);
479169695Skan  return 0;
480169695Skan
481169695Skan found:
482169695Skan  CloseHandle (h);
483169695Skan  return full_executable;
484169695Skan}
485169695Skan
486169695Skan/* Low-level process creation function and helper.  */
487169695Skan
488169695Skanstatic int
489169695Skanenv_compare (const void *a_ptr, const void *b_ptr)
490169695Skan{
491169695Skan  const char *a;
492169695Skan  const char *b;
493169695Skan  unsigned char c1;
494169695Skan  unsigned char c2;
495169695Skan
496169695Skan  a = *(const char **) a_ptr;
497169695Skan  b = *(const char **) b_ptr;
498169695Skan
499169695Skan  /* a and b will be of the form: VAR=VALUE
500169695Skan     We compare only the variable name part here using a case-insensitive
501169695Skan     comparison algorithm.  It might appear that in fact strcasecmp () can
502169695Skan     take the place of this whole function, and indeed it could, save for
503169695Skan     the fact that it would fail in cases such as comparing A1=foo and
504169695Skan     A=bar (because 1 is less than = in the ASCII character set).
505169695Skan     (Environment variables containing no numbers would work in such a
506169695Skan     scenario.)  */
507169695Skan
508169695Skan  do
509169695Skan    {
510169695Skan      c1 = (unsigned char) tolower (*a++);
511169695Skan      c2 = (unsigned char) tolower (*b++);
512169695Skan
513169695Skan      if (c1 == '=')
514169695Skan        c1 = '\0';
515169695Skan
516169695Skan      if (c2 == '=')
517169695Skan        c2 = '\0';
518169695Skan    }
519169695Skan  while (c1 == c2 && c1 != '\0');
520169695Skan
521169695Skan  return c1 - c2;
522169695Skan}
523169695Skan
524169695Skanstatic long
525169695Skanwin32_spawn (const char *executable,
526169695Skan	     BOOL search,
527169695Skan	     char *const *argv,
528169695Skan             char *const *env, /* array of strings of the form: VAR=VALUE */
529169695Skan	     DWORD dwCreationFlags,
530169695Skan	     LPSTARTUPINFO si,
531169695Skan	     LPPROCESS_INFORMATION pi)
532169695Skan{
533169695Skan  char *full_executable;
534169695Skan  char *cmdline;
535169695Skan  char **env_copy;
536169695Skan  char *env_block = NULL;
537169695Skan
538169695Skan  full_executable = NULL;
539169695Skan  cmdline = NULL;
540169695Skan
541169695Skan  if (env)
542169695Skan    {
543169695Skan      int env_size;
544169695Skan
545169695Skan      /* Count the number of environment bindings supplied.  */
546169695Skan      for (env_size = 0; env[env_size]; env_size++)
547169695Skan        continue;
548169695Skan
549169695Skan      /* Assemble an environment block, if required.  This consists of
550169695Skan         VAR=VALUE strings juxtaposed (with one null character between each
551169695Skan         pair) and an additional null at the end.  */
552169695Skan      if (env_size > 0)
553169695Skan        {
554169695Skan          int var;
555169695Skan          int total_size = 1; /* 1 is for the final null.  */
556169695Skan          char *bufptr;
557169695Skan
558169695Skan          /* Windows needs the members of the block to be sorted by variable
559169695Skan             name.  */
560169695Skan          env_copy = alloca (sizeof (char *) * env_size);
561169695Skan          memcpy (env_copy, env, sizeof (char *) * env_size);
562169695Skan          qsort (env_copy, env_size, sizeof (char *), env_compare);
563169695Skan
564169695Skan          for (var = 0; var < env_size; var++)
565169695Skan            total_size += strlen (env[var]) + 1;
566169695Skan
567169695Skan          env_block = malloc (total_size);
568169695Skan          bufptr = env_block;
569169695Skan          for (var = 0; var < env_size; var++)
570169695Skan            bufptr = stpcpy (bufptr, env_copy[var]) + 1;
571169695Skan
572169695Skan          *bufptr = '\0';
573169695Skan        }
574169695Skan    }
575169695Skan
576169695Skan  full_executable = find_executable (executable, search);
577169695Skan  if (!full_executable)
578169695Skan    goto error;
579169695Skan  cmdline = argv_to_cmdline (argv);
580169695Skan  if (!cmdline)
581169695Skan    goto error;
582169695Skan
583169695Skan  /* Create the child process.  */
584169695Skan  if (!CreateProcess (full_executable, cmdline,
585169695Skan		      /*lpProcessAttributes=*/NULL,
586169695Skan		      /*lpThreadAttributes=*/NULL,
587169695Skan		      /*bInheritHandles=*/TRUE,
588169695Skan		      dwCreationFlags,
589169695Skan		      (LPVOID) env_block,
590169695Skan		      /*lpCurrentDirectory=*/NULL,
591169695Skan		      si,
592169695Skan		      pi))
593169695Skan    {
594169695Skan      if (env_block)
595169695Skan        free (env_block);
596169695Skan
597169695Skan      free (full_executable);
598169695Skan
599169695Skan      return -1;
600169695Skan    }
601169695Skan
602169695Skan  /* Clean up.  */
603169695Skan  CloseHandle (pi->hThread);
604169695Skan  free (full_executable);
605169695Skan  if (env_block)
606169695Skan    free (env_block);
607169695Skan
608169695Skan  return (long) pi->hProcess;
609169695Skan
610169695Skan error:
611169695Skan  if (env_block)
612169695Skan    free (env_block);
613169695Skan  if (cmdline)
614169695Skan    free (cmdline);
615169695Skan  if (full_executable)
616169695Skan    free (full_executable);
617169695Skan
618169695Skan  return -1;
619169695Skan}
620169695Skan
621169695Skanstatic long
622169695Skanspawn_script (const char *executable, char *const *argv,
623169695Skan              char* const *env,
624169695Skan	      DWORD dwCreationFlags,
625169695Skan	      LPSTARTUPINFO si,
626169695Skan	      LPPROCESS_INFORMATION pi)
627169695Skan{
628169695Skan  int pid = -1;
629169695Skan  int save_errno = errno;
630169695Skan  int fd = _open (executable, _O_RDONLY);
631169695Skan
632169695Skan  if (fd >= 0)
633169695Skan    {
634169695Skan      char buf[MAX_PATH + 5];
635169695Skan      int len = _read (fd, buf, sizeof (buf) - 1);
636169695Skan      _close (fd);
637169695Skan      if (len > 3)
638169695Skan	{
639169695Skan	  char *eol;
640169695Skan	  buf[len] = '\0';
641169695Skan	  eol = strchr (buf, '\n');
642169695Skan	  if (eol && strncmp (buf, "#!", 2) == 0)
643169695Skan	    {
644169695Skan	      char *executable1;
645169695Skan	      const char ** avhere = (const char **) --argv;
646169695Skan	      do
647169695Skan		*eol = '\0';
648169695Skan	      while (*--eol == '\r' || *eol == ' ' || *eol == '\t');
649169695Skan	      for (executable1 = buf + 2; *executable1 == ' ' || *executable1 == '\t'; executable1++)
650169695Skan		continue;
651169695Skan
652169695Skan	      backslashify (executable1);
653169695Skan	      *avhere = executable1;
654169695Skan#ifndef USE_MINGW_MSYS
655169695Skan	      executable = strrchr (executable1, '\\') + 1;
656169695Skan	      if (!executable)
657169695Skan		executable = executable1;
658169695Skan	      pid = win32_spawn (executable, TRUE, argv, env,
659169695Skan				 dwCreationFlags, si, pi);
660169695Skan#else
661169695Skan	      if (strchr (executable1, '\\') == NULL)
662169695Skan		pid = win32_spawn (executable1, TRUE, argv, env,
663169695Skan				   dwCreationFlags, si, pi);
664169695Skan	      else if (executable1[0] != '\\')
665169695Skan		pid = win32_spawn (executable1, FALSE, argv, env,
666169695Skan				   dwCreationFlags, si, pi);
667169695Skan	      else
668169695Skan		{
669169695Skan		  const char *newex = mingw_rootify (executable1);
670169695Skan		  *avhere = newex;
671169695Skan		  pid = win32_spawn (newex, FALSE, argv, env,
672169695Skan				     dwCreationFlags, si, pi);
673169695Skan		  if (executable1 != newex)
674169695Skan		    free ((char *) newex);
675169695Skan		  if (pid < 0)
676169695Skan		    {
677169695Skan		      newex = msys_rootify (executable1);
678169695Skan		      if (newex != executable1)
679169695Skan			{
680169695Skan			  *avhere = newex;
681169695Skan			  pid = win32_spawn (newex, FALSE, argv, env,
682169695Skan					     dwCreationFlags, si, pi);
683169695Skan			  free ((char *) newex);
684169695Skan			}
685169695Skan		    }
686169695Skan		}
687169695Skan#endif
688169695Skan	    }
689169695Skan	}
690169695Skan    }
691169695Skan  if (pid < 0)
692169695Skan    errno = save_errno;
693169695Skan  return pid;
694169695Skan}
695169695Skan
696169695Skan/* Execute a child.  */
697169695Skan
698169695Skanstatic long
699169695Skanpex_win32_exec_child (struct pex_obj *obj ATTRIBUTE_UNUSED, int flags,
700169695Skan		      const char *executable, char * const * argv,
701169695Skan                      char* const* env,
702169695Skan		      int in, int out, int errdes,
703169695Skan		      int toclose ATTRIBUTE_UNUSED,
704169695Skan		      const char **errmsg,
705169695Skan		      int *err)
706169695Skan{
707169695Skan  long pid;
708169695Skan  HANDLE stdin_handle;
709169695Skan  HANDLE stdout_handle;
710169695Skan  HANDLE stderr_handle;
711169695Skan  DWORD dwCreationFlags;
712169695Skan  OSVERSIONINFO version_info;
713169695Skan  STARTUPINFO si;
714169695Skan  PROCESS_INFORMATION pi;
715169695Skan
716169695Skan  stdin_handle = INVALID_HANDLE_VALUE;
717169695Skan  stdout_handle = INVALID_HANDLE_VALUE;
718169695Skan  stderr_handle = INVALID_HANDLE_VALUE;
719169695Skan
720169695Skan  stdin_handle = (HANDLE) _get_osfhandle (in);
721169695Skan  stdout_handle = (HANDLE) _get_osfhandle (out);
722169695Skan  if (!(flags & PEX_STDERR_TO_STDOUT))
723169695Skan    stderr_handle = (HANDLE) _get_osfhandle (errdes);
724169695Skan  else
725169695Skan    stderr_handle = stdout_handle;
726169695Skan
727169695Skan  /* Determine the version of Windows we are running on.  */
728169695Skan  version_info.dwOSVersionInfoSize = sizeof (version_info);
729169695Skan  GetVersionEx (&version_info);
730169695Skan  if (version_info.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS)
731169695Skan    /* On Windows 95/98/ME the CREATE_NO_WINDOW flag is not
732169695Skan       supported, so we cannot avoid creating a console window.  */
733169695Skan    dwCreationFlags = 0;
734169695Skan  else
735169695Skan    {
736169695Skan      HANDLE conout_handle;
737169695Skan
738169695Skan      /* Determine whether or not we have an associated console.  */
739169695Skan      conout_handle = CreateFile("CONOUT$",
740169695Skan				 GENERIC_WRITE,
741169695Skan				 FILE_SHARE_WRITE,
742169695Skan				 /*lpSecurityAttributes=*/NULL,
743169695Skan				 OPEN_EXISTING,
744169695Skan				 FILE_ATTRIBUTE_NORMAL,
745169695Skan				 /*hTemplateFile=*/NULL);
746169695Skan      if (conout_handle == INVALID_HANDLE_VALUE)
747169695Skan	/* There is no console associated with this process.  Since
748169695Skan	   the child is a console process, the OS would normally
749169695Skan	   create a new console Window for the child.  Since we'll be
750169695Skan	   redirecting the child's standard streams, we do not need
751169695Skan	   the console window.  */
752169695Skan	dwCreationFlags = CREATE_NO_WINDOW;
753169695Skan      else
754169695Skan	{
755169695Skan	  /* There is a console associated with the process, so the OS
756169695Skan	     will not create a new console.  And, if we use
757169695Skan	     CREATE_NO_WINDOW in this situation, the child will have
758169695Skan	     no associated console.  Therefore, if the child's
759169695Skan	     standard streams are connected to the console, the output
760169695Skan	     will be discarded.  */
761169695Skan	  CloseHandle(conout_handle);
762169695Skan	  dwCreationFlags = 0;
763169695Skan	}
764169695Skan    }
765169695Skan
766169695Skan  /* Since the child will be a console process, it will, by default,
767169695Skan     connect standard input/output to its console.  However, we want
768169695Skan     the child to use the handles specifically designated above.  In
769169695Skan     addition, if there is no console (such as when we are running in
770169695Skan     a Cygwin X window), then we must redirect the child's
771169695Skan     input/output, as there is no console for the child to use.  */
772169695Skan  memset (&si, 0, sizeof (si));
773169695Skan  si.cb = sizeof (si);
774169695Skan  si.dwFlags = STARTF_USESTDHANDLES;
775169695Skan  si.hStdInput = stdin_handle;
776169695Skan  si.hStdOutput = stdout_handle;
777169695Skan  si.hStdError = stderr_handle;
778169695Skan
779169695Skan  /* Create the child process.  */
780169695Skan  pid = win32_spawn (executable, (flags & PEX_SEARCH) != 0,
781169695Skan		     argv, env, dwCreationFlags, &si, &pi);
782169695Skan  if (pid == -1)
783169695Skan    pid = spawn_script (executable, argv, env, dwCreationFlags,
784169695Skan                        &si, &pi);
785169695Skan  if (pid == -1)
786169695Skan    {
787169695Skan      *err = ENOENT;
788169695Skan      *errmsg = "CreateProcess";
789169695Skan    }
790169695Skan
791169695Skan  /* Close the standard output and standard error handles in the
792169695Skan     parent.  */
793169695Skan  if (out != STDOUT_FILENO)
794169695Skan    obj->funcs->close (obj, out);
795169695Skan  if (errdes != STDERR_FILENO)
796169695Skan    obj->funcs->close (obj, errdes);
797169695Skan
798169695Skan  return pid;
799169695Skan}
800169695Skan
801169695Skan/* Wait for a child process to complete.  MS CRTDLL doesn't return
802169695Skan   enough information in status to decide if the child exited due to a
803169695Skan   signal or not, rather it simply returns an integer with the exit
804169695Skan   code of the child; eg., if the child exited with an abort() call
805169695Skan   and didn't have a handler for SIGABRT, it simply returns with
806169695Skan   status == 3.  We fix the status code to conform to the usual WIF*
807169695Skan   macros.  Note that WIFSIGNALED will never be true under CRTDLL. */
808169695Skan
809169695Skanstatic int
810169695Skanpex_win32_wait (struct pex_obj *obj ATTRIBUTE_UNUSED, long pid,
811169695Skan		int *status, struct pex_time *time, int done ATTRIBUTE_UNUSED,
812169695Skan		const char **errmsg, int *err)
813169695Skan{
814169695Skan  DWORD termstat;
815169695Skan  HANDLE h;
816169695Skan
817169695Skan  if (time != NULL)
818169695Skan    memset (time, 0, sizeof *time);
819169695Skan
820169695Skan  h = (HANDLE) pid;
821169695Skan
822169695Skan  /* FIXME: If done is non-zero, we should probably try to kill the
823169695Skan     process.  */
824169695Skan  if (WaitForSingleObject (h, INFINITE) != WAIT_OBJECT_0)
825169695Skan    {
826169695Skan      CloseHandle (h);
827169695Skan      *err = ECHILD;
828169695Skan      *errmsg = "WaitForSingleObject";
829169695Skan      return -1;
830169695Skan    }
831169695Skan
832169695Skan  GetExitCodeProcess (h, &termstat);
833169695Skan  CloseHandle (h);
834169695Skan
835169695Skan  /* A value of 3 indicates that the child caught a signal, but not
836169695Skan     which one.  Since only SIGABRT, SIGFPE and SIGINT do anything, we
837169695Skan     report SIGABRT.  */
838169695Skan  if (termstat == 3)
839169695Skan    *status = SIGABRT;
840169695Skan  else
841169695Skan    *status = (termstat & 0xff) << 8;
842169695Skan
843169695Skan  return 0;
844169695Skan}
845169695Skan
846169695Skan/* Create a pipe.  */
847169695Skan
848169695Skanstatic int
849169695Skanpex_win32_pipe (struct pex_obj *obj ATTRIBUTE_UNUSED, int *p,
850169695Skan		int binary)
851169695Skan{
852169695Skan  return _pipe (p, 256, binary ? _O_BINARY : _O_TEXT);
853169695Skan}
854169695Skan
855169695Skan/* Get a FILE pointer to read from a file descriptor.  */
856169695Skan
857169695Skanstatic FILE *
858169695Skanpex_win32_fdopenr (struct pex_obj *obj ATTRIBUTE_UNUSED, int fd,
859169695Skan		   int binary)
860169695Skan{
861169695Skan  return fdopen (fd, binary ? "rb" : "r");
862169695Skan}
863169695Skan
864169695Skanstatic FILE *
865169695Skanpex_win32_fdopenw (struct pex_obj *obj ATTRIBUTE_UNUSED, int fd,
866169695Skan		   int binary)
867169695Skan{
868169695Skan  HANDLE h = (HANDLE) _get_osfhandle (fd);
869169695Skan  if (h == INVALID_HANDLE_VALUE)
870169695Skan    return NULL;
871169695Skan  if (! SetHandleInformation (h, HANDLE_FLAG_INHERIT, 0))
872169695Skan    return NULL;
873169695Skan  return fdopen (fd, binary ? "wb" : "w");
874169695Skan}
875169695Skan
876169695Skan#ifdef MAIN
877169695Skan#include <stdio.h>
878169695Skan
879169695Skanint
880169695Skanmain (int argc ATTRIBUTE_UNUSED, char **argv)
881169695Skan{
882169695Skan  char const *errmsg;
883169695Skan  int err;
884169695Skan  argv++;
885169695Skan  printf ("%ld\n", pex_win32_exec_child (NULL, PEX_SEARCH, argv[0], argv, NULL, 0, 0, 1, 2, &errmsg, &err));
886169695Skan  exit (0);
887169695Skan}
888169695Skan#endif
889