diff options
author | Christopher Faylor <me@cgf.cx> | 2000-09-03 04:16:35 +0000 |
---|---|---|
committer | Christopher Faylor <me@cgf.cx> | 2000-09-03 04:16:35 +0000 |
commit | b0e82b74fbdfa2dee89505aba03f2827480cc8ca (patch) | |
tree | 42b2a83a749596de6cb3a075e379a4e30ecd1796 /winsup/cygwin/path.cc | |
parent | 39630fe3a1b6106001a9f5f65a9d52bf48583739 (diff) | |
download | cygnal-b0e82b74fbdfa2dee89505aba03f2827480cc8ca.tar.gz cygnal-b0e82b74fbdfa2dee89505aba03f2827480cc8ca.tar.bz2 cygnal-b0e82b74fbdfa2dee89505aba03f2827480cc8ca.zip |
* Makefile.in: Add cygheap.o.
* child_info.h: Add specific exec class.
* cygheap.h: New file. Contains declarations for cygwin heap.
* cygheap.cc: New file. Implements cygwin heap functions.
* dcrt0.cc (quoted): Simplify due to new method for passing arguments between
cygwin programs.
(alloc_stack_hard_way): Attempt to handle overlapped stack.
(dll_crt0_1): Move child_info processing here. Accomodate new method for
passing arguments between cygwin programs. Initialize cygwin heap. Establish
__argc and __argv variables.
(_dll_crt0): Move most of child_info processing to dll_crt0_1.
(cygwin_dll_init): Remove duplication.
* dtable.cc (dtable::extend): Allocate dtable using cygwin heap.
(dtable::build_fhandler): Ditto for fhandler type being constructed.
(dtable::dup_worker): Free new fhandler from cygwin heap on error.
(dtable::select_*): Don't assume that this == fdtab.
(dtable::linearize_fd_array): Delete.
(dtable::delinearize_fd_array): Delete.
(dtable::fixup_after_exec): New file.
(dtable::vfork_child_dup): Use cygwin heap.
(dtable::vfork_parent_restore): Ditto.
* dtable.h: Remove obsolete methods. Add new method.
* environ.cc (posify): Eliminate already_posix parameter and logic.
(envsize): New function.
(_addenv): Use envsize.
(environ_init): Accept an argument pointing to an existing environment list.
If supplied, allocate space for this in the the program's heap.
* fhandler.cc (fhandler_base::operator =): Move here from fhandler.h. Use
cygwin heap to allocate filenames.
(fhandler_base::set_name): Allocate/free names from cygwin heap.
(fhandler_base::linearize): Delete.
(fhandler_base::de_linearize): Delete.
(fhandler_base::operator delete): Free from cygwin heap.
(fhandler_base::~fhandler_base): Ditto.
* fhandler.h: Accomodate elimination of *linearize and other changes above.
* fhandler_console.cc (fhandler_console::fixup_after_exec): Rename from
de_linearize.
* heap.h: New file.
* fhandler_tty.cc (fhandler_tty_slave::fhandler_tty_slave): Use cygwin heap for
name. fhandler_tty::fixup_after_exec): Rename from de_linearize.
* fork.cc (fork): Call cygheap_fixup_in_child.
* heap.cc: Use declarations in heap.h.
* malloc.cc: Sprinkle assertions throughout to catch attempts to free/realloc
something from the cygwin heap.
* path.cc: Throughout, eliminate use of per-thread cache for cwd. Use cwd_*
functions rather than cwd_* variables to access cwd_win32 and cwd_posix.
(cwd_win32): New function.
(cwd_posix): New function.
(cwd_hash): New function.
(cwd_fixup_after_exec): New function.
* path.h: Accomodate path.cc changes.
* pinfo.cc (pinfo_init): Accept a pointer to an environment table. Pass this
to environ_init. Eliminate old 'title' tests.
* pinfo.h: Accomodate above change in argument.
* spawn.cc (struct av): New method for building argv list.
(av::unshift): New method.
(spawn_guts): Allocate everything that the child process needs in the cygwin
heap and pass a pointer to this to the child. Build argv list using new
method. Eliminate delinearize stuff.
* thread.h: Eliminate _cwd_win32 and _cwd_posix buffers.
* winsup.h: Eliminate obsolete functions. Add envsize() declaration.
Diffstat (limited to 'winsup/cygwin/path.cc')
-rw-r--r-- | winsup/cygwin/path.cc | 149 |
1 files changed, 106 insertions, 43 deletions
diff --git a/winsup/cygwin/path.cc b/winsup/cygwin/path.cc index 48da8c4c9..6400699ee 100644 --- a/winsup/cygwin/path.cc +++ b/winsup/cygwin/path.cc @@ -88,6 +88,7 @@ details. */ #include "sync.h" #include "sigproc.h" #include "pinfo.h" +#include "cygheap.h" static int normalize_win32_path (const char *cwd, const char *src, char *dst); static char *getcwd_inner (char *buf, size_t ulen, int posix_p, int with_chroot); @@ -150,15 +151,71 @@ struct symlink_info /* Cache getcwd value. FIXME: We need a lock for these in order to support multiple threads. */ -#ifdef _MT_SAFE -#define cwd_win32 _reent_winsup()->_cwd_win32 -#define cwd_posix _reent_winsup()->_cwd_posix -#define cwd_hash _reent_winsup()->_cwd_hash -#else -static char *cwd_win32; -static char *cwd_posix; -static unsigned long cwd_hash; -#endif +#define TMPCWD ((char *) alloca (MAX_PATH + 1)) + +struct cwdstuff +{ + char *posix; + char *win32; + DWORD hash; + muto *lock; +}; + +cwdstuff cwd; + +char * __stdcall +cwd_win32 (char *buf) +{ + char *ret; + cwd.lock->acquire (); + if (cwd.win32 == NULL) + ret = NULL; + else if (buf == NULL) + ret = cwd.win32; + else + ret = strcpy (buf, cwd.win32); + cwd.lock->release (); + return ret; +} + +char * __stdcall +cwd_posix (char *buf) +{ + char *ret; + cwd.lock->acquire (); + if (cwd.posix == NULL) + ret = NULL; + else if (buf == NULL) + ret = cwd.posix; + else + ret = strcpy (buf, cwd.posix); + cwd.lock->release (); + return ret; +} + +DWORD __stdcall +cwd_hash () +{ + DWORD hashnow; + cwd.lock->acquire (); + hashnow = cwd.hash; + cwd.lock->release (); + return hashnow; +} + +void __stdcall +cwd_init () +{ + cwd.lock = new_muto (FALSE, "cwd"); +} + +void __stdcall +cwd_fixup_after_exec (char *win32, char *posix, DWORD hash) +{ + cwd.win32 = win32; + cwd.posix = posix; + cwd.hash = hash; +} #define ischrootpath(path) \ (myself->rootlen && \ @@ -965,7 +1022,7 @@ mount_info::conv_to_win32_path (const char *src_path, char *win32_path, if (strpbrk (src_path, ":\\") != NULL) { debug_printf ("%s already win32", src_path); - rc = normalize_win32_path (cwd_win32, src_path, dst); + rc = normalize_win32_path (cwd_win32 (TMPCWD), src_path, dst); if (rc) { debug_printf ("normalize_win32_path failed, rc %d", rc); @@ -1082,10 +1139,12 @@ fillin: /* Compute relative path if asked to and able to. */ unsigned cwdlen; cwdlen = 0; /* avoid a (hopefully) bogus compiler warning */ + char *cwd_win32_now; + cwd_win32_now = cwd_win32 (TMPCWD); if (win32_path == NULL) /* nothing to do */; else if (isrelpath && - path_prefix_p (cwd_win32, dst, cwdlen = strlen (cwd_win32))) + path_prefix_p (cwd_win32_now, dst, cwdlen = strlen (cwd_win32_now))) { size_t n = strlen (dst); if (n < cwdlen) @@ -1095,7 +1154,7 @@ fillin: if (n == cwdlen) dst += cwdlen; else - dst += isdirsep (cwd_win32[cwdlen - 1]) ? cwdlen : cwdlen + 1; + dst += isdirsep (cwd_win32_now[cwdlen - 1]) ? cwdlen : cwdlen + 1; memmove (win32_path, dst, strlen (dst) + 1); if (!*win32_path) @@ -2453,10 +2512,9 @@ hash_path_name (unsigned long hash, const char *name) Otherwise the inodes same will differ depending on whether a file is referenced with an absolute value or relatively. */ - if (*name != '\\' && (cwd_win32 == NULL || - get_cwd_win32 ())) + if (*name != '\\' && (cwd_win32 (TMPCWD) == NULL || get_cwd_win32 ())) { - hash = cwd_hash; + hash = cwd_hash (); if (name[0] == '.' && name[1] == '\0') return hash; hash = hash_path_name (hash, "\\"); @@ -2481,18 +2539,20 @@ get_cwd_win32 () { DWORD dlen, len; + cwd.lock->acquire (); for (dlen = 256; ; dlen *= 2) { - cwd_win32 = (char *) realloc (cwd_win32, dlen + 2); - if ((len = GetCurrentDirectoryA (dlen, cwd_win32)) < dlen) + cwd.win32 = (char *) crealloc (cwd.win32, dlen + 2); + if ((len = GetCurrentDirectoryA (dlen, cwd.win32)) < dlen) break; } if (len == 0) __seterrno (); else - cwd_hash = hash_path_name (0, cwd_win32); + cwd.hash = hash_path_name (0, cwd.win32); + cwd.lock->release (); return len; } @@ -2504,16 +2564,18 @@ getcwd_inner (char *buf, size_t ulen, int posix_p, int with_chroot) char *resbuf = NULL; size_t len = ulen; - if (cwd_win32 == NULL && !get_cwd_win32 ()) + if (cwd_win32 (TMPCWD) == NULL && !get_cwd_win32 ()) return NULL; + char *cwd_win32_now = cwd_win32 (TMPCWD); + char *cwd_posix_now = cwd_posix (TMPCWD); if (!posix_p) { - if (strlen (cwd_win32) >= len) + if (strlen (cwd_win32_now) >= len) set_errno (ERANGE); else { - strcpy (buf, cwd_win32); + strcpy (buf, cwd_win32_now); resbuf = buf; } @@ -2521,21 +2583,21 @@ getcwd_inner (char *buf, size_t ulen, int posix_p, int with_chroot) resbuf, resbuf ? resbuf : "", buf, len); return resbuf; } - else if (cwd_posix != NULL) + else if (cwd_posix_now != NULL) { - debug_printf("myself->root: %s, cwd_posix: %s", myself->root, cwd_posix); - if (strlen (cwd_posix) >= len) + debug_printf("myself->root: %s, cwd_posix: %s", myself->root, cwd_posix_now); + if (strlen (cwd_posix_now) >= len) set_errno (ERANGE); - else if (with_chroot && ischrootpath(cwd_posix)) + else if (with_chroot && ischrootpath(cwd_posix_now)) { - strcpy (buf, cwd_posix + myself->rootlen); + strcpy (buf, cwd_posix_now + myself->rootlen); if (!buf[0]) strcpy (buf, "/"); resbuf = buf; } else { - strcpy (buf, cwd_posix); + strcpy (buf, cwd_posix_now); resbuf = buf; } @@ -2549,30 +2611,29 @@ getcwd_inner (char *buf, size_t ulen, int posix_p, int with_chroot) char temp[MAX_PATH]; /* Turn from Win32 style to our style. */ - cygwin_shared->mount.conv_to_posix_path (cwd_win32, temp, 0); + cygwin_shared->mount.conv_to_posix_path (cwd_win32_now, temp, 0); size_t tlen = strlen (temp); if (with_chroot && ischrootpath (temp)) tlen -= myself->rootlen; - cwd_posix = (char *) realloc ( - cwd_posix, tlen + 1); - if (cwd_posix != NULL) + cwd.lock->acquire (); + cwd.posix = (char *) crealloc (cwd.posix, tlen + 1); + if (cwd.posix != NULL) if (with_chroot && ischrootpath (temp)) { - strcpy (cwd_posix, temp + myself->rootlen); + strcpy (cwd.posix, temp + myself->rootlen); if (!buf[0]) strcpy (buf, "/"); } else - strcpy (cwd_posix, temp); + strcpy (cwd.posix, temp); + + cwd.lock->release (); if (tlen >= ulen) - { - /* len was too small */ - set_errno (ERANGE); - } + set_errno (ERANGE); /* len was too small */ else { strcpy (buf, temp); @@ -2643,12 +2704,13 @@ chdir (const char *dir) __seterrno (); else { + cwd.lock->acquire (); /* Store new cache information */ - free (cwd_win32); - cwd_win32 = strdup (path); + cfree (cwd.win32); + cwd.win32 = cstrdup (path); char pathbuf[MAX_PATH]; - (void) normalize_posix_path (cwd_posix, dir, pathbuf); + (void) normalize_posix_path (cwd.posix, dir, pathbuf); /* Look for trailing path component consisting entirely of dots. This is needed only in case of chdir since Windows simply ignores count of dots > 2 here instead of returning an error code. Counts of dots @@ -2656,11 +2718,12 @@ chdir (const char *dir) char *last_slash = strrchr (pathbuf, '/'); if (last_slash > pathbuf && strspn (last_slash + 1, ".") == strlen (last_slash + 1)) *last_slash = '\0'; - free (cwd_posix); - cwd_posix = strdup (pathbuf); + cfree (cwd.posix); + cwd.posix = cstrdup (pathbuf); + cwd.lock->release (); } - syscall_printf ("%d = chdir() cwd_posix '%s' native '%s'", res, cwd_posix, native_dir); + syscall_printf ("%d = chdir() cwd.posix '%s' native '%s'", res, cwd.posix, native_dir); return res; } |