* cygcheck.cc (dirname): New static function.
(find_app_on_path): Use SYMLINK_MAX. Resolve symlink relative to link's location. Adjust to the fact that cygpath already normalizes its return value. * path.cc (rel_vconcat): Add cwd parameter, and use it instead of calling GetCurrentDirectory() if possible. Rename throughout. (vcygpath): Rename from cygpath and accept cwd and va_list. Pass cwd on to rel_vconcat(). (cygpath_rel): New front end for vcygpath. (cygpath): Ditto. * path.h (cygpath_rel): Declare. (SYMLINK_MAX): Define to 4095.
This commit is contained in:
parent
0c4cb56009
commit
60efa4e546
@ -1,3 +1,18 @@
|
|||||||
|
2008-03-11 Brian Dessent <brian@dessent.net>
|
||||||
|
|
||||||
|
* cygcheck.cc (dirname): New static function.
|
||||||
|
(find_app_on_path): Use SYMLINK_MAX. Resolve symlink relative
|
||||||
|
to link's location. Adjust to the fact that cygpath already
|
||||||
|
normalizes its return value.
|
||||||
|
* path.cc (rel_vconcat): Add cwd parameter, and use it instead
|
||||||
|
of calling GetCurrentDirectory() if possible. Rename throughout.
|
||||||
|
(vcygpath): Rename from cygpath and accept cwd and va_list. Pass
|
||||||
|
cwd on to rel_vconcat().
|
||||||
|
(cygpath_rel): New front end for vcygpath.
|
||||||
|
(cygpath): Ditto.
|
||||||
|
* path.h (cygpath_rel): Declare.
|
||||||
|
(SYMLINK_MAX): Define to 4095.
|
||||||
|
|
||||||
2008-03-09 Brian Dessent <brian@dessent.net>
|
2008-03-09 Brian Dessent <brian@dessent.net>
|
||||||
|
|
||||||
* Makefile.in (install): Don't install the testsuite.
|
* Makefile.in (install): Don't install the testsuite.
|
||||||
|
@ -807,6 +807,28 @@ ls (char *f)
|
|||||||
display_error ("ls: CloseHandle()");
|
display_error ("ls: CloseHandle()");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Remove filename from 's' and return directory name without trailing
|
||||||
|
backslash, or NULL if 's' doesn't seem to have a dirname. */
|
||||||
|
static char *
|
||||||
|
dirname (const char *s)
|
||||||
|
{
|
||||||
|
static char buf[MAX_PATH];
|
||||||
|
|
||||||
|
if (!s)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
strncpy (buf, s, MAX_PATH);
|
||||||
|
buf[MAX_PATH - 1] = '\0'; // in case strlen(s) > MAX_PATH
|
||||||
|
char *lastsep = strrchr (buf, '\\');
|
||||||
|
if (!lastsep)
|
||||||
|
return NULL; // no backslash -> no dirname
|
||||||
|
else if (lastsep - buf <= 2 && buf[1] == ':')
|
||||||
|
lastsep[1] = '\0'; // can't remove backslash of "x:\"
|
||||||
|
else
|
||||||
|
*lastsep = '\0';
|
||||||
|
return buf;
|
||||||
|
}
|
||||||
|
|
||||||
// Find a real application on the path (possibly following symlinks)
|
// Find a real application on the path (possibly following symlinks)
|
||||||
static const char *
|
static const char *
|
||||||
find_app_on_path (const char *app, bool showall = false)
|
find_app_on_path (const char *app, bool showall = false)
|
||||||
@ -821,26 +843,25 @@ find_app_on_path (const char *app, bool showall = false)
|
|||||||
|
|
||||||
if (is_symlink (fh))
|
if (is_symlink (fh))
|
||||||
{
|
{
|
||||||
static char tmp[4000] = "";
|
static char tmp[SYMLINK_MAX];
|
||||||
char *ptr;
|
if (!readlink (fh, tmp, SYMLINK_MAX))
|
||||||
if (!readlink (fh, tmp, 3999))
|
|
||||||
display_error("readlink failed");
|
display_error("readlink failed");
|
||||||
ptr = cygpath (tmp, NULL);
|
|
||||||
for (char *p = ptr; (p = strchr (p, '/')); p++)
|
/* Resolve the linkname relative to the directory of the link. */
|
||||||
*p = '\\';
|
char *ptr = cygpath_rel (dirname (papp), tmp, NULL);
|
||||||
printf (" -> %s\n", ptr);
|
printf (" -> %s\n", ptr);
|
||||||
if (!strchr (ptr, '\\'))
|
if (!strchr (ptr, '\\'))
|
||||||
{
|
{
|
||||||
char *lastsep;
|
char *lastsep;
|
||||||
strncpy (tmp, cygpath (papp, NULL), 3999);
|
strncpy (tmp, cygpath (papp, NULL), SYMLINK_MAX - 1);
|
||||||
for (char *p = tmp; (p = strchr (p, '/')); p++)
|
|
||||||
*p = '\\';
|
|
||||||
lastsep = strrchr (tmp, '\\');
|
lastsep = strrchr (tmp, '\\');
|
||||||
strncpy (lastsep+1, ptr, 3999-(lastsep-tmp));
|
strncpy (lastsep+1, ptr, SYMLINK_MAX - 1 - (lastsep-tmp));
|
||||||
ptr = tmp;
|
ptr = tmp;
|
||||||
}
|
}
|
||||||
if (!CloseHandle (fh))
|
if (!CloseHandle (fh))
|
||||||
display_error ("find_app_on_path: CloseHandle()");
|
display_error ("find_app_on_path: CloseHandle()");
|
||||||
|
/* FIXME: We leak the ptr returned by cygpath() here which is a
|
||||||
|
malloc()d string. */
|
||||||
return find_app_on_path (ptr, showall);
|
return find_app_on_path (ptr, showall);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -486,26 +486,35 @@ unconvert_slashes (char* name)
|
|||||||
*name++ = '\\';
|
*name++ = '\\';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* This is a helper function for when vcygpath is passed what appears
|
||||||
|
to be a relative POSIX path. We take a Win32 CWD (either as specified
|
||||||
|
in 'cwd' or as retrieved with GetCurrentDirectory() if 'cwd' is NULL)
|
||||||
|
and find the mount table entry with the longest match. We replace the
|
||||||
|
matching portion with the corresponding POSIX prefix, and to that append
|
||||||
|
's' and anything in 'v'. The returned result is a mostly-POSIX
|
||||||
|
absolute path -- 'mostly' because the portions of CWD that didn't
|
||||||
|
match the mount prefix will still have '\\' separators. */
|
||||||
static char *
|
static char *
|
||||||
rel_vconcat (const char *s, va_list v)
|
rel_vconcat (const char *cwd, const char *s, va_list v)
|
||||||
{
|
{
|
||||||
char path[MAX_PATH + 1];
|
char pathbuf[MAX_PATH];
|
||||||
if (!GetCurrentDirectory (MAX_PATH, path))
|
if (!cwd || *cwd == '\0')
|
||||||
return NULL;
|
{
|
||||||
|
if (!GetCurrentDirectory (MAX_PATH, pathbuf))
|
||||||
|
return NULL;
|
||||||
|
cwd = pathbuf;
|
||||||
|
}
|
||||||
|
|
||||||
int max_len = -1;
|
int max_len = -1;
|
||||||
struct mnt *m, *match = NULL;
|
struct mnt *m, *match = NULL;
|
||||||
|
|
||||||
if (s[0] == '.' && isslash (s[1]))
|
for (m = mount_table; m->posix; m++)
|
||||||
s += 2;
|
|
||||||
|
|
||||||
for (m = mount_table; m->posix ; m++)
|
|
||||||
{
|
{
|
||||||
if (m->flags & MOUNT_CYGDRIVE)
|
if (m->flags & MOUNT_CYGDRIVE)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
int n = strlen (m->native);
|
int n = strlen (m->native);
|
||||||
if (n < max_len || !path_prefix_p (m->native, path, n))
|
if (n < max_len || !path_prefix_p (m->native, cwd, n))
|
||||||
continue;
|
continue;
|
||||||
max_len = n;
|
max_len = n;
|
||||||
match = m;
|
match = m;
|
||||||
@ -514,34 +523,36 @@ rel_vconcat (const char *s, va_list v)
|
|||||||
char *temppath;
|
char *temppath;
|
||||||
if (!match)
|
if (!match)
|
||||||
// No prefix matched - best effort to return meaningful value.
|
// No prefix matched - best effort to return meaningful value.
|
||||||
temppath = concat (path, "/", s, NULL);
|
temppath = concat (cwd, "/", s, NULL);
|
||||||
else if (strcmp (match->posix, "/") != 0)
|
else if (strcmp (match->posix, "/") != 0)
|
||||||
// Matched on non-root. Copy matching prefix + remaining 'path'.
|
// Matched on non-root. Copy matching prefix + remaining 'path'.
|
||||||
temppath = concat (match->posix, path + max_len, "/", s, NULL);
|
temppath = concat (match->posix, cwd + max_len, "/", s, NULL);
|
||||||
else if (path[max_len] == '\0')
|
else if (cwd[max_len] == '\0')
|
||||||
// Matched on root and there's no remaining 'path'.
|
// Matched on root and there's no remaining 'path'.
|
||||||
temppath = concat ("/", s, NULL);
|
temppath = concat ("/", s, NULL);
|
||||||
else if (isslash (path[max_len]))
|
else if (isslash (cwd[max_len]))
|
||||||
// Matched on root but remaining 'path' starts with a slash anyway.
|
// Matched on root but remaining 'path' starts with a slash anyway.
|
||||||
temppath = concat (path + max_len, "/", s, NULL);
|
temppath = concat (cwd + max_len, "/", s, NULL);
|
||||||
else
|
else
|
||||||
temppath = concat ("/", path + max_len, "/", s, NULL);
|
temppath = concat ("/", cwd + max_len, "/", s, NULL);
|
||||||
|
|
||||||
char *res = vconcat (temppath, v);
|
char *res = vconcat (temppath, v);
|
||||||
free (temppath);
|
free (temppath);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
char *
|
/* Convert a POSIX path in 's' to an absolute Win32 path, and append
|
||||||
cygpath (const char *s, ...)
|
anything in 'v' to the end, returning the result. If 's' is a
|
||||||
|
relative path then 'cwd' is used as the working directory to make
|
||||||
|
it absolute. Pass NULL in 'cwd' to use GetCurrentDirectory. */
|
||||||
|
static char *
|
||||||
|
vcygpath (const char *cwd, const char *s, va_list v)
|
||||||
{
|
{
|
||||||
va_list v;
|
|
||||||
int max_len = -1;
|
int max_len = -1;
|
||||||
struct mnt *m, *match = NULL;
|
struct mnt *m, *match = NULL;
|
||||||
|
|
||||||
if (!mount_table[0].posix)
|
if (!mount_table[0].posix)
|
||||||
read_mounts ();
|
read_mounts ();
|
||||||
va_start (v, s);
|
|
||||||
char *path;
|
char *path;
|
||||||
if (s[0] == '.' && isslash (s[1]))
|
if (s[0] == '.' && isslash (s[1]))
|
||||||
s += 2;
|
s += 2;
|
||||||
@ -549,7 +560,7 @@ cygpath (const char *s, ...)
|
|||||||
if (s[0] == '/' || s[1] == ':') /* FIXME: too crude? */
|
if (s[0] == '/' || s[1] == ':') /* FIXME: too crude? */
|
||||||
path = vconcat (s, v);
|
path = vconcat (s, v);
|
||||||
else
|
else
|
||||||
path = rel_vconcat (s, v);
|
path = rel_vconcat (cwd, s, v);
|
||||||
|
|
||||||
if (!path)
|
if (!path)
|
||||||
return NULL;
|
return NULL;
|
||||||
@ -557,7 +568,7 @@ cygpath (const char *s, ...)
|
|||||||
if (strncmp (path, "/./", 3) == 0)
|
if (strncmp (path, "/./", 3) == 0)
|
||||||
memmove (path + 1, path + 3, strlen (path + 3) + 1);
|
memmove (path + 1, path + 3, strlen (path + 3) + 1);
|
||||||
|
|
||||||
for (m = mount_table; m->posix ; m++)
|
for (m = mount_table; m->posix; m++)
|
||||||
{
|
{
|
||||||
if (m->flags & MOUNT_CYGDRIVE)
|
if (m->flags & MOUNT_CYGDRIVE)
|
||||||
continue;
|
continue;
|
||||||
@ -586,6 +597,26 @@ cygpath (const char *s, ...)
|
|||||||
return native;
|
return native;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
char *
|
||||||
|
cygpath_rel (const char *cwd, const char *s, ...)
|
||||||
|
{
|
||||||
|
va_list v;
|
||||||
|
|
||||||
|
va_start (v, s);
|
||||||
|
|
||||||
|
return vcygpath (cwd, s, v);
|
||||||
|
}
|
||||||
|
|
||||||
|
char *
|
||||||
|
cygpath (const char *s, ...)
|
||||||
|
{
|
||||||
|
va_list v;
|
||||||
|
|
||||||
|
va_start (v, s);
|
||||||
|
|
||||||
|
return vcygpath (NULL, s, v);
|
||||||
|
}
|
||||||
|
|
||||||
static mnt *m = NULL;
|
static mnt *m = NULL;
|
||||||
|
|
||||||
extern "C" FILE *
|
extern "C" FILE *
|
||||||
|
@ -9,9 +9,11 @@ Cygwin license. Please consult the file "CYGWIN_LICENSE" for
|
|||||||
details. */
|
details. */
|
||||||
|
|
||||||
char *cygpath (const char *s, ...);
|
char *cygpath (const char *s, ...);
|
||||||
|
char *cygpath_rel (const char *cwd, const char *s, ...);
|
||||||
bool is_exe (HANDLE);
|
bool is_exe (HANDLE);
|
||||||
bool is_symlink (HANDLE);
|
bool is_symlink (HANDLE);
|
||||||
bool readlink (HANDLE, char *, int);
|
bool readlink (HANDLE, char *, int);
|
||||||
int get_word (HANDLE, int);
|
int get_word (HANDLE, int);
|
||||||
int get_dword (HANDLE, int);
|
int get_dword (HANDLE, int);
|
||||||
|
|
||||||
|
#define SYMLINK_MAX 4095 /* PATH_MAX - 1 */
|
||||||
|
Loading…
x
Reference in New Issue
Block a user