<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.
This commit is contained in:
Eli Zaretskii 2009-03-14 14:42:06 +00:00
parent 656b15a404
commit 27ef86f6b1
2 changed files with 71 additions and 47 deletions

View File

@ -1,3 +1,15 @@
2009-03-14 Eli Zaretskii <eliz@gnu.org>
* w32/subproc/sub_proc.c <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.
2009-03-07 Eli Zaretskii <eliz@gnu.org> 2009-03-07 Eli Zaretskii <eliz@gnu.org>
* function.c (func_shell): Don't close pipedes[1] if it is -1. * function.c (func_shell): Don't close pipedes[1] if it is -1.

View File

@ -1,6 +1,6 @@
/* Process handling for Windows. /* Process handling for Windows.
Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 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. This file is part of GNU Make.
GNU Make is free software; you can redistribute it and/or modify it under the 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" #include "debug.h"
static char *make_command_line(char *shell_name, char *exec_path, char **argv); static char *make_command_line(char *shell_name, char *exec_path, char **argv);
extern char *xmalloc (unsigned int);
typedef struct sub_process_t { typedef struct sub_process_t {
int sv_stdin[2]; int sv_stdin[2];
@ -347,53 +348,54 @@ process_init_fd(HANDLE stdinh, HANDLE stdouth, HANDLE stderrh)
static HANDLE 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; HANDLE exec_handle;
char *fname; char *fname;
char *ext; 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); strcpy(fname, exec_path);
ext = fname + strlen(fname); ext = fname + strlen(fname);
strcpy(ext, ".exe"); for (i = 0; extensions[i]; i++) {
if ((exec_handle = (HANDLE)OpenFile(fname, file_info, strcpy(ext, extensions[i]);
OF_READ | OF_SHARE_COMPAT)) != (HANDLE)HFILE_ERROR) { if (((req_len = SearchPath (path_var, fname, NULL, full_len,
free(fname); full_fname, NULL)) > 0
return(exec_handle); /* For compatibility with previous code, which
} used OpenFile, and with Windows operation in
general, also look in various default
strcpy(ext, ".cmd"); locations, such as Windows directory and
if ((exec_handle = (HANDLE)OpenFile(fname, file_info, Windows System directory. Warning: this also
OF_READ | OF_SHARE_COMPAT)) != (HANDLE)HFILE_ERROR) { searches PATH in the Make's environment, which
free(fname); might not be what the Makefile wants, but it
return(exec_handle); seems to be OK as a fallback, after the
} previous SearchPath failed to find on child's
PATH. */
strcpy(ext, ".bat"); || (req_len = SearchPath (NULL, fname, NULL, full_len,
if ((exec_handle = (HANDLE)OpenFile(fname, file_info, full_fname, NULL)) > 0)
OF_READ | OF_SHARE_COMPAT)) != (HANDLE)HFILE_ERROR) { && req_len <= full_len
free(fname); && (exec_handle =
return(exec_handle); CreateFile(full_fname,
} GENERIC_READ,
FILE_SHARE_READ | FILE_SHARE_WRITE,
/* should .com come before this case? */ NULL,
if ((exec_handle = (HANDLE)OpenFile(exec_path, file_info, OPEN_EXISTING,
OF_READ | OF_SHARE_COMPAT)) != (HANDLE)HFILE_ERROR) { FILE_ATTRIBUTE_NORMAL,
free(fname); NULL)) != INVALID_HANDLE_VALUE) {
return(exec_handle); 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);
} }
free(fname); free(fname);
return(exec_handle); return INVALID_HANDLE_VALUE;
} }
@ -416,6 +418,9 @@ process_begin(
char *shell_name = 0; char *shell_name = 0;
int file_not_found=0; int file_not_found=0;
HANDLE exec_handle; HANDLE exec_handle;
char exec_fname[MAX_PATH];
const char *path_var = NULL;
char **ep;
char buf[256]; char buf[256];
DWORD bytes_returned; DWORD bytes_returned;
DWORD flags; DWORD flags;
@ -423,8 +428,6 @@ process_begin(
STARTUPINFO startInfo; STARTUPINFO startInfo;
PROCESS_INFORMATION procInfo; PROCESS_INFORMATION procInfo;
char *envblk=NULL; char *envblk=NULL;
OFSTRUCT file_info;
/* /*
* Shell script detection... if the exec_path starts with #! then * 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 * hard-code the path to the shell or perl or whatever: Instead, we
* assume it's in the path somewhere (generally, the NT tools * assume it's in the path somewhere (generally, the NT tools
* bin directory) * 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 * If we couldn't open the file, just assume that Windows will be
* to find and execute it. * somehow able to find and execute it.
*/ */
if (exec_handle == (HANDLE)HFILE_ERROR) { if (exec_handle == INVALID_HANDLE_VALUE) {
file_not_found++; file_not_found++;
} }
else { else {
@ -496,8 +509,7 @@ process_begin(
if (file_not_found) if (file_not_found)
command_line = make_command_line( shell_name, exec_path, argv); command_line = make_command_line( shell_name, exec_path, argv);
else else
command_line = make_command_line( shell_name, file_info.szPathName, command_line = make_command_line( shell_name, exec_fname, argv);
argv);
if ( command_line == NULL ) { if ( command_line == NULL ) {
pproc->last_err = 0; pproc->last_err = 0;
@ -517,7 +529,7 @@ process_begin(
if ((shell_name) || (file_not_found)) { if ((shell_name) || (file_not_found)) {
exec_path = 0; /* Search for the program in %Path% */ exec_path = 0; /* Search for the program in %Path% */
} else { } else {
exec_path = file_info.szPathName; exec_path = exec_fname;
} }
/* /*