diff options
Diffstat (limited to 'winsup/cygwin/spawn.cc')
-rw-r--r-- | winsup/cygwin/spawn.cc | 114 |
1 files changed, 37 insertions, 77 deletions
diff --git a/winsup/cygwin/spawn.cc b/winsup/cygwin/spawn.cc index a0686c5d8..f8fb1bbe5 100644 --- a/winsup/cygwin/spawn.cc +++ b/winsup/cygwin/spawn.cc @@ -1,7 +1,7 @@ /* spawn.cc Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, - 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014 Red Hat, Inc. + 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015 Red Hat, Inc. This file is part of Cygwin. @@ -53,7 +53,7 @@ perhaps_suffix (const char *prog, path_conv& buf, int& err, unsigned opt) err = 0; debug_printf ("prog '%s'", prog); - buf.check (prog, PC_SYM_FOLLOW | PC_NULLEMPTY, + buf.check (prog, PC_SYM_FOLLOW | PC_NULLEMPTY | PC_POSIX, (opt & FE_DLL) ? stat_suffixes : exe_suffixes); if (buf.isdir ()) @@ -75,124 +75,86 @@ perhaps_suffix (const char *prog, path_conv& buf, int& err, unsigned opt) return ext; } -/* Find an executable name, possibly by appending known executable - suffixes to it. The win32-translated name is placed in 'buf'. - Any found suffix is returned in known_suffix. - - If the file is not found and !null_if_not_found then the win32 version - of name is placed in buf and returned. Otherwise the contents of buf - is undefined and NULL is returned. */ +/* Find an executable name, possibly by appending known executable suffixes + to it. The path_conv struct 'buf' is filled and contains both, win32 and + posix path of the file.. Any found suffix is returned in known_suffix. + If the file is not found and !FE_NNF then the win32 version of name is + placed in buf and returned. Otherwise the contents of buf is undefined + and NULL is returned. */ const char * __reg3 -find_exec (const char *name, path_conv& buf, const char *mywinenv, +find_exec (const char *name, path_conv& buf, const char *search, unsigned opt, const char **known_suffix) { const char *suffix = ""; - debug_printf ("find_exec (%s)", name); - const char *retval; + const char *retval = NULL; tmp_pathbuf tp; + char *tmp_path; char *tmp = tp.c_get (); - const char *posix = (opt & FE_NATIVE) ? NULL : name; bool has_slash = !!strpbrk (name, "/\\"); int err = 0; - /* Check to see if file can be opened as is first. - Win32 systems always check . first, but PATH may not be set up to - do this. */ + debug_printf ("find_exec (%s)", name); + + /* Check to see if file can be opened as is first. */ if ((has_slash || opt & FE_CWD) && (suffix = perhaps_suffix (name, buf, err, opt)) != NULL) { - if (posix && !has_slash) - { - tmp[0] = '.'; - tmp[1] = '/'; - strcpy (tmp + 2, name); - posix = tmp; - } retval = buf.get_win32 (); goto out; } - win_env *winpath; const char *path; - const char *posix_path; - - posix = (opt & FE_NATIVE) ? NULL : tmp; - - if (strchr (mywinenv, '/')) - { - /* it's not really an environment variable at all */ - int n = cygwin_conv_path_list (CCP_POSIX_TO_WIN_A, mywinenv, NULL, 0); - char *s = (char *) alloca (n); - if (cygwin_conv_path_list (CCP_POSIX_TO_WIN_A, mywinenv, s, n)) - goto errout; - path = s; - posix_path = mywinenv - 1; - } - else if (has_slash || strchr (name, '\\') || isdrive (name) - || !(winpath = getwinenv (mywinenv)) - || !(path = winpath->get_native ()) || *path == '\0') - /* Return the error condition if this is an absolute path or if there - is no PATH to search. */ + /* If it starts with a slash, it's a PATH-like pathlist. Otherwise it's + the name of an environment variable. */ + if (strchr (search, '/')) + *stpncpy (tmp, search, NT_MAX_PATH - 1) = '\0'; + else if (has_slash || isdrive (name) || !(path = getenv (search)) || !*path) goto errout; else - posix_path = winpath->get_posix () - 1; + *stpncpy (tmp, path, NT_MAX_PATH - 1) = '\0'; - debug_printf ("%s%s", mywinenv, path); - /* Iterate over the specified path, looking for the file with and without - executable extensions. */ + path = tmp; + debug_printf ("searchpath %s", path); + + tmp_path = tp.c_get (); do { - posix_path++; - char *eotmp = strccpy (tmp, &path, ';'); + char *eotmp = strccpy (tmp_path, &path, ':'); /* An empty path or '.' means the current directory, but we've already tried that. */ - if (opt & FE_CWD && (tmp[0] == '\0' || (tmp[0] == '.' && tmp[1] == '\0'))) + if ((opt & FE_CWD) && (tmp_path[0] == '\0' + || (tmp_path[0] == '.' && tmp_path[1] == '\0'))) continue; - *eotmp++ = '\\'; + *eotmp++ = '/'; strcpy (eotmp, name); - debug_printf ("trying %s", tmp); + debug_printf ("trying %s", tmp_path); int err1; - if ((suffix = perhaps_suffix (tmp, buf, err1, opt)) != NULL) + if ((suffix = perhaps_suffix (tmp_path, buf, err1, opt)) != NULL) { if (buf.has_acls () && check_file_access (buf, X_OK, true)) continue; - - if (posix == tmp) - { - eotmp = strccpy (tmp, &posix_path, ':'); - if (eotmp == tmp) - *eotmp++ = '.'; - *eotmp++ = '/'; - strcpy (eotmp, name); - } retval = buf.get_win32 (); goto out; } + } - while (*path && *++path && (posix_path = strchr (posix_path, ':'))); + while (*path && *++path); errout: - posix = NULL; /* Couldn't find anything in the given path. - Take the appropriate action based on null_if_not_found. */ - if (opt & FE_NNF) - retval = NULL; - else if (!(opt & FE_NATIVE)) - retval = name; - else + Take the appropriate action based on FE_NNF. */ + if (!(opt & FE_NNF)) { - buf.check (name); + buf.check (name, PC_SYM_FOLLOW | PC_POSIX); retval = buf.get_win32 (); } out: - if (posix) - retval = buf.set_path (posix); debug_printf ("%s = find_exec (%s)", (char *) buf.get_win32 (), name); if (known_suffix) *known_suffix = suffix ?: strchr (buf.get_win32 (), '\0'); @@ -1238,10 +1200,8 @@ av::setup (const char *prog_arg, path_conv& real_path, const char *ext, if (arg1) unshift (arg1); - /* FIXME: This should not be using FE_NATIVE. It should be putting - the posix path on the argv list. */ - find_exec (pgm, real_path, "PATH=", FE_NATIVE, &ext); - unshift (real_path.get_win32 (), 1); + find_exec (pgm, real_path, "PATH", FE_NADA, &ext); + unshift (real_path.normalized_path); } if (real_path.iscygexec ()) dup_all (); |