From 0986989f6a290a15e9229f65dd4846d97ee1864e Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Thu, 30 Jul 2009 08:56:57 +0000 Subject: [PATCH] * path.h (class path_conv): Convert path from char array to char *. Initialize to NULL in constructors. Drop normalized_path_size member. (path_conv::size): Remove. (path_conv::operator =): Always copy with sizeof path_conv. Always duplicate path on cygheap. (path_conv::set_path): Move implementation to spawn.cc. * path.cc (path_conv::set_normalized_path): Always allocate normalized_path on cygheap. (path_conv::check): Don't work on path, rather allocate THIS_path in TLS and use it throughout. When finished, allocate path on cygheap and copy over. Defer tacking on extension after having copied path. * spawn.cc (path_conv::set_path): Implement here. --- winsup/cygwin/ChangeLog | 15 +++++++++++ winsup/cygwin/path.cc | 56 ++++++++++++++++++++++------------------- winsup/cygwin/path.h | 32 ++++++++++------------- winsup/cygwin/spawn.cc | 8 ++++++ 4 files changed, 66 insertions(+), 45 deletions(-) diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog index 9c758646a..e8c125c6c 100644 --- a/winsup/cygwin/ChangeLog +++ b/winsup/cygwin/ChangeLog @@ -1,3 +1,18 @@ +2009-07-29 Corinna Vinschen + + * path.h (class path_conv): Convert path from char array to char *. + Initialize to NULL in constructors. Drop normalized_path_size member. + (path_conv::size): Remove. + (path_conv::operator =): Always copy with sizeof path_conv. Always + duplicate path on cygheap. + (path_conv::set_path): Move implementation to spawn.cc. + * path.cc (path_conv::set_normalized_path): Always allocate + normalized_path on cygheap. + (path_conv::check): Don't work on path, rather allocate THIS_path in + TLS and use it throughout. When finished, allocate path on cygheap + and copy over. Defer tacking on extension after having copied path. + * spawn.cc (path_conv::set_path): Implement here. + 2009-07-27 Corinna Vinschen * mount.h (enum fs_info_type): New type. diff --git a/winsup/cygwin/path.cc b/winsup/cygwin/path.cc index 4f224429d..45e7fae0e 100644 --- a/winsup/cygwin/path.cc +++ b/winsup/cygwin/path.cc @@ -376,21 +376,13 @@ path_conv::fillin (HANDLE h) void path_conv::set_normalized_path (const char *path_copy) { - char *p = strchr (path_copy, '\0'); - size_t n = 1 + p - path_copy; - - normalized_path = path + sizeof (path) - n; - - char *eopath = strchr (path, '\0'); - if (normalized_path > eopath) - normalized_path_size = n; - else + if (path_copy) { - normalized_path = (char *) cmalloc_abort (HEAP_STR, n); - normalized_path_size = 0; - } + size_t n = strlen (path_copy) + 1; - memcpy (normalized_path, path_copy, n); + normalized_path = (char *) cmalloc_abort (HEAP_STR, n); + memcpy (normalized_path, path_copy, n); + } } WCHAR tfx_chars[] NO_COPY = { @@ -627,9 +619,11 @@ path_conv::check (const char *src, unsigned opt, char *path_copy = tp.c_get (); char *pathbuf = tp.c_get (); char *tmp_buf = tp.t_get (); + char *THIS_path = tp.c_get (); symlink_info sym; bool need_directory = 0; bool saw_symlinks = 0; + bool add_ext = false; bool is_relpath; char *tail, *path_end; @@ -658,9 +652,12 @@ path_conv::check (const char *src, unsigned opt, if (wide_path) cfree (wide_path); wide_path = NULL; + if (path) + cfree (path); + path = NULL; memset (&dev, 0, sizeof (dev)); fs.clear (); - if (!normalized_path_size && normalized_path) + if (normalized_path) cfree (normalized_path); normalized_path = NULL; int component = 0; // Number of translated components @@ -729,7 +726,7 @@ path_conv::check (const char *src, unsigned opt, { suff = suffixes; sym.pflags = path_flags; - full_path = this->path; + full_path = THIS_path; } /* Convert to native path spec sans symbolic link info. */ @@ -747,7 +744,7 @@ path_conv::check (const char *src, unsigned opt, fileattr = FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_READONLY; else { - fileattr = getfileattr (this->path, + fileattr = getfileattr (THIS_path, sym.pflags & MOUNT_NOPOSIX); dev.devn = FH_FS; } @@ -757,7 +754,7 @@ path_conv::check (const char *src, unsigned opt, { dev.devn = FH_FS; #if 0 - fileattr = getfileattr (this->path, sym.pflags & MOUNT_NOPOSIX); + fileattr = getfileattr (THIS_path, sym.pflags & MOUNT_NOPOSIX); if (!component && fileattr == INVALID_FILE_ATTRIBUTES) { fileattr = FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_READONLY; @@ -882,7 +879,7 @@ is_virtual_symlink: { error = sym.error; if (component == 0) - add_ext_from_sym (sym); + add_ext = true; else if (!(sym.fileattr & FILE_ATTRIBUTE_DIRECTORY)) { error = ENOTDIR; @@ -903,10 +900,10 @@ is_virtual_symlink: set_symlink (symlen); // last component of path is a symlink. if (opt & PC_SYM_CONTENTS) { - strcpy (path, sym.contents); + strcpy (THIS_path, sym.contents); goto out; } - add_ext_from_sym (sym); + add_ext = true; goto out; } else @@ -966,7 +963,7 @@ virtual_component_retry: { too_long: error = ENAMETOOLONG; - strcpy (path, "::ENAMETOOLONG::"); + this->path = cstrdup ("::ENAMETOOLONG::"); return; } @@ -993,9 +990,13 @@ virtual_component_retry: } if (!(opt & PC_SYM_CONTENTS)) - add_ext_from_sym (sym); + add_ext = true; out: + this->path = (char *) cmalloc_abort (HEAP_STR, strlen (THIS_path) + 7); + stpcpy (this->path, THIS_path); + if (add_ext) + add_ext_from_sym (sym); if (dev.devn == FH_NETDRIVE && component) { /* This case indicates a non-existant resp. a non-retrievable @@ -1089,9 +1090,7 @@ out: if (saw_symlinks) set_has_symlinks (); - if (!(opt & PC_POSIX)) - normalized_path_size = 0; - else + if ((opt & PC_POSIX)) { if (tail < path_end && tail > path_copy + 1) *tail = '/'; @@ -1111,11 +1110,16 @@ out: path_conv::~path_conv () { - if (!normalized_path_size && normalized_path) + if (normalized_path) { cfree (normalized_path); normalized_path = NULL; } + if (path) + { + cfree (path); + path = NULL; + } if (wide_path) { cfree (wide_path); diff --git a/winsup/cygwin/path.h b/winsup/cygwin/path.h index 952e0584a..7a8033d3d 100644 --- a/winsup/cygwin/path.h +++ b/winsup/cygwin/path.h @@ -83,6 +83,8 @@ enum path_types PATH_SOCKET = 0x40000000 }; +extern "C" char *__stdcall cstrdup (const char *s); + class symlink_info; class path_conv @@ -163,40 +165,36 @@ class path_conv path_conv (const device& in_dev) : fileattr (INVALID_FILE_ATTRIBUTES), wide_path (NULL), path_flags (0), - known_suffix (NULL), error (0), dev (in_dev), normalized_path (NULL), - normalized_path_size (0) + known_suffix (NULL), error (0), dev (in_dev), normalized_path (NULL) { - strcpy (path, in_dev.native); + path = cstrdup (in_dev.native); } path_conv (int, const char *src, unsigned opt = PC_SYM_FOLLOW, const suffix_info *suffixes = NULL) - : wide_path (NULL), normalized_path (NULL), normalized_path_size (0) + : wide_path (NULL), normalized_path (NULL), path (NULL) { check (src, opt, suffixes); } path_conv (const UNICODE_STRING *src, unsigned opt = PC_SYM_FOLLOW, const suffix_info *suffixes = NULL) - : wide_path (NULL), normalized_path (NULL), normalized_path_size (0) + : wide_path (NULL), normalized_path (NULL), path (NULL) { check (src, opt | PC_NULLEMPTY, suffixes); } path_conv (const char *src, unsigned opt = PC_SYM_FOLLOW, const suffix_info *suffixes = NULL) - : wide_path (NULL), normalized_path (NULL), normalized_path_size (0) + : wide_path (NULL), normalized_path (NULL), path (NULL) { check (src, opt | PC_NULLEMPTY, suffixes); } path_conv () : fileattr (INVALID_FILE_ATTRIBUTES), wide_path (NULL), path_flags (0), - known_suffix (NULL), error (0), normalized_path (NULL), - normalized_path_size (0) - { - path[0] = '\0'; - } + known_suffix (NULL), error (0), normalized_path (NULL), path (NULL) + {} ~path_conv (); inline char *get_win32 () { return path; } @@ -214,7 +212,8 @@ class path_conv operator int () {return fileattr; } path_conv &operator =(path_conv &pc) { - memcpy (this, &pc, pc.size ()); + memcpy (this, &pc, sizeof pc); + path = cstrdup (pc.path); set_normalized_path (pc.normalized_path); wide_path = NULL; return *this; @@ -233,22 +232,17 @@ class path_conv bool fs_is_cdrom () const {return fs.is_cdrom ();} bool fs_is_mvfs () const {return fs.is_mvfs ();} ULONG fs_serial_number () const {return fs.serial_number ();} - void set_path (const char *p) {strcpy (path, p);} + inline void set_path (const char *p); void fillin (HANDLE h); - inline size_t size () - { - return (sizeof (*this) - sizeof (path)) + strlen (path) + 1 + normalized_path_size; - } bool is_binary (); unsigned __stdcall ndisk_links (DWORD); char *normalized_path; - size_t normalized_path_size; void set_normalized_path (const char *) __attribute__ ((regparm (2))); DWORD get_symlink_length () { return symlink_length; }; private: DWORD symlink_length; - char path[NT_MAX_PATH]; + char *path; }; /* Symlink marker */ diff --git a/winsup/cygwin/spawn.cc b/winsup/cygwin/spawn.cc index e292decfd..09b9cd80f 100644 --- a/winsup/cygwin/spawn.cc +++ b/winsup/cygwin/spawn.cc @@ -87,6 +87,14 @@ perhaps_suffix (const char *prog, path_conv& buf, int& err, unsigned opt) return ext; } +inline void +path_conv::set_path (const char *p) +{ + if (path) + cfree (path); + path = cstrdup (p); +} + /* 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.