From 6ea0c04e7ca613dbf28b5f913fe2d6f84ee7cbfc Mon Sep 17 00:00:00 2001 From: Christopher Faylor Date: Wed, 31 Oct 2001 00:55:32 +0000 Subject: [PATCH] * cygheap.h (cygheap_fdmanip::cygheap_fdmanip): Clear fh. (cygheap_fdmanip::isopen): New method. * syscalls.cc (_read): Avoid accessing closed fd. * path.h (fe_types): New enum. (path_conv::set_path): New method. (find_exec): Change null_if_not_found argument to something more generic. * spawn.cc (find_exec): Default to returning the POSIX path rather than the windows path, unless instructed otherwise. (spawn_guts): Force call to find_exec to use native paths. * dlfcn.cc (check_path_access): Accommodate new find_exec arguments. * environ.h (win_env::get_posix): New method. --- winsup/cygwin/ChangeLog | 16 ++++++++++++ winsup/cygwin/cygheap.h | 3 ++- winsup/cygwin/dlfcn.cc | 2 +- winsup/cygwin/environ.h | 3 ++- winsup/cygwin/path.h | 15 ++++++++++-- winsup/cygwin/spawn.cc | 51 +++++++++++++++++++++++++++++++-------- winsup/cygwin/syscalls.cc | 3 +++ 7 files changed, 78 insertions(+), 15 deletions(-) diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog index 0fc1db1ff..98ac1d364 100644 --- a/winsup/cygwin/ChangeLog +++ b/winsup/cygwin/ChangeLog @@ -1,3 +1,19 @@ +2001-10-30 Christopher Faylor + + * cygheap.h (cygheap_fdmanip::cygheap_fdmanip): Clear fh. + (cygheap_fdmanip::isopen): New method. + * syscalls.cc (_read): Avoid accessing closed fd. + + * path.h (fe_types): New enum. + (path_conv::set_path): New method. + (find_exec): Change null_if_not_found argument to something more + generic. + * spawn.cc (find_exec): Default to returning the POSIX path rather than + the windows path, unless instructed otherwise. + (spawn_guts): Force call to find_exec to use native paths. + * dlfcn.cc (check_path_access): Accommodate new find_exec arguments. + * environ.h (win_env::get_posix): New method. + 2001-10-30 Corinna Vinschen * fhandler_socket.cc (fhandler_socket::close): Add error handling. diff --git a/winsup/cygwin/cygheap.h b/winsup/cygwin/cygheap.h index 16f22c52d..5b868040f 100644 --- a/winsup/cygwin/cygheap.h +++ b/winsup/cygwin/cygheap.h @@ -184,7 +184,7 @@ class cygheap_fdmanip fhandler_base **fh; bool locked; public: - cygheap_fdmanip () {} + cygheap_fdmanip (): fh (NULL) {} virtual ~cygheap_fdmanip () { if (locked) @@ -198,6 +198,7 @@ class cygheap_fdmanip operator fhandler_base* &() {return *fh;} void operator = (fhandler_base *fh) {*this->fh = fh;} fhandler_base *operator -> () const {return *fh;} + bool isopen () const {return *fh;} }; class cygheap_fdnew : public cygheap_fdmanip diff --git a/winsup/cygwin/dlfcn.cc b/winsup/cygwin/dlfcn.cc index 068c8a965..b6babe66b 100644 --- a/winsup/cygwin/dlfcn.cc +++ b/winsup/cygwin/dlfcn.cc @@ -38,7 +38,7 @@ set_dl_error (const char *str) inline const char * __stdcall check_path_access (const char *mywinenv, const char *name, path_conv& buf) { - return find_exec (name, buf, mywinenv, TRUE); + return find_exec (name, buf, mywinenv, FE_NNF | FE_NATIVE | FE_CWD); } /* Search LD_LIBRARY_PATH for dll, if it exists. diff --git a/winsup/cygwin/environ.h b/winsup/cygwin/environ.h index 888b473dd..86f70f675 100644 --- a/winsup/cygwin/environ.h +++ b/winsup/cygwin/environ.h @@ -28,7 +28,8 @@ struct win_env int (*posix_len) (const char *); int (*win32_len) (const char *); void add_cache (const char *in_posix, const char *in_native = NULL); - const char * get_native () {return native ? native + namelen : NULL;} + const char * get_native () const {return native ? native + namelen : NULL;} + const char * get_posix () const {return posix ? posix : NULL;} }; win_env * __stdcall getwinenv (const char *name, const char *posix = NULL); diff --git a/winsup/cygwin/path.h b/winsup/cygwin/path.h index 6778e27a7..0f3409a75 100644 --- a/winsup/cygwin/path.h +++ b/winsup/cygwin/path.h @@ -136,6 +136,7 @@ class path_conv DWORD file_attributes () {return fileattr;} DWORD get_drive_type () {return drive_type;} BOOL fs_fast_ea () {return sym_opt & PC_CHECK_EA;} + void set_path (const char *p) {strcpy (path, p);} }; /* Symlink marker */ @@ -150,8 +151,18 @@ class path_conv #define MAX_LINK_DEPTH 10 int __stdcall slash_unc_prefix_p (const char *path) __attribute__ ((regparm(1))); -const char * __stdcall find_exec (const char *name, path_conv& buf, const char *winenv = "PATH=", - int null_if_notfound = 0, const char **known_suffix = NULL) __attribute__ ((regparm(3))); +enum fe_types +{ + FE_NADA = 0, /* Nothing special */ + FE_NNF = 1, /* Return NULL if not found */ + FE_NATIVE = 2, /* Return native path in path_conv struct */ + FE_CWD = 4 /* Search CWD for program */ +}; +const char * __stdcall find_exec (const char *name, path_conv& buf, + const char *winenv = "PATH=", + unsigned opt = FE_NADA, + const char **known_suffix = NULL) + __attribute__ ((regparm(3))); /* Common macros for checking for invalid path names */ #define isdrive(s) (isalpha (*(s)) && (s)[1] == ':') diff --git a/winsup/cygwin/spawn.cc b/winsup/cygwin/spawn.cc index ee004666b..0c6eb5cc5 100644 --- a/winsup/cygwin/spawn.cc +++ b/winsup/cygwin/spawn.cc @@ -84,21 +84,34 @@ perhaps_suffix (const char *prog, path_conv &buf) const char * __stdcall find_exec (const char *name, path_conv& buf, const char *mywinenv, - int null_if_notfound, const char **known_suffix) + unsigned opt, const char **known_suffix) { const char *suffix = ""; debug_printf ("find_exec (%s)", name); char *retval = buf; + char tmp[MAX_PATH]; + const char *posix = (opt & FE_NATIVE) ? NULL : name; + bool has_slash = strchr (name, '/'); /* 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. */ - if ((suffix = perhaps_suffix (name, buf)) != NULL) - goto out; + if ((has_slash || opt & FE_CWD) + && (suffix = perhaps_suffix (name, buf)) != NULL) + { + if (posix && !has_slash) + { + tmp[0] = '.'; + tmp[1] = '/'; + strcpy (tmp + 2, name); + posix = tmp; + } + goto out; + } win_env *winpath; const char *path; - char tmp[MAX_PATH]; + const char *posix_path; /* Return the error condition if this is an absolute path or if there is no PATH to search. */ @@ -111,14 +124,17 @@ find_exec (const char *name, path_conv& buf, const char *mywinenv, debug_printf ("%s%s", mywinenv, path); + posix = (opt & FE_NATIVE) ? NULL : tmp; + posix_path = winpath->get_posix () - 1; /* Iterate over the specified path, looking for the file with and without executable extensions. */ do { + posix_path++; char *eotmp = strccpy (tmp, &path, ';'); /* An empty path or '.' means the current directory, but we've already tried that. */ - if (tmp[0] == '\0' || (tmp[0] == '.' && tmp[1] == '\0')) + if (opt & FE_CWD && (tmp[0] == '\0' || (tmp[0] == '.' && tmp[1] == '\0'))) continue; *eotmp++ = '\\'; @@ -127,19 +143,32 @@ find_exec (const char *name, path_conv& buf, const char *mywinenv, debug_printf ("trying %s", tmp); if ((suffix = perhaps_suffix (tmp, buf)) != NULL) - goto out; + { + if (posix == tmp) + { + eotmp = strccpy (tmp, &posix_path, ':'); + if (eotmp == tmp) + *eotmp++ = '.'; + *eotmp++ = '/'; + strcpy (eotmp, name); + } + goto out; + } } - while (*path && *++path); + while (*path && *++path && (posix_path = strchr (posix_path, ':'))); errout: + posix = NULL; /* Couldn't find anything in the given path. Take the appropriate action based on null_if_not_found. */ - if (null_if_notfound) + if (opt & FE_NNF) retval = NULL; - else + else if (opt & FE_NATIVE) buf.check (name); out: + if (posix) + buf.set_path (posix); debug_printf ("%s = find_exec (%s)", (char *) buf, name); if (known_suffix) *known_suffix = suffix ?: strchr (buf, '\0'); @@ -466,7 +495,9 @@ spawn_guts (HANDLE hToken, const char * prog_arg, const char *const *argv, if (arg1) newargv.unshift (arg1); - find_exec (pgm, real_path, "PATH=", 0, &ext); + /* 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); newargv.unshift (real_path, 1); } diff --git a/winsup/cygwin/syscalls.cc b/winsup/cygwin/syscalls.cc index 637ecaf90..57eb51cd2 100644 --- a/winsup/cygwin/syscalls.cc +++ b/winsup/cygwin/syscalls.cc @@ -322,6 +322,9 @@ _read (int fd, void *ptr, size_t len) goto out; } + if (!cfd.isopen()) + return -1; + /* Check to see if this is a background read from a "tty", sending a SIGTTIN, if appropriate */ res = cfd->bg_check (SIGTTIN);