* 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:
Christopher Faylor
2000-09-03 04:16:35 +00:00
parent 39630fe3a1
commit b0e82b74fb
44 changed files with 2219 additions and 1888 deletions

View File

@ -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;
}