1 /* Utilities to execute a program in a subprocess (possibly linked by pipes
2 with other subprocesses), and wait for it. Generic Win32 specialization.
3 Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, 2006
4 Free Software Foundation, Inc.
6 This file is part of the libiberty library.
7 Libiberty is free software; you can redistribute it and/or
8 modify it under the terms of the GNU Library General Public
9 License as published by the Free Software Foundation; either
10 version 2 of the License, or (at your option) any later version.
12 Libiberty is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 Library General Public License for more details.
17 You should have received a copy of the GNU Library General Public
18 License along with libiberty; see the file COPYING.LIB. If not,
19 write to the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor,
20 Boston, MA 02110-1301, USA. */
22 #include "pex-common.h"
35 #ifdef HAVE_SYS_WAIT_H
48 /* mingw32 headers may not define the following. */
58 # define WAIT_GRANDCHILD 1
61 #define MINGW_NAME "Minimalist GNU for Windows"
62 #define MINGW_NAME_LEN (sizeof(MINGW_NAME) - 1)
64 extern char *stpcpy (char *dst
, const char *src
);
66 /* Ensure that the executable pathname uses Win32 backslashes. This
67 is not necessary on NT, but on W9x, forward slashes causes
68 failure of spawn* and exec* functions (and probably any function
69 that calls CreateProcess) *iff* the executable pathname (argv[0])
70 is a quoted string. And quoting is necessary in case a pathname
71 contains embedded white space. You can't win. */
73 backslashify (char *s
)
75 while ((s
= strchr (s
, '/')) != NULL
)
80 static int pex_win32_open_read (struct pex_obj
*, const char *, int);
81 static int pex_win32_open_write (struct pex_obj
*, const char *, int);
82 static pid_t
pex_win32_exec_child (struct pex_obj
*, int, const char *,
83 char * const *, char * const *,
85 const char **, int *);
86 static int pex_win32_close (struct pex_obj
*, int);
87 static pid_t
pex_win32_wait (struct pex_obj
*, pid_t
, int *,
88 struct pex_time
*, int, const char **, int *);
89 static int pex_win32_pipe (struct pex_obj
*, int *, int);
90 static FILE *pex_win32_fdopenr (struct pex_obj
*, int, int);
91 static FILE *pex_win32_fdopenw (struct pex_obj
*, int, int);
93 /* The list of functions we pass to the common routines. */
95 const struct pex_funcs funcs
=
108 /* Return a newly initialized pex_obj structure. */
111 pex_init (int flags
, const char *pname
, const char *tempbase
)
113 return pex_init_common (flags
, pname
, tempbase
, &funcs
);
116 /* Open a file for reading. */
119 pex_win32_open_read (struct pex_obj
*obj ATTRIBUTE_UNUSED
, const char *name
,
122 return _open (name
, _O_RDONLY
| (binary
? _O_BINARY
: _O_TEXT
));
125 /* Open a file for writing. */
128 pex_win32_open_write (struct pex_obj
*obj ATTRIBUTE_UNUSED
, const char *name
,
131 /* Note that we can't use O_EXCL here because gcc may have already
132 created the temporary file via make_temp_file. */
134 (_O_WRONLY
| _O_CREAT
| _O_TRUNC
135 | (binary
? _O_BINARY
: _O_TEXT
)),
136 _S_IREAD
| _S_IWRITE
);
142 pex_win32_close (struct pex_obj
*obj ATTRIBUTE_UNUSED
, int fd
)
147 #ifdef USE_MINGW_MSYS
148 static const char *mingw_keys
[] = {"SOFTWARE", "Microsoft", "Windows", "CurrentVersion", "Uninstall", NULL
};
150 /* Tack the executable on the end of a (possibly slash terminated) buffer
151 and convert everything to \. */
153 tack_on_executable (char *buf
, const char *executable
)
155 char *p
= strchr (buf
, '\0');
156 if (p
> buf
&& (p
[-1] == '\\' || p
[-1] == '/'))
158 backslashify (strcat (buf
, executable
));
162 /* Walk down a registry hierarchy until the end. Return the key. */
164 openkey (HKEY hStart
, const char *keys
[])
167 for (hKey
= hStart
; *keys
; keys
++)
171 res
= RegOpenKey (hTmp
, *keys
, &hKey
);
173 if (hTmp
!= HKEY_LOCAL_MACHINE
)
176 if (res
!= ERROR_SUCCESS
)
182 /* Return the "mingw root" as derived from the mingw uninstall information. */
184 mingw_rootify (const char *executable
)
188 char *namebuf
, *foundbuf
;
192 /* Open the uninstall "directory". */
193 hKey
= openkey (HKEY_LOCAL_MACHINE
, mingw_keys
);
199 /* Need to enumerate all of the keys here looking for one the most recent
201 if (RegQueryInfoKey (hKey
, NULL
, NULL
, NULL
, NULL
, &maxlen
, NULL
, NULL
,
202 NULL
, NULL
, NULL
, NULL
) != ERROR_SUCCESS
)
207 namebuf
= XNEWVEC (char, ++maxlen
);
208 foundbuf
= XNEWVEC (char, maxlen
);
210 if (!namebuf
|| !foundbuf
)
218 /* Look through all of the keys for one that begins with Minimal GNU...
219 Try to get the latest version by doing a string compare although that
220 string never really works with version number sorting. */
221 for (i
= 0; RegEnumKey (hKey
, i
, namebuf
, maxlen
) == ERROR_SUCCESS
; i
++)
223 int match
= strcasecmp (namebuf
, MINGW_NAME
);
226 if (match
> 0 && strncasecmp (namebuf
, MINGW_NAME
, MINGW_NAME_LEN
) > 0)
228 if (strcasecmp (namebuf
, foundbuf
) > 0)
229 strcpy (foundbuf
, namebuf
);
233 /* If foundbuf is empty, we didn't find anything. Punt. */
241 /* Open the key that we wanted */
242 res
= RegOpenKey (hKey
, foundbuf
, &hTmp
);
246 /* Don't know why this would fail, but you gotta check */
247 if (res
!= ERROR_SUCCESS
)
251 /* Get the length of the value pointed to by InstallLocation */
252 if (RegQueryValueEx (hTmp
, "InstallLocation", 0, NULL
, NULL
,
253 &maxlen
) != ERROR_SUCCESS
|| maxlen
== 0)
259 /* Allocate space for the install location */
260 foundbuf
= XNEWVEC (char, maxlen
+ strlen (executable
));
267 /* Read the install location into the buffer */
268 res
= RegQueryValueEx (hTmp
, "InstallLocation", 0, NULL
, (LPBYTE
) foundbuf
,
271 if (res
!= ERROR_SUCCESS
)
277 /* Concatenate the install location and the executable, turn all slashes
278 to backslashes, and return that. */
279 return tack_on_executable (foundbuf
, executable
);
282 /* Read the install location of msys from it's installation file and
283 rootify the executable based on that. */
285 msys_rootify (const char *executable
)
288 size_t execlen
= strlen (executable
) + 1;
293 buf
= XNEWVEC (char, bufsize
+ execlen
);
296 res
= GetPrivateProfileString ("InstallSettings", "InstallPath", NULL
,
297 buf
, bufsize
, "msys.ini");
300 if (strlen (buf
) < bufsize
)
313 return tack_on_executable (buf
, executable
);
321 /* Return the number of arguments in an argv array, not including the null
322 terminating argument. */
325 argv_to_argc (char *const *argv
)
327 char *const *i
= argv
;
333 /* Return a Windows command-line from ARGV. It is the caller's
334 responsibility to free the string returned. */
337 argv_to_cmdline (char *const *argv
)
345 for (i
= 0; argv
[i
]; i
++)
347 /* We quote every last argument. This simplifies the problem;
348 we need only escape embedded double-quotes and immediately
349 preceeding backslash characters. A sequence of backslach characters
350 that is not follwed by a double quote character will not be
352 for (j
= 0; argv
[i
][j
]; j
++)
354 if (argv
[i
][j
] == '"')
356 /* Escape preceeding backslashes. */
357 for (k
= j
- 1; k
>= 0 && argv
[i
][k
] == '\\'; k
--)
359 /* Escape the qote character. */
363 /* Trailing backslashes also need to be escaped because they will be
364 followed by the terminating quote. */
365 for (k
= j
- 1; k
>= 0 && argv
[i
][k
] == '\\'; k
--)
368 cmdline_len
+= 3; /* for leading and trailing quotes and space */
370 cmdline
= XNEWVEC (char, cmdline_len
);
372 for (i
= 0; argv
[i
]; i
++)
375 for (j
= 0; argv
[i
][j
]; j
++)
377 if (argv
[i
][j
] == '"')
379 for (k
= j
- 1; k
>= 0 && argv
[i
][k
] == '\\'; k
--)
385 for (k
= j
- 1; k
>= 0 && argv
[i
][k
] == '\\'; k
--)
394 /* We'll try the passed filename with all the known standard
395 extensions, and then without extension. We try no extension
396 last so that we don't try to run some random extension-less
397 file that might be hanging around. We try both extension
398 and no extension so that we don't need any fancy logic
399 to determine if a file has extension. */
400 static const char *const
410 /* Returns the full path to PROGRAM. If SEARCH is true, look for
411 PROGRAM in each directory in PATH. */
414 find_executable (const char *program
, BOOL search
)
416 char *full_executable
;
419 const char *path
= 0;
420 const char *const *ext
;
422 size_t proglen
= strlen (program
);
423 int has_slash
= (strchr (program
, '/') || strchr (program
, '\\'));
430 path
= getenv ("PATH");
435 for (p
= path
; *p
; p
= q
)
438 while (*q
!= ';' && *q
!= '\0')
440 if ((size_t)(q
- p
) > fe_len
)
445 fe_len
= fe_len
+ 1 + proglen
+ 5 /* space for extension */;
446 full_executable
= XNEWVEC (char, fe_len
);
452 while (*q
!= ';' && *q
!= '\0')
456 memcpy (e
, p
, q
- p
);
465 for (e
= full_executable
; *e
; e
++)
469 /* At this point, e points to the terminating NUL character for
471 for (ext
= std_suffixes
; *ext
; ext
++)
473 /* Remove any current extension. */
475 /* Add the new one. */
476 strcat (full_executable
, *ext
);
478 /* Attempt to open this file. */
479 h
= CreateFile (full_executable
, GENERIC_READ
,
480 FILE_SHARE_READ
| FILE_SHARE_WRITE
,
481 0, OPEN_EXISTING
, FILE_ATTRIBUTE_NORMAL
, 0);
482 if (h
!= INVALID_HANDLE_VALUE
)
488 free (full_executable
);
493 return full_executable
;
496 /* Low-level process creation function and helper. */
499 env_compare (const void *a_ptr
, const void *b_ptr
)
506 a
= *(const char **) a_ptr
;
507 b
= *(const char **) b_ptr
;
509 /* a and b will be of the form: VAR=VALUE
510 We compare only the variable name part here using a case-insensitive
511 comparison algorithm. It might appear that in fact strcasecmp () can
512 take the place of this whole function, and indeed it could, save for
513 the fact that it would fail in cases such as comparing A1=foo and
514 A=bar (because 1 is less than = in the ASCII character set).
515 (Environment variables containing no numbers would work in such a
520 c1
= (unsigned char) tolower (*a
++);
521 c2
= (unsigned char) tolower (*b
++);
529 while (c1
== c2
&& c1
!= '\0');
534 /* Execute a Windows executable as a child process. This will fail if the
535 * target is not actually an executable, such as if it is a shell script. */
538 win32_spawn (const char *executable
,
541 char *const *env
, /* array of strings of the form: VAR=VALUE */
542 DWORD dwCreationFlags
,
544 LPPROCESS_INFORMATION pi
)
546 char *full_executable
;
549 char *env_block
= NULL
;
551 full_executable
= NULL
;
558 /* Count the number of environment bindings supplied. */
559 for (env_size
= 0; env
[env_size
]; env_size
++)
562 /* Assemble an environment block, if required. This consists of
563 VAR=VALUE strings juxtaposed (with one null character between each
564 pair) and an additional null at the end. */
568 int total_size
= 1; /* 1 is for the final null. */
571 /* Windows needs the members of the block to be sorted by variable
573 env_copy
= (char **) alloca (sizeof (char *) * env_size
);
574 memcpy (env_copy
, env
, sizeof (char *) * env_size
);
575 qsort (env_copy
, env_size
, sizeof (char *), env_compare
);
577 for (var
= 0; var
< env_size
; var
++)
578 total_size
+= strlen (env
[var
]) + 1;
580 env_block
= XNEWVEC (char, total_size
);
582 for (var
= 0; var
< env_size
; var
++)
583 bufptr
= stpcpy (bufptr
, env_copy
[var
]) + 1;
589 full_executable
= find_executable (executable
, search
);
590 if (!full_executable
)
592 cmdline
= argv_to_cmdline (argv
);
596 /* Create the child process. */
597 if (!CreateProcess (full_executable
, cmdline
,
598 /*lpProcessAttributes=*/NULL
,
599 /*lpThreadAttributes=*/NULL
,
600 /*bInheritHandles=*/TRUE
,
603 /*lpCurrentDirectory=*/NULL
,
609 free (full_executable
);
615 CloseHandle (pi
->hThread
);
616 free (full_executable
);
619 return (pid_t
) pi
->hProcess
;
624 free (full_executable
);
629 /* Spawn a script. This simulates the Unix script execution mechanism.
630 This function is called as a fallback if win32_spawn fails. */
633 spawn_script (const char *executable
, char *const *argv
,
635 DWORD dwCreationFlags
,
637 LPPROCESS_INFORMATION pi
)
639 pid_t pid
= (pid_t
) -1;
640 int save_errno
= errno
;
641 int fd
= _open (executable
, _O_RDONLY
);
643 /* Try to open script, check header format, extract interpreter path,
644 and spawn script using that interpretter. */
647 char buf
[MAX_PATH
+ 5];
648 int len
= _read (fd
, buf
, sizeof (buf
) - 1);
654 eol
= strchr (buf
, '\n');
655 if (eol
&& strncmp (buf
, "#!", 2) == 0)
658 /* Header format is OK. */
663 /* Extract interpreter path. */
666 while (*--eol
== '\r' || *eol
== ' ' || *eol
== '\t');
667 for (executable1
= buf
+ 2; *executable1
== ' ' || *executable1
== '\t'; executable1
++)
669 backslashify (executable1
);
671 /* Duplicate argv, prepending the interpreter path. */
672 new_argc
= argv_to_argc (argv
) + 1;
673 avhere
= XNEWVEC (const char *, new_argc
+ 1);
674 *avhere
= executable1
;
675 memcpy (avhere
+ 1, argv
, new_argc
* sizeof(*argv
));
676 argv
= (char *const *)avhere
;
678 /* Spawn the child. */
679 #ifndef USE_MINGW_MSYS
680 executable
= strrchr (executable1
, '\\') + 1;
682 executable
= executable1
;
683 pid
= win32_spawn (executable
, TRUE
, argv
, env
,
684 dwCreationFlags
, si
, pi
);
686 if (strchr (executable1
, '\\') == NULL
)
687 pid
= win32_spawn (executable1
, TRUE
, argv
, env
,
688 dwCreationFlags
, si
, pi
);
689 else if (executable1
[0] != '\\')
690 pid
= win32_spawn (executable1
, FALSE
, argv
, env
,
691 dwCreationFlags
, si
, pi
);
694 const char *newex
= mingw_rootify (executable1
);
696 pid
= win32_spawn (newex
, FALSE
, argv
, env
,
697 dwCreationFlags
, si
, pi
);
698 if (executable1
!= newex
)
699 free ((char *) newex
);
700 if (pid
== (pid_t
) -1)
702 newex
= msys_rootify (executable1
);
703 if (newex
!= executable1
)
706 pid
= win32_spawn (newex
, FALSE
, argv
, env
,
707 dwCreationFlags
, si
, pi
);
708 free ((char *) newex
);
717 if (pid
== (pid_t
) -1)
722 /* Execute a child. */
725 pex_win32_exec_child (struct pex_obj
*obj ATTRIBUTE_UNUSED
, int flags
,
726 const char *executable
, char * const * argv
,
728 int in
, int out
, int errdes
,
729 int toclose ATTRIBUTE_UNUSED
,
735 HANDLE stdout_handle
;
736 HANDLE stderr_handle
;
737 DWORD dwCreationFlags
;
738 OSVERSIONINFO version_info
;
740 PROCESS_INFORMATION pi
;
741 int orig_out
, orig_in
, orig_err
;
742 BOOL separate_stderr
= !(flags
& PEX_STDERR_TO_STDOUT
);
744 /* Ensure we have inheritable descriptors to pass to the child, and close the
745 original descriptors. */
748 if (orig_in
!= STDIN_FILENO
)
752 out
= _dup (orig_out
);
753 if (orig_out
!= STDOUT_FILENO
)
759 errdes
= _dup (orig_err
);
760 if (orig_err
!= STDERR_FILENO
)
764 stdin_handle
= INVALID_HANDLE_VALUE
;
765 stdout_handle
= INVALID_HANDLE_VALUE
;
766 stderr_handle
= INVALID_HANDLE_VALUE
;
768 stdin_handle
= (HANDLE
) _get_osfhandle (in
);
769 stdout_handle
= (HANDLE
) _get_osfhandle (out
);
771 stderr_handle
= (HANDLE
) _get_osfhandle (errdes
);
773 stderr_handle
= stdout_handle
;
775 /* Determine the version of Windows we are running on. */
776 version_info
.dwOSVersionInfoSize
= sizeof (version_info
);
777 GetVersionEx (&version_info
);
778 if (version_info
.dwPlatformId
== VER_PLATFORM_WIN32_WINDOWS
)
779 /* On Windows 95/98/ME the CREATE_NO_WINDOW flag is not
780 supported, so we cannot avoid creating a console window. */
784 HANDLE conout_handle
;
786 /* Determine whether or not we have an associated console. */
787 conout_handle
= CreateFile("CONOUT$",
790 /*lpSecurityAttributes=*/NULL
,
792 FILE_ATTRIBUTE_NORMAL
,
793 /*hTemplateFile=*/NULL
);
794 if (conout_handle
== INVALID_HANDLE_VALUE
)
795 /* There is no console associated with this process. Since
796 the child is a console process, the OS would normally
797 create a new console Window for the child. Since we'll be
798 redirecting the child's standard streams, we do not need
799 the console window. */
800 dwCreationFlags
= CREATE_NO_WINDOW
;
803 /* There is a console associated with the process, so the OS
804 will not create a new console. And, if we use
805 CREATE_NO_WINDOW in this situation, the child will have
806 no associated console. Therefore, if the child's
807 standard streams are connected to the console, the output
808 will be discarded. */
809 CloseHandle(conout_handle
);
814 /* Since the child will be a console process, it will, by default,
815 connect standard input/output to its console. However, we want
816 the child to use the handles specifically designated above. In
817 addition, if there is no console (such as when we are running in
818 a Cygwin X window), then we must redirect the child's
819 input/output, as there is no console for the child to use. */
820 memset (&si
, 0, sizeof (si
));
822 si
.dwFlags
= STARTF_USESTDHANDLES
;
823 si
.hStdInput
= stdin_handle
;
824 si
.hStdOutput
= stdout_handle
;
825 si
.hStdError
= stderr_handle
;
827 /* Create the child process. */
828 pid
= win32_spawn (executable
, (flags
& PEX_SEARCH
) != 0,
829 argv
, env
, dwCreationFlags
, &si
, &pi
);
830 if (pid
== (pid_t
) -1)
831 pid
= spawn_script (executable
, argv
, env
, dwCreationFlags
,
833 if (pid
== (pid_t
) -1)
836 *errmsg
= "CreateProcess";
839 /* Close the standard input, standard output and standard error handles
850 /* Wait for a child process to complete. MS CRTDLL doesn't return
851 enough information in status to decide if the child exited due to a
852 signal or not, rather it simply returns an integer with the exit
853 code of the child; eg., if the child exited with an abort() call
854 and didn't have a handler for SIGABRT, it simply returns with
855 status == 3. We fix the status code to conform to the usual WIF*
856 macros. Note that WIFSIGNALED will never be true under CRTDLL. */
859 pex_win32_wait (struct pex_obj
*obj ATTRIBUTE_UNUSED
, pid_t pid
,
860 int *status
, struct pex_time
*time
, int done ATTRIBUTE_UNUSED
,
861 const char **errmsg
, int *err
)
867 memset (time
, 0, sizeof *time
);
871 /* FIXME: If done is non-zero, we should probably try to kill the
873 if (WaitForSingleObject (h
, INFINITE
) != WAIT_OBJECT_0
)
877 *errmsg
= "WaitForSingleObject";
881 GetExitCodeProcess (h
, &termstat
);
884 /* A value of 3 indicates that the child caught a signal, but not
885 which one. Since only SIGABRT, SIGFPE and SIGINT do anything, we
890 *status
= (termstat
& 0xff) << 8;
898 pex_win32_pipe (struct pex_obj
*obj ATTRIBUTE_UNUSED
, int *p
,
901 return _pipe (p
, 256, (binary
? _O_BINARY
: _O_TEXT
) | _O_NOINHERIT
);
904 /* Get a FILE pointer to read from a file descriptor. */
907 pex_win32_fdopenr (struct pex_obj
*obj ATTRIBUTE_UNUSED
, int fd
,
910 HANDLE h
= (HANDLE
) _get_osfhandle (fd
);
911 if (h
== INVALID_HANDLE_VALUE
)
913 if (! SetHandleInformation (h
, HANDLE_FLAG_INHERIT
, 0))
915 return fdopen (fd
, binary
? "rb" : "r");
919 pex_win32_fdopenw (struct pex_obj
*obj ATTRIBUTE_UNUSED
, int fd
,
922 HANDLE h
= (HANDLE
) _get_osfhandle (fd
);
923 if (h
== INVALID_HANDLE_VALUE
)
925 if (! SetHandleInformation (h
, HANDLE_FLAG_INHERIT
, 0))
927 return fdopen (fd
, binary
? "wb" : "w");
934 main (int argc ATTRIBUTE_UNUSED
, char **argv
)
939 printf ("%ld\n", (long) pex_win32_exec_child (NULL
, PEX_SEARCH
, argv
[0], argv
, NULL
, 0, 0, 1, 2, &errmsg
, &err
));