* 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.
This commit is contained in:
@ -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;
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user