mirror of
git://sourceware.org/git/newlib-cygwin.git
synced 2025-02-01 12:00:35 +08:00
* path.cc (cwd_win32): Eliminate.
(cwd_posix): Eliminate. (cwd_hash): Eliminate. (cwdstuff::init): Rename from cwd_init. (cwdstuff::fixup_after_exec): Rename from cwd_fixup_after_exec. (cwdstuff::get): Rename from get_cwd_inner. (normalize_posix_path): Eliminate cwd argument. Just calculate when necessary. (normalize_win32_path): Ditto. (mount_info::conv_to_win32_path): Eliminate cwd retrieval here. (mount_info::conv_to_posix_path): Ditto. (hash_path_name): Accomodate additional methods in cwdstuff. (get_cwd_win32): Eliminate. (getcwd): Use cwdstuff methods. Properly handle case where buf == NULL and len < 0. (cwdstuff::get_hash): New method. (cwdstuff::get_initial): New method. (cwdstuff::set): New method. (cwdstuff::get): New method. (cwdstuff::copy): New method. * path.h: Move cwdstuff struct here. Add a bunch of stuff to cwdstuff. Make cygcwd an extern. * spawn.cc (spawn_guts): Use copy method to get copies of cwd info to pass to execed process. * dcrt0.cc (dll_crt0_1): Use cygcwd methods for cwd initialization.
This commit is contained in:
parent
108952ea1d
commit
7e24f1bf3a
@ -1,3 +1,31 @@
|
|||||||
|
Mon Sep 4 22:53:58 2000 Christopher Faylor <cgf@cygnus.com>
|
||||||
|
|
||||||
|
* path.cc (cwd_win32): Eliminate.
|
||||||
|
(cwd_posix): Eliminate.
|
||||||
|
(cwd_hash): Eliminate.
|
||||||
|
(cwdstuff::init): Rename from cwd_init.
|
||||||
|
(cwdstuff::fixup_after_exec): Rename from cwd_fixup_after_exec.
|
||||||
|
(cwdstuff::get): Rename from get_cwd_inner.
|
||||||
|
(normalize_posix_path): Eliminate cwd argument. Just calculate when
|
||||||
|
necessary.
|
||||||
|
(normalize_win32_path): Ditto.
|
||||||
|
(mount_info::conv_to_win32_path): Eliminate cwd retrieval here.
|
||||||
|
(mount_info::conv_to_posix_path): Ditto.
|
||||||
|
(hash_path_name): Accomodate additional methods in cwdstuff.
|
||||||
|
(get_cwd_win32): Eliminate.
|
||||||
|
(getcwd): Use cwdstuff methods. Properly handle case where buf == NULL
|
||||||
|
and len < 0.
|
||||||
|
(cwdstuff::get_hash): New method.
|
||||||
|
(cwdstuff::get_initial): New method.
|
||||||
|
(cwdstuff::set): New method.
|
||||||
|
(cwdstuff::get): New method.
|
||||||
|
(cwdstuff::copy): New method.
|
||||||
|
* path.h: Move cwdstuff struct here. Add a bunch of stuff to cwdstuff.
|
||||||
|
Make cygcwd an extern.
|
||||||
|
* spawn.cc (spawn_guts): Use copy method to get copies of cwd info to
|
||||||
|
pass to execed process.
|
||||||
|
* dcrt0.cc (dll_crt0_1): Use cygcwd methods for cwd initialization.
|
||||||
|
|
||||||
2000-09-03 Egor Duda <deo@logos-m.ru>
|
2000-09-03 Egor Duda <deo@logos-m.ru>
|
||||||
|
|
||||||
* path.cc (readlink): Check if buffer length is positive.
|
* path.cc (readlink): Check if buffer length is positive.
|
||||||
|
@ -111,13 +111,18 @@ _cfree (void *ptr)
|
|||||||
static void *__stdcall
|
static void *__stdcall
|
||||||
_crealloc (void *ptr, int size)
|
_crealloc (void *ptr, int size)
|
||||||
{
|
{
|
||||||
char *newptr;
|
void *newptr;
|
||||||
|
if (ptr == NULL)
|
||||||
|
newptr = _cmalloc (size);
|
||||||
|
else
|
||||||
|
{
|
||||||
int oldsize = bucket2size[*(int *) ((char *) ptr - 4)];
|
int oldsize = bucket2size[*(int *) ((char *) ptr - 4)];
|
||||||
if (size <= oldsize)
|
if (size <= oldsize)
|
||||||
return ptr;
|
return ptr;
|
||||||
newptr = (char *) _cmalloc (size);
|
newptr = _cmalloc (size);
|
||||||
memcpy (newptr, ptr, oldsize);
|
memcpy (newptr, ptr, oldsize);
|
||||||
_cfree (ptr);
|
_cfree (ptr);
|
||||||
|
}
|
||||||
return newptr;
|
return newptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -671,7 +671,7 @@ dll_crt0_1 ()
|
|||||||
__argc = spawn_info->moreinfo->argc;
|
__argc = spawn_info->moreinfo->argc;
|
||||||
__argv = spawn_info->moreinfo->argv;
|
__argv = spawn_info->moreinfo->argv;
|
||||||
envp = spawn_info->moreinfo->environ;
|
envp = spawn_info->moreinfo->environ;
|
||||||
cwd_fixup_after_exec (spawn_info->moreinfo->cwd_win32,
|
cygcwd.fixup_after_exec (spawn_info->moreinfo->cwd_win32,
|
||||||
spawn_info->moreinfo->cwd_posix,
|
spawn_info->moreinfo->cwd_posix,
|
||||||
spawn_info->moreinfo->cwd_hash);
|
spawn_info->moreinfo->cwd_hash);
|
||||||
fdtab.fixup_after_exec (spawn_info->parent, spawn_info->moreinfo->nfds,
|
fdtab.fixup_after_exec (spawn_info->parent, spawn_info->moreinfo->nfds,
|
||||||
@ -733,7 +733,7 @@ dll_crt0_1 ()
|
|||||||
}
|
}
|
||||||
|
|
||||||
cygheap_init (); /* Initialize cygwin's heap */
|
cygheap_init (); /* Initialize cygwin's heap */
|
||||||
cwd_init ();
|
cygcwd.init ();
|
||||||
|
|
||||||
/* Initialize our process table entry. */
|
/* Initialize our process table entry. */
|
||||||
pinfo_init (envp);
|
pinfo_init (envp);
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
/* path.cc: path support.
|
/* path.cc: path support.
|
||||||
|
|
||||||
Copyright 1996, 1997, 1998, 1999, 2000 Cygnus Solutions.
|
Copyright 1996, 1997, 1998, 1999, 2000 Red Hat, Inc.
|
||||||
|
|
||||||
This file is part of Cygwin.
|
This file is part of Cygwin.
|
||||||
|
|
||||||
@ -15,46 +15,22 @@ details. */
|
|||||||
|
|
||||||
Pathnames are handled as follows:
|
Pathnames are handled as follows:
|
||||||
|
|
||||||
- / is equivalent to \
|
- A \ or : in a path denotes a pure windows spec.
|
||||||
- Paths beginning with // (or \\) are not translated (i.e. looked
|
- Paths beginning with // (or \\) are not translated (i.e. looked
|
||||||
up in the mount table) and are assumed to be UNC path names.
|
up in the mount table) and are assumed to be UNC path names.
|
||||||
- Paths containing a : are not translated (paths like
|
|
||||||
/foo/bar/baz:qux: don't make much sense but having the rule written
|
|
||||||
this way allows one to use strchr).
|
|
||||||
|
|
||||||
The goal in the above set of rules is to allow both POSIX and Win32
|
The goal in the above set of rules is to allow both POSIX and Win32
|
||||||
flavors of pathnames without either interfering. The rules are
|
flavors of pathnames without either interfering. The rules are
|
||||||
intended to be as close to a superset of both as possible.
|
intended to be as close to a superset of both as possible.
|
||||||
|
|
||||||
A possible future enhancement would be to allow people to
|
|
||||||
disable/enable the mount table handling to support pure Win32
|
|
||||||
pathnames. Hopefully this won't be needed. The suggested way to
|
|
||||||
do this would be an environment variable because
|
|
||||||
a) we need something that is inherited from parent to child,
|
|
||||||
b) environment variables can be passed from the DOS shell to a
|
|
||||||
cygwin app,
|
|
||||||
c) it allows disabling the feature on an app by app basis within
|
|
||||||
the same session (whereas playing about with the registry wouldn't
|
|
||||||
-- without getting too complicated). Example:
|
|
||||||
CYGWIN=pathrules[=@]{win32,posix}. If CYGWIN=pathrules=win32,
|
|
||||||
mount table handling is disabled. [The intent is to have CYGWIN be
|
|
||||||
a catchall for tweaking various cygwin.dll features].
|
|
||||||
|
|
||||||
Note that you can have more than one path to a file. The mount
|
Note that you can have more than one path to a file. The mount
|
||||||
table is always prefered when translating Win32 paths to POSIX
|
table is always prefered when translating Win32 paths to POSIX
|
||||||
paths. Win32 paths in mount table entries may be UNC paths or
|
paths. Win32 paths in mount table entries may be UNC paths or
|
||||||
standard Win32 paths starting with <drive-letter>:
|
standard Win32 paths starting with <drive-letter>:
|
||||||
|
|
||||||
Text vs Binary issues are not considered here in path style
|
Text vs Binary issues are not considered here in path style
|
||||||
decisions.
|
decisions, although the appropriate flags are retrieved and
|
||||||
|
stored in various structures.
|
||||||
/ and \ are treated as equivalent. One or the other is prefered in
|
|
||||||
certain situations (e.g. / is preferred in result of getcwd, \ is
|
|
||||||
preferred in arguments to Win32 api calls), but this code will
|
|
||||||
translate as necessary.
|
|
||||||
|
|
||||||
Apps wishing to translate to/from pure Win32 and POSIX-like
|
|
||||||
pathnames can use cygwin_foo.
|
|
||||||
|
|
||||||
Removing mounted filesystem support would simplify things greatly,
|
Removing mounted filesystem support would simplify things greatly,
|
||||||
but having it gives us a mechanism of treating disk that lives on a
|
but having it gives us a mechanism of treating disk that lives on a
|
||||||
@ -68,7 +44,7 @@ details. */
|
|||||||
|
|
||||||
Each DOS drive is defined to have a current directory. Supporting
|
Each DOS drive is defined to have a current directory. Supporting
|
||||||
this would complicate things so for now things are defined so that
|
this would complicate things so for now things are defined so that
|
||||||
c: means c:\.
|
c: means c:\. FIXME: Is this still true?
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "winsup.h"
|
#include "winsup.h"
|
||||||
@ -90,14 +66,10 @@ details. */
|
|||||||
#include "pinfo.h"
|
#include "pinfo.h"
|
||||||
#include "cygheap.h"
|
#include "cygheap.h"
|
||||||
|
|
||||||
static int normalize_win32_path (const char *cwd, const char *src, char *dst);
|
static int normalize_win32_path (const char *src, char *dst);
|
||||||
static char *getcwd_inner (char *buf, size_t ulen, int posix_p, int with_chroot);
|
|
||||||
static void slashify (const char *src, char *dst, int trailing_slash_p);
|
static void slashify (const char *src, char *dst, int trailing_slash_p);
|
||||||
static void backslashify (const char *src, char *dst, int trailing_slash_p);
|
static void backslashify (const char *src, char *dst, int trailing_slash_p);
|
||||||
static int path_prefix_p_ (const char *path1, const char *path2, int len1);
|
static int path_prefix_p_ (const char *path1, const char *path2, int len1);
|
||||||
static int get_cwd_win32 ();
|
|
||||||
|
|
||||||
static NO_COPY const char escape_char = '^';
|
|
||||||
|
|
||||||
struct symlink_info
|
struct symlink_info
|
||||||
{
|
{
|
||||||
@ -113,7 +85,7 @@ struct symlink_info
|
|||||||
int check (const char *path, const suffix_info *suffixes);
|
int check (const char *path, const suffix_info *suffixes);
|
||||||
};
|
};
|
||||||
|
|
||||||
/********************** Path Helper Functions *************************/
|
cwdstuff cygcwd; /* The current working directory. */
|
||||||
|
|
||||||
#define path_prefix_p(p1, p2, l1) \
|
#define path_prefix_p(p1, p2, l1) \
|
||||||
((tolower(*(p1))==tolower(*(p2))) && \
|
((tolower(*(p1))==tolower(*(p2))) && \
|
||||||
@ -123,6 +95,20 @@ struct symlink_info
|
|||||||
(((x) & (FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_DIRECTORY)) == \
|
(((x) & (FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_DIRECTORY)) == \
|
||||||
FILE_ATTRIBUTE_SYSTEM)
|
FILE_ATTRIBUTE_SYSTEM)
|
||||||
|
|
||||||
|
/* Determine if path prefix matches current cygdrive */
|
||||||
|
#define iscygdrive(path) \
|
||||||
|
(path_prefix_p (cygwin_shared->mount.cygdrive, (path), cygwin_shared->mount.cygdrive_len))
|
||||||
|
|
||||||
|
#define iscygdrive_device(path) \
|
||||||
|
(iscygdrive(path) && isalpha(path[cygwin_shared->mount.cygdrive_len]) && \
|
||||||
|
(isdirsep(path[cygwin_shared->mount.cygdrive_len + 1]) || \
|
||||||
|
!path[cygwin_shared->mount.cygdrive_len + 1]))
|
||||||
|
|
||||||
|
#define ischrootpath(path) \
|
||||||
|
(myself->rootlen && \
|
||||||
|
strncasematch (myself->root, path, myself->rootlen) && \
|
||||||
|
(path[myself->rootlen] == '/' || path[myself->rootlen] == '\0'))
|
||||||
|
|
||||||
/* Return non-zero if PATH1 is a prefix of PATH2.
|
/* Return non-zero if PATH1 is a prefix of PATH2.
|
||||||
Both are assumed to be of the same path style and / vs \ usage.
|
Both are assumed to be of the same path style and / vs \ usage.
|
||||||
Neither may be "".
|
Neither may be "".
|
||||||
@ -137,91 +123,6 @@ struct symlink_info
|
|||||||
/foo is not a prefix of /foobar
|
/foo is not a prefix of /foobar
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Determine if path prefix matches current cygdrive */
|
|
||||||
#define iscygdrive(path) \
|
|
||||||
(path_prefix_p (cygwin_shared->mount.cygdrive, (path), cygwin_shared->mount.cygdrive_len))
|
|
||||||
|
|
||||||
#define iscygdrive_device(path) \
|
|
||||||
(iscygdrive(path) && isalpha(path[cygwin_shared->mount.cygdrive_len]) && \
|
|
||||||
(isdirsep(path[cygwin_shared->mount.cygdrive_len + 1]) || \
|
|
||||||
!path[cygwin_shared->mount.cygdrive_len + 1]))
|
|
||||||
|
|
||||||
/******************** Directory-related Support **************************/
|
|
||||||
|
|
||||||
/* Cache getcwd value. FIXME: We need a lock for these in order to
|
|
||||||
support multiple threads. */
|
|
||||||
|
|
||||||
#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 && \
|
|
||||||
strncasematch (myself->root, path, myself->rootlen) && \
|
|
||||||
(path[myself->rootlen] == '/' || path[myself->rootlen] == '\0'))
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
path_prefix_p_ (const char *path1, const char *path2, int len1)
|
path_prefix_p_ (const char *path1, const char *path2, int len1)
|
||||||
{
|
{
|
||||||
@ -621,12 +522,12 @@ win32_device_name (const char *src_path, char *win32_path,
|
|||||||
#define isslash(c) ((c) == '/')
|
#define isslash(c) ((c) == '/')
|
||||||
|
|
||||||
static int
|
static int
|
||||||
normalize_posix_path (const char *cwd, const char *src, char *dst)
|
normalize_posix_path (const char *src, char *dst)
|
||||||
{
|
{
|
||||||
const char *src_start = src;
|
const char *src_start = src;
|
||||||
char *dst_start = dst;
|
char *dst_start = dst;
|
||||||
|
|
||||||
syscall_printf ("cwd %s, src %s", cwd, src);
|
syscall_printf ("src %s", src);
|
||||||
if (isdrive (src) || strpbrk (src, "\\:"))
|
if (isdrive (src) || strpbrk (src, "\\:"))
|
||||||
{
|
{
|
||||||
cygwin_conv_to_full_posix_path (src, dst);
|
cygwin_conv_to_full_posix_path (src, dst);
|
||||||
@ -634,6 +535,8 @@ normalize_posix_path (const char *cwd, const char *src, char *dst)
|
|||||||
}
|
}
|
||||||
if (!isslash (src[0]))
|
if (!isslash (src[0]))
|
||||||
{
|
{
|
||||||
|
char cwd[MAX_PATH];
|
||||||
|
cygcwd.get (cwd); /* FIXME: check return value */
|
||||||
if (strlen (cwd) + 1 + strlen (src) >= MAX_PATH)
|
if (strlen (cwd) + 1 + strlen (src) >= MAX_PATH)
|
||||||
{
|
{
|
||||||
debug_printf ("ENAMETOOLONG = normalize_posix_path (%s)", src);
|
debug_printf ("ENAMETOOLONG = normalize_posix_path (%s)", src);
|
||||||
@ -727,7 +630,7 @@ normalize_posix_path (const char *cwd, const char *src, char *dst)
|
|||||||
The result is 0 for success, or an errno error value.
|
The result is 0 for success, or an errno error value.
|
||||||
FIXME: A lot of this should be mergeable with the POSIX critter. */
|
FIXME: A lot of this should be mergeable with the POSIX critter. */
|
||||||
static int
|
static int
|
||||||
normalize_win32_path (const char *cwd, const char *src, char *dst)
|
normalize_win32_path (const char *src, char *dst)
|
||||||
{
|
{
|
||||||
const char *src_start = src;
|
const char *src_start = src;
|
||||||
char *dst_start = dst;
|
char *dst_start = dst;
|
||||||
@ -735,6 +638,8 @@ normalize_win32_path (const char *cwd, const char *src, char *dst)
|
|||||||
|
|
||||||
if (!SLASH_P (src[0]) && strchr (src, ':') == NULL)
|
if (!SLASH_P (src[0]) && strchr (src, ':') == NULL)
|
||||||
{
|
{
|
||||||
|
char cwd[MAX_PATH];
|
||||||
|
cygcwd.get (cwd, 0); /* FIXME: check return value */
|
||||||
if (strlen (cwd) + 1 + strlen (src) >= MAX_PATH)
|
if (strlen (cwd) + 1 + strlen (src) >= MAX_PATH)
|
||||||
{
|
{
|
||||||
debug_printf ("ENAMETOOLONG = normalize_win32_path (%s)", src);
|
debug_printf ("ENAMETOOLONG = normalize_win32_path (%s)", src);
|
||||||
@ -1005,9 +910,6 @@ mount_info::conv_to_win32_path (const char *src_path, char *win32_path,
|
|||||||
mount_item *mi = NULL; /* initialized to avoid compiler warning */
|
mount_item *mi = NULL; /* initialized to avoid compiler warning */
|
||||||
char pathbuf[MAX_PATH];
|
char pathbuf[MAX_PATH];
|
||||||
|
|
||||||
char cwd[MAX_PATH];
|
|
||||||
getcwd_inner (cwd, MAX_PATH, TRUE, 0); /* FIXME: check rc */
|
|
||||||
|
|
||||||
/* Determine where the destination should be placed. */
|
/* Determine where the destination should be placed. */
|
||||||
if (full_win32_path != NULL)
|
if (full_win32_path != NULL)
|
||||||
dst = full_win32_path;
|
dst = full_win32_path;
|
||||||
@ -1022,7 +924,7 @@ mount_info::conv_to_win32_path (const char *src_path, char *win32_path,
|
|||||||
if (strpbrk (src_path, ":\\") != NULL)
|
if (strpbrk (src_path, ":\\") != NULL)
|
||||||
{
|
{
|
||||||
debug_printf ("%s already win32", src_path);
|
debug_printf ("%s already win32", src_path);
|
||||||
rc = normalize_win32_path (cwd_win32 (TMPCWD), src_path, dst);
|
rc = normalize_win32_path (src_path, dst);
|
||||||
if (rc)
|
if (rc)
|
||||||
{
|
{
|
||||||
debug_printf ("normalize_win32_path failed, rc %d", rc);
|
debug_printf ("normalize_win32_path failed, rc %d", rc);
|
||||||
@ -1065,10 +967,7 @@ mount_info::conv_to_win32_path (const char *src_path, char *win32_path,
|
|||||||
converting it to a DOS-style path, looking up the appropriate drive
|
converting it to a DOS-style path, looking up the appropriate drive
|
||||||
in the mount table. */
|
in the mount table. */
|
||||||
|
|
||||||
/* No need to fetch cwd if path is absolute. */
|
rc = normalize_posix_path (src_path, pathbuf);
|
||||||
isrelpath = !isslash (*src_path);
|
|
||||||
|
|
||||||
rc = normalize_posix_path (cwd, src_path, pathbuf);
|
|
||||||
|
|
||||||
if (rc)
|
if (rc)
|
||||||
{
|
{
|
||||||
@ -1077,6 +976,8 @@ mount_info::conv_to_win32_path (const char *src_path, char *win32_path,
|
|||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
isrelpath = !isslash (*src_path);
|
||||||
|
|
||||||
/* See if this is a cygwin "device" */
|
/* See if this is a cygwin "device" */
|
||||||
if (win32_device_name (pathbuf, dst, devn, unit))
|
if (win32_device_name (pathbuf, dst, devn, unit))
|
||||||
{
|
{
|
||||||
@ -1137,14 +1038,14 @@ mount_info::conv_to_win32_path (const char *src_path, char *win32_path,
|
|||||||
|
|
||||||
fillin:
|
fillin:
|
||||||
/* Compute relative path if asked to and able to. */
|
/* 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)
|
if (win32_path == NULL)
|
||||||
/* nothing to do */;
|
/* nothing to do */;
|
||||||
else if (isrelpath &&
|
else if (isrelpath)
|
||||||
path_prefix_p (cwd_win32_now, dst, cwdlen = strlen (cwd_win32_now)))
|
{
|
||||||
|
char cwd_win32[MAX_PATH];
|
||||||
|
cygcwd.get (cwd_win32, 0); /* FIXME: check return value someday */
|
||||||
|
unsigned cwdlen = strlen (cwd_win32);
|
||||||
|
if (path_prefix_p (cwd_win32, dst, cwdlen))
|
||||||
{
|
{
|
||||||
size_t n = strlen (dst);
|
size_t n = strlen (dst);
|
||||||
if (n < cwdlen)
|
if (n < cwdlen)
|
||||||
@ -1154,7 +1055,7 @@ fillin:
|
|||||||
if (n == cwdlen)
|
if (n == cwdlen)
|
||||||
dst += cwdlen;
|
dst += cwdlen;
|
||||||
else
|
else
|
||||||
dst += isdirsep (cwd_win32_now[cwdlen - 1]) ? cwdlen : cwdlen + 1;
|
dst += isdirsep (cwd_win32[cwdlen - 1]) ? cwdlen : cwdlen + 1;
|
||||||
|
|
||||||
memmove (win32_path, dst, strlen (dst) + 1);
|
memmove (win32_path, dst, strlen (dst) + 1);
|
||||||
if (!*win32_path)
|
if (!*win32_path)
|
||||||
@ -1165,6 +1066,7 @@ fillin:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
else if (win32_path != dst)
|
else if (win32_path != dst)
|
||||||
strcpy (win32_path, dst);
|
strcpy (win32_path, dst);
|
||||||
|
|
||||||
@ -1273,15 +1175,7 @@ mount_info::conv_to_posix_path (const char *src_path, char *posix_path,
|
|||||||
}
|
}
|
||||||
|
|
||||||
char pathbuf[MAX_PATH];
|
char pathbuf[MAX_PATH];
|
||||||
char cwd[MAX_PATH];
|
int rc = normalize_win32_path (src_path, pathbuf);
|
||||||
|
|
||||||
/* No need to fetch cwd if path is absolute. */
|
|
||||||
if (relative_path_p)
|
|
||||||
getcwd_inner (cwd, MAX_PATH, 0, 0); /* FIXME: check rc */
|
|
||||||
else
|
|
||||||
strcpy (cwd, "/"); /* some innocuous value */
|
|
||||||
|
|
||||||
int rc = normalize_win32_path (cwd, src_path, pathbuf);
|
|
||||||
if (rc != 0)
|
if (rc != 0)
|
||||||
{
|
{
|
||||||
debug_printf ("%d = conv_to_posix_path (%s)", rc, src_path);
|
debug_printf ("%d = conv_to_posix_path (%s)", rc, src_path);
|
||||||
@ -2513,9 +2407,9 @@ hash_path_name (unsigned long hash, const char *name)
|
|||||||
Otherwise the inodes same will differ depending on whether a file is
|
Otherwise the inodes same will differ depending on whether a file is
|
||||||
referenced with an absolute value or relatively. */
|
referenced with an absolute value or relatively. */
|
||||||
|
|
||||||
if (*name != '\\' && (cwd_win32 (TMPCWD) == NULL || get_cwd_win32 ()))
|
if (*name != '\\')
|
||||||
{
|
{
|
||||||
hash = cwd_hash ();
|
hash = cygcwd.get_hash ();
|
||||||
if (name[0] == '.' && name[1] == '\0')
|
if (name[0] == '.' && name[1] == '\0')
|
||||||
return hash;
|
return hash;
|
||||||
hash = hash_path_name (hash, "\\");
|
hash = hash_path_name (hash, "\\");
|
||||||
@ -2535,134 +2429,38 @@ hashit:
|
|||||||
return hash;
|
return hash;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
|
||||||
get_cwd_win32 ()
|
|
||||||
{
|
|
||||||
DWORD dlen, len;
|
|
||||||
|
|
||||||
cwd.lock->acquire ();
|
|
||||||
for (dlen = 256; ; dlen *= 2)
|
|
||||||
{
|
|
||||||
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.lock->release ();
|
|
||||||
return len;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* getcwd */
|
|
||||||
|
|
||||||
char *
|
|
||||||
getcwd_inner (char *buf, size_t ulen, int posix_p, int with_chroot)
|
|
||||||
{
|
|
||||||
char *resbuf = NULL;
|
|
||||||
size_t len = ulen;
|
|
||||||
|
|
||||||
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_now) >= len)
|
|
||||||
set_errno (ERANGE);
|
|
||||||
else
|
|
||||||
{
|
|
||||||
strcpy (buf, cwd_win32_now);
|
|
||||||
resbuf = buf;
|
|
||||||
}
|
|
||||||
|
|
||||||
syscall_printf ("%p (%s) = getcwd_inner (%p, %d, win32) (cached)",
|
|
||||||
resbuf, resbuf ? resbuf : "", buf, len);
|
|
||||||
return resbuf;
|
|
||||||
}
|
|
||||||
else if (cwd_posix_now != NULL)
|
|
||||||
{
|
|
||||||
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_now))
|
|
||||||
{
|
|
||||||
strcpy (buf, cwd_posix_now + myself->rootlen);
|
|
||||||
if (!buf[0])
|
|
||||||
strcpy (buf, "/");
|
|
||||||
resbuf = buf;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
strcpy (buf, cwd_posix_now);
|
|
||||||
resbuf = buf;
|
|
||||||
}
|
|
||||||
|
|
||||||
syscall_printf ("%p (%s) = getcwd_inner (%p, %d, posix) (cached)",
|
|
||||||
resbuf, resbuf ? resbuf : "", buf, len);
|
|
||||||
return resbuf;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* posix_p required and cwd_posix == NULL */
|
|
||||||
|
|
||||||
char temp[MAX_PATH];
|
|
||||||
|
|
||||||
/* Turn from Win32 style to our style. */
|
|
||||||
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.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);
|
|
||||||
if (!buf[0])
|
|
||||||
strcpy (buf, "/");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
strcpy (cwd.posix, temp);
|
|
||||||
|
|
||||||
cwd.lock->release ();
|
|
||||||
|
|
||||||
if (tlen >= ulen)
|
|
||||||
set_errno (ERANGE); /* len was too small */
|
|
||||||
else
|
|
||||||
{
|
|
||||||
strcpy (buf, temp);
|
|
||||||
resbuf = buf;
|
|
||||||
}
|
|
||||||
|
|
||||||
syscall_printf ("%p (%s) = getcwd_inner (%p, %d, %s)",
|
|
||||||
resbuf, resbuf ? resbuf : "",
|
|
||||||
buf, len, posix_p ? "posix" : "win32");
|
|
||||||
return resbuf;
|
|
||||||
}
|
|
||||||
|
|
||||||
char *
|
char *
|
||||||
getcwd (char *buf, size_t ulen)
|
getcwd (char *buf, size_t ulen)
|
||||||
{
|
{
|
||||||
char *res;
|
char *res;
|
||||||
|
char *usebuf, uselen;
|
||||||
|
|
||||||
if (buf == NULL || ulen == 0)
|
if (buf != NULL)
|
||||||
{
|
{
|
||||||
buf = (char *) alloca (MAX_PATH);
|
usebuf = buf;
|
||||||
res = getcwd_inner (buf, MAX_PATH, 1, 1);
|
uselen = TRUE;
|
||||||
res = strdup (buf);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
res = getcwd_inner (buf, ulen, 1, 1);
|
if (ulen >= 0)
|
||||||
|
uselen = TRUE;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
uselen = FALSE;
|
||||||
|
ulen = MAX_PATH + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
usebuf = (char *) malloc (ulen);
|
||||||
|
usebuf [ulen - 1] = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
|
res = cygcwd.get (usebuf, 1, 1, ulen);
|
||||||
|
|
||||||
|
if (res && !uselen)
|
||||||
|
usebuf = (char *) realloc (usebuf, strlen (usebuf) + 1);
|
||||||
|
else if (!res && buf == NULL)
|
||||||
|
free (usebuf);
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2704,27 +2502,12 @@ chdir (const char *dir)
|
|||||||
if (res == -1)
|
if (res == -1)
|
||||||
__seterrno ();
|
__seterrno ();
|
||||||
else
|
else
|
||||||
{
|
cygcwd.set (path);
|
||||||
cwd.lock->acquire ();
|
|
||||||
/* Store new cache information */
|
|
||||||
cfree (cwd.win32);
|
|
||||||
cwd.win32 = cstrdup (path);
|
|
||||||
|
|
||||||
char pathbuf[MAX_PATH];
|
/* Note that we're accessing cwd.posix without a lock here. I didn't think
|
||||||
(void) normalize_posix_path (cwd.posix, dir, pathbuf);
|
it was worth locking just for strace. */
|
||||||
/* Look for trailing path component consisting entirely of dots. This
|
syscall_printf ("%d = chdir() cygcwd.posix '%s' native '%s'", res,
|
||||||
is needed only in case of chdir since Windows simply ignores count
|
cygcwd.posix, native_dir);
|
||||||
of dots > 2 here instead of returning an error code. Counts of dots
|
|
||||||
<= 2 are already eliminated by normalize_posix_path. */
|
|
||||||
char *last_slash = strrchr (pathbuf, '/');
|
|
||||||
if (last_slash > pathbuf && strspn (last_slash + 1, ".") == strlen (last_slash + 1))
|
|
||||||
*last_slash = '\0';
|
|
||||||
cfree (cwd.posix);
|
|
||||||
cwd.posix = cstrdup (pathbuf);
|
|
||||||
cwd.lock->release ();
|
|
||||||
}
|
|
||||||
|
|
||||||
syscall_printf ("%d = chdir() cwd.posix '%s' native '%s'", res, cwd.posix, native_dir);
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3065,3 +2848,130 @@ check_null_empty_path (const char *name)
|
|||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Return the hash value for the current win32 value.
|
||||||
|
This is used when constructing inodes. */
|
||||||
|
DWORD
|
||||||
|
cwdstuff::get_hash ()
|
||||||
|
{
|
||||||
|
DWORD hashnow;
|
||||||
|
lock->acquire ();
|
||||||
|
hashnow = hash;
|
||||||
|
lock->release ();
|
||||||
|
return hashnow;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Initialize cygcwd 'muto' for serializing access to cwd info. */
|
||||||
|
void
|
||||||
|
cwdstuff::init ()
|
||||||
|
{
|
||||||
|
lock = new_muto (FALSE, "cwd");
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Called to fill in cwd values after an exec. */
|
||||||
|
void
|
||||||
|
cwdstuff::fixup_after_exec (char *win32_cwd, char *posix_cwd, DWORD hash_cwd)
|
||||||
|
{
|
||||||
|
win32 = win32_cwd;
|
||||||
|
posix = posix_cwd;
|
||||||
|
hash = hash_cwd;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Get initial cwd. Should only be called once in a
|
||||||
|
process tree. */
|
||||||
|
bool
|
||||||
|
cwdstuff::get_initial ()
|
||||||
|
{
|
||||||
|
lock->acquire ();
|
||||||
|
DWORD len, dlen;
|
||||||
|
|
||||||
|
int i;
|
||||||
|
for (i = 0, dlen = MAX_PATH, len = 0; i < 3; dlen *= 2, i++)
|
||||||
|
{
|
||||||
|
win32 = (char *) crealloc (win32, dlen + 2);
|
||||||
|
if ((len = GetCurrentDirectoryA (dlen, win32)) < dlen)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (len == 0)
|
||||||
|
{
|
||||||
|
__seterrno ();
|
||||||
|
lock->release ();
|
||||||
|
debug_printf ("get_initial_cwd failed, %E");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
set (NULL);
|
||||||
|
return 1; /* Leaves cwd lock unreleased */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Fill out the elements of a cwdstuff struct.
|
||||||
|
It is assumed that the lock for the cwd is acquired if
|
||||||
|
win32_cwd == NULL. */
|
||||||
|
void
|
||||||
|
cwdstuff::set (char *win32_cwd)
|
||||||
|
{
|
||||||
|
if (win32_cwd)
|
||||||
|
{
|
||||||
|
lock->acquire ();
|
||||||
|
win32 = (char *) crealloc (win32, strlen (win32_cwd) + 1);
|
||||||
|
strcpy (win32, win32_cwd);
|
||||||
|
}
|
||||||
|
|
||||||
|
hash = hash_path_name (0, win32);
|
||||||
|
|
||||||
|
/* Turn from Win32 style to our style. */
|
||||||
|
char temp[MAX_PATH];
|
||||||
|
cygwin_shared->mount.conv_to_posix_path (win32, temp, 0);
|
||||||
|
|
||||||
|
posix = (char *) crealloc (posix, strlen (temp) + 1);
|
||||||
|
strcpy (posix, temp);
|
||||||
|
|
||||||
|
if (win32_cwd)
|
||||||
|
lock->release ();
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Copy the value for either the posix or the win32 cwd into a buffer. */
|
||||||
|
char *
|
||||||
|
cwdstuff::get (char *buf, int need_posix, int with_chroot, unsigned ulen)
|
||||||
|
{
|
||||||
|
size_t len = ulen;
|
||||||
|
|
||||||
|
if (!get_initial ()) /* Get initial cwd and set cwd lock */
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
char *tocopy;
|
||||||
|
if (!need_posix)
|
||||||
|
tocopy = win32;
|
||||||
|
else
|
||||||
|
tocopy = with_chroot && ischrootpath(posix) ?
|
||||||
|
posix + myself->rootlen : posix;
|
||||||
|
|
||||||
|
debug_printf("myself->root: %s, posix: %s", myself->root, posix);
|
||||||
|
if (strlen (tocopy) >= ulen)
|
||||||
|
set_errno (ERANGE);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
strcpy (buf, tocopy);
|
||||||
|
if (!buf[0]) /* Should only happen when chroot */
|
||||||
|
strcpy (buf, "/");
|
||||||
|
}
|
||||||
|
|
||||||
|
lock->release ();
|
||||||
|
syscall_printf ("(%s) = cwdstuff::get (%p, %d, %d, %d)",
|
||||||
|
buf, buf, len, need_posix, with_chroot);
|
||||||
|
return buf;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Get copies of all cwdstuff elements. Used by spawn_guts. */
|
||||||
|
void
|
||||||
|
cwdstuff::copy (char * &posix_cwd, char * &win32_cwd, DWORD hash_cwd)
|
||||||
|
{
|
||||||
|
lock->acquire ();
|
||||||
|
get_initial (); /* FIXME: Check return someday */
|
||||||
|
posix_cwd = cstrdup (posix);
|
||||||
|
win32_cwd = cstrdup (win32);
|
||||||
|
hash_cwd = hash;
|
||||||
|
lock->release ();
|
||||||
|
}
|
||||||
|
@ -110,11 +110,6 @@ int __stdcall check_null_empty_path (const char *name);
|
|||||||
|
|
||||||
const char * __stdcall find_exec (const char *name, path_conv& buf, const char *winenv = "PATH=",
|
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);
|
int null_if_notfound = 0, const char **known_suffix = NULL);
|
||||||
void __stdcall cwd_init ();
|
|
||||||
char * __stdcall cwd_posix (char *);
|
|
||||||
char * __stdcall cwd_win32 (char *);
|
|
||||||
DWORD __stdcall cwd_hash ();
|
|
||||||
void __stdcall cwd_fixup_after_exec (char *, char *, DWORD);
|
|
||||||
|
|
||||||
/* Common macros for checking for invalid path names */
|
/* Common macros for checking for invalid path names */
|
||||||
|
|
||||||
@ -127,3 +122,24 @@ void __stdcall cwd_fixup_after_exec (char *, char *, DWORD);
|
|||||||
})
|
})
|
||||||
|
|
||||||
#define isdrive(s) (isalpha (*(s)) && (s)[1] == ':')
|
#define isdrive(s) (isalpha (*(s)) && (s)[1] == ':')
|
||||||
|
|
||||||
|
/* cwd cache stuff. */
|
||||||
|
|
||||||
|
class muto;
|
||||||
|
|
||||||
|
struct cwdstuff
|
||||||
|
{
|
||||||
|
char *posix;
|
||||||
|
char *win32;
|
||||||
|
DWORD hash;
|
||||||
|
muto *lock;
|
||||||
|
char *get (char *buf, int need_posix = 1, int with_chroot = 0, unsigned ulen = MAX_PATH);
|
||||||
|
DWORD get_hash ();
|
||||||
|
void init ();
|
||||||
|
void fixup_after_exec (char *win32, char *posix, DWORD hash);
|
||||||
|
bool get_initial ();
|
||||||
|
void copy (char * &posix_cwd, char * &win32_cwd, DWORD hash_cwd);
|
||||||
|
void set (char *win32_cwd);
|
||||||
|
};
|
||||||
|
|
||||||
|
extern cwdstuff cygcwd;
|
||||||
|
@ -505,10 +505,8 @@ spawn_guts (HANDLE hToken, const char * prog_arg, const char *const *argv,
|
|||||||
ciresrv.moreinfo->argc = newargv.argc;
|
ciresrv.moreinfo->argc = newargv.argc;
|
||||||
ciresrv.moreinfo->argv = newargv;
|
ciresrv.moreinfo->argv = newargv;
|
||||||
|
|
||||||
/* FIXME: Should lock cwd access here. */
|
cygcwd.copy (ciresrv.moreinfo->cwd_posix, ciresrv.moreinfo->cwd_win32,
|
||||||
ciresrv.moreinfo->cwd_posix = cwd_posix (NULL);
|
ciresrv.moreinfo->cwd_hash);
|
||||||
ciresrv.moreinfo->cwd_win32 = cwd_win32 (NULL);
|
|
||||||
ciresrv.moreinfo->cwd_hash = cwd_hash ();
|
|
||||||
|
|
||||||
ciresrv.moreinfo->environ = (char **) cmalloc (HEAP_ARGV, envsize (envp, 1));
|
ciresrv.moreinfo->environ = (char **) cmalloc (HEAP_ARGV, envsize (envp, 1));
|
||||||
char **c;
|
char **c;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user