summaryrefslogtreecommitdiff
path: root/w32
diff options
context:
space:
mode:
authorEli Zaretskii <eliz@gnu.org>2009-03-14 14:42:06 +0000
committerEli Zaretskii <eliz@gnu.org>2009-03-14 14:42:06 +0000
commit27ef86f6b1caa78cefabc632dfbbe78bf7aa56d6 (patch)
tree632b2e294334d25ea4f208cf7720b7c4edf7101e /w32
parent656b15a40423a90ca74e3f29ea206e9bae4da5e5 (diff)
downloadgunmake-27ef86f6b1caa78cefabc632dfbbe78bf7aa56d6.tar.gz
<top level>: Update Copyright years. Add prototype for xmalloc.
(find_file): Accept 3 arguments PATH_VAR, FULL_FNAME, and FULL_LEN instead of an LPOFSTRUCT pointer. Use xmalloc instead of malloc. Loop over an array of extensions, instead of duplicating the same code inline. Use SearchPath followed by CreateFile, instead of the obsolete OpenFile. Fixes Savannah bug #17277. (process_begin): Find $(PATH) in `envp', and pass a pointer to it to `find_file'. Fixes Savannah bug #25662.
Diffstat (limited to 'w32')
-rw-r--r--w32/subproc/sub_proc.c106
1 files changed, 59 insertions, 47 deletions
diff --git a/w32/subproc/sub_proc.c b/w32/subproc/sub_proc.c
index 80dbf0a..a49ccc2 100644
--- a/w32/subproc/sub_proc.c
+++ b/w32/subproc/sub_proc.c
@@ -1,6 +1,6 @@
/* Process handling for Windows.
Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
-2006, 2007 Free Software Foundation, Inc.
+2006, 2007 2009 Free Software Foundation, Inc.
This file is part of GNU Make.
GNU Make is free software; you can redistribute it and/or modify it under the
@@ -28,6 +28,7 @@ this program. If not, see <http://www.gnu.org/licenses/>. */
#include "debug.h"
static char *make_command_line(char *shell_name, char *exec_path, char **argv);
+extern char *xmalloc (unsigned int);
typedef struct sub_process_t {
int sv_stdin[2];
@@ -347,53 +348,54 @@ process_init_fd(HANDLE stdinh, HANDLE stdouth, HANDLE stderrh)
static HANDLE
-find_file(char *exec_path, LPOFSTRUCT file_info)
+find_file(const char *exec_path, const char *path_var,
+ char *full_fname, DWORD full_len)
{
HANDLE exec_handle;
char *fname;
char *ext;
+ DWORD req_len;
+ int i;
+ static const char *extensions[] =
+ /* Should .com come before no-extension case? */
+ { ".exe", ".cmd", ".bat", "", ".com", NULL };
- fname = malloc(strlen(exec_path) + 5);
+ fname = xmalloc(strlen(exec_path) + 5);
strcpy(fname, exec_path);
ext = fname + strlen(fname);
- strcpy(ext, ".exe");
- if ((exec_handle = (HANDLE)OpenFile(fname, file_info,
- OF_READ | OF_SHARE_COMPAT)) != (HANDLE)HFILE_ERROR) {
- free(fname);
- return(exec_handle);
- }
-
- strcpy(ext, ".cmd");
- if ((exec_handle = (HANDLE)OpenFile(fname, file_info,
- OF_READ | OF_SHARE_COMPAT)) != (HANDLE)HFILE_ERROR) {
- free(fname);
- return(exec_handle);
- }
-
- strcpy(ext, ".bat");
- if ((exec_handle = (HANDLE)OpenFile(fname, file_info,
- OF_READ | OF_SHARE_COMPAT)) != (HANDLE)HFILE_ERROR) {
- free(fname);
- return(exec_handle);
- }
-
- /* should .com come before this case? */
- if ((exec_handle = (HANDLE)OpenFile(exec_path, file_info,
- OF_READ | OF_SHARE_COMPAT)) != (HANDLE)HFILE_ERROR) {
- free(fname);
- return(exec_handle);
- }
-
- strcpy(ext, ".com");
- if ((exec_handle = (HANDLE)OpenFile(fname, file_info,
- OF_READ | OF_SHARE_COMPAT)) != (HANDLE)HFILE_ERROR) {
- free(fname);
- return(exec_handle);
+ for (i = 0; extensions[i]; i++) {
+ strcpy(ext, extensions[i]);
+ if (((req_len = SearchPath (path_var, fname, NULL, full_len,
+ full_fname, NULL)) > 0
+ /* For compatibility with previous code, which
+ used OpenFile, and with Windows operation in
+ general, also look in various default
+ locations, such as Windows directory and
+ Windows System directory. Warning: this also
+ searches PATH in the Make's environment, which
+ might not be what the Makefile wants, but it
+ seems to be OK as a fallback, after the
+ previous SearchPath failed to find on child's
+ PATH. */
+ || (req_len = SearchPath (NULL, fname, NULL, full_len,
+ full_fname, NULL)) > 0)
+ && req_len <= full_len
+ && (exec_handle =
+ CreateFile(full_fname,
+ GENERIC_READ,
+ FILE_SHARE_READ | FILE_SHARE_WRITE,
+ NULL,
+ OPEN_EXISTING,
+ FILE_ATTRIBUTE_NORMAL,
+ NULL)) != INVALID_HANDLE_VALUE) {
+ free(fname);
+ return(exec_handle);
+ }
}
free(fname);
- return(exec_handle);
+ return INVALID_HANDLE_VALUE;
}
@@ -416,6 +418,9 @@ process_begin(
char *shell_name = 0;
int file_not_found=0;
HANDLE exec_handle;
+ char exec_fname[MAX_PATH];
+ const char *path_var = NULL;
+ char **ep;
char buf[256];
DWORD bytes_returned;
DWORD flags;
@@ -423,8 +428,6 @@ process_begin(
STARTUPINFO startInfo;
PROCESS_INFORMATION procInfo;
char *envblk=NULL;
- OFSTRUCT file_info;
-
/*
* Shell script detection... if the exec_path starts with #! then
@@ -433,16 +436,26 @@ process_begin(
* hard-code the path to the shell or perl or whatever: Instead, we
* assume it's in the path somewhere (generally, the NT tools
* bin directory)
- * We use OpenFile here because it is capable of searching the Path.
*/
- exec_handle = find_file(exec_path, &file_info);
+ /* Use the Makefile's value of PATH to look for the program to
+ execute, because it could be different from Make's PATH
+ (e.g., if the target sets its own value. */
+ for (ep = envp; ep; ep++) {
+ if (strncmp (*ep, "PATH=", 5) == 0
+ || strncmp (*ep, "Path=", 5) == 0) {
+ path_var = *ep + 5;
+ break;
+ }
+ }
+ exec_handle = find_file(exec_path, path_var,
+ exec_fname, sizeof(exec_fname));
/*
- * If we couldn't open the file, just assume that Windows32 will be able
- * to find and execute it.
+ * If we couldn't open the file, just assume that Windows will be
+ * somehow able to find and execute it.
*/
- if (exec_handle == (HANDLE)HFILE_ERROR) {
+ if (exec_handle == INVALID_HANDLE_VALUE) {
file_not_found++;
}
else {
@@ -496,8 +509,7 @@ process_begin(
if (file_not_found)
command_line = make_command_line( shell_name, exec_path, argv);
else
- command_line = make_command_line( shell_name, file_info.szPathName,
- argv);
+ command_line = make_command_line( shell_name, exec_fname, argv);
if ( command_line == NULL ) {
pproc->last_err = 0;
@@ -517,7 +529,7 @@ process_begin(
if ((shell_name) || (file_not_found)) {
exec_path = 0; /* Search for the program in %Path% */
} else {
- exec_path = file_info.szPathName;
+ exec_path = exec_fname;
}
/*