summaryrefslogtreecommitdiffstats
path: root/winsup/cygwin
diff options
context:
space:
mode:
authorChristopher Faylor <me@cgf.cx>2000-04-13 22:43:48 +0000
committerChristopher Faylor <me@cgf.cx>2000-04-13 22:43:48 +0000
commit2cf9359a8af319a2cd3d0788664ffc6140bbec9f (patch)
tree5ce54b75d64c9c70bb165b9a704df0d8b7fc8689 /winsup/cygwin
parent8a06963c1c19b7267316e7d81b46efe6f1b978cc (diff)
downloadcygnal-2cf9359a8af319a2cd3d0788664ffc6140bbec9f.tar.gz
cygnal-2cf9359a8af319a2cd3d0788664ffc6140bbec9f.tar.bz2
cygnal-2cf9359a8af319a2cd3d0788664ffc6140bbec9f.zip
* dcrt0.cc (insert_file): Avoid freeing previously allocated argument list.
* path.cc (symlink_info::check): Rename from symlink_check_one. Use new symlink_info struct for communication. (path_conv::path_conv): Use symlink_info structure for communication with symlink_info::check. Fix typo which resulted in symbolic links always being resolved. (readlink): Use stat_suffixes array when resolving a link. * syscalls.cc (stat_suffixes): Make global.
Diffstat (limited to 'winsup/cygwin')
-rw-r--r--winsup/cygwin/ChangeLog12
-rw-r--r--winsup/cygwin/Makefile.in1
-rw-r--r--winsup/cygwin/dcrt0.cc11
-rw-r--r--winsup/cygwin/path.cc126
-rw-r--r--winsup/cygwin/syscalls.cc2
5 files changed, 83 insertions, 69 deletions
diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog
index c630be808..f2da24eeb 100644
--- a/winsup/cygwin/ChangeLog
+++ b/winsup/cygwin/ChangeLog
@@ -1,3 +1,15 @@
+Thu Apr 13 18:32:26 2000 Christopher Faylor <cgf@cygnus.com>
+
+ * dcrt0.cc (insert_file): Avoid freeing previously allocated argument
+ list.
+ * path.cc (symlink_info::check): Rename from symlink_check_one. Use
+ new symlink_info struct for communication.
+ (path_conv::path_conv): Use symlink_info structure for communication
+ with symlink_info::check. Fix typo which resulted in symbolic links
+ always being resolved.
+ (readlink): Use stat_suffixes array when resolving a link.
+ * syscalls.cc (stat_suffixes): Make global.
+
Thu Apr 13 20:50:00 2000 Corinna Vinschen <corinna@vinschen.de>
* include/cygwin/version.h: Bump minor api to reflect export change.
diff --git a/winsup/cygwin/Makefile.in b/winsup/cygwin/Makefile.in
index bcfa67d30..6305640a5 100644
--- a/winsup/cygwin/Makefile.in
+++ b/winsup/cygwin/Makefile.in
@@ -338,4 +338,3 @@ uname.o: $(WINSUP_H)
wait.o: $(WINSUP_H)
window.o: $(WINSUP_H)
thread.o: $(WINSUP_H)
-
diff --git a/winsup/cygwin/dcrt0.cc b/winsup/cygwin/dcrt0.cc
index 0a5c080ff..5fd9cd4b1 100644
--- a/winsup/cygwin/dcrt0.cc
+++ b/winsup/cygwin/dcrt0.cc
@@ -185,7 +185,7 @@ host_dependent_constants::init ()
* -@foo and not the contents of foo.
*/
static int __stdcall
-insert_file (char *name, char *&cmd)
+insert_file (char *name, char *&cmd, int& alloc_cmd)
{
HANDLE f;
DWORD size;
@@ -378,7 +378,7 @@ static void __stdcall
build_argv (char *cmd, char **&argv, int &argc, int winshell)
{
int argvlen = 0;
- char *alloc_cmd = NULL; // command allocated by insert_file
+ int alloc_cmd = 0; // command allocated by insert_file
int nesting = 0; // monitor "nesting" from insert_file
argc = 0;
@@ -420,13 +420,8 @@ build_argv (char *cmd, char **&argv, int &argc, int winshell)
{
if (++nesting > MAX_AT_FILE_LEVEL)
api_fatal ("Too many levels of nesting for %s", word);
- if (insert_file (word, cmd))
- {
- if (alloc_cmd)
- free (alloc_cmd); // Free space from previous insert_file
- alloc_cmd = cmd; // and remember it for next time.
+ if (insert_file (word, cmd, alloc_cmd))
continue; // There's new stuff in cmd now
- }
}
/* See if we need to allocate more space for argv */
diff --git a/winsup/cygwin/path.cc b/winsup/cygwin/path.cc
index 7cb022fa4..60b763899 100644
--- a/winsup/cygwin/path.cc
+++ b/winsup/cygwin/path.cc
@@ -87,10 +87,6 @@ details. */
#include "winsup.h"
#include <ctype.h>
-static int symlink_check_one (const char *path, char *buf, int buflen,
- DWORD& fileattr, unsigned *pflags,
- const suffix_info *suffixes,
- char *&found_suffix);
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);
static void slashify (const char *src, char *dst, int trailing_slash_p);
@@ -100,6 +96,19 @@ static int get_current_directory_name ();
static NO_COPY const char escape_char = '^';
+struct symlink_info
+{
+ char buf[3 + MAX_PATH * 3];
+ char *known_suffix;
+ char *ext_here;
+ char *contents;
+ unsigned pflags;
+ DWORD fileattr;
+ int is_symlink;
+ symlink_info (): known_suffix (NULL), contents (buf + MAX_PATH + 1) {}
+ int check (const char *path, const suffix_info *suffixes);
+};
+
/********************** Path Helper Functions *************************/
#define path_prefix_p(p1, p2, l1) \
@@ -183,9 +192,9 @@ path_conv::path_conv (const char *src, symlink_follow follow_mode,
/* This array is used when expanding symlinks. It is MAX_PATH * 2
in length so that we can hold the expanded symlink plus a
trailer. */
- char work_buf[MAX_PATH * 3 + 3];
char path_buf[MAX_PATH];
char path_copy[MAX_PATH];
+ symlink_info sym;
char *rel_path, *full_path;
@@ -197,7 +206,6 @@ path_conv::path_conv (const char *src, symlink_follow follow_mode,
else
rel_path = this->path, full_path = path_buf;
- char *sym_buf = work_buf + MAX_PATH + 1;
/* This loop handles symlink expansion. */
int loop = 0;
path_flags = 0;
@@ -241,47 +249,46 @@ path_conv::path_conv (const char *src, symlink_follow follow_mode,
tail = path_copy + 1 + (tail - full_path); // Point to end of copy
- *sym_buf = '\0'; // Paranoid
-
/* Scan path_copy from right to left looking either for a symlink
or an actual existing file. If an existing file is found, just
return. If a symlink is found exit the for loop.
Also: be careful to preserve the errno returned from
- symlink_check_one as the caller may need it. */
+ symlink.check as the caller may need it. */
/* FIXME: Do we have to worry about multiple \'s here? */
int component = 0; // Number of translated components
- DWORD attr;
+ sym.contents[0] = '\0';
+
for (;;)
{
save_errno s (0);
- unsigned dummy_flags, *fp;
const suffix_info *suff;
-
- /* Don't allow symlink_check_one to set anything in the path_conv
+
+ /* Don't allow symlink.check to set anything in the path_conv
class if we're working on an inner component of the path */
if (component)
{
- fp = &dummy_flags;
suff = NULL;
+ sym.pflags = 0;
}
else
{
- fp = &path_flags;
suff = suffixes;
+ sym.pflags = path_flags;
}
- MALLOC_CHECK;
- int len = symlink_check_one (path_copy, sym_buf, MAX_PATH, attr,
- fp, suff, known_suffix);
- MALLOC_CHECK;
- /* If symlink_check_one found an existing non-symlink file, then
+ int len = sym.check (path_copy, suff);
+
+ if (!component)
+ path_flags = sym.pflags;
+
+ /* If symlink.check found an existing non-symlink file, then
it returns a length of 0 and sets errno to EINVAL. It also sets
- any suffix found into `sym_buf'. */
- if (!len && get_errno () == EINVAL)
+ any suffix found into `ext_here'. */
+ if (!sym.is_symlink && sym.fileattr != (DWORD) -1)
{
if (component == 0)
{
- fileattr = attr;
+ fileattr = sym.fileattr;
goto fillin;
}
goto out; // file found
@@ -293,18 +300,19 @@ path_conv::path_conv (const char *src, symlink_follow follow_mode,
these operations again on the newly derived path. */
else if (len > 0)
{
- if (component != 0 && follow_mode != SYMLINK_FOLLOW)
+ if (component == 0 && follow_mode != SYMLINK_FOLLOW)
{
set_symlink (); // last component of path is a symlink.
- fileattr = attr;
+ fileattr = sym.fileattr;
if (follow_mode == SYMLINK_CONTENTS)
- strcpy (path, sym_buf);
+ strcpy (path, sym.contents);
goto fillin;
}
break;
}
- s.reset (); // remember errno from symlink_check_one
+ /* No existing file found. */
+ s.reset (); // remember errno from symlink.check
if (!(tail = strrchr (path_copy, '\\')) ||
(tail > path_copy && tail[-1] == ':'))
@@ -326,7 +334,7 @@ path_conv::path_conv (const char *src, symlink_follow follow_mode,
tail = full_path + (tail - path_copy);
int taillen = strlen (tail);
- int buflen = strlen (sym_buf);
+ int buflen = strlen (sym.contents);
if (buflen + taillen > MAX_PATH)
{
error = ENAMETOOLONG;
@@ -336,23 +344,23 @@ path_conv::path_conv (const char *src, symlink_follow follow_mode,
/* Copy tail of full_path to discovered symlink. */
char *p;
- for (p = sym_buf + buflen; *tail; tail++)
+ for (p = sym.contents + buflen; *tail; tail++)
*p++ = *tail == '\\' ? '/' : *tail;
*p = '\0';
/* If symlink referred to an absolute path, then we
- just use sym_buf and loop. Otherwise tack the head of
- path_copy before sym_buf and translate it back from a
+ just use sym.contents and loop. Otherwise tack the head of
+ path_copy before sym.contents and translate it back from a
Win32-style path to a POSIX-style one. */
- if (isabspath (sym_buf))
- src = sym_buf;
+ if (isabspath (sym.contents))
+ src = sym.contents;
else if (!(tail = strrchr (path_copy, '\\')))
system_printf ("problem parsing %s - '%s'", src, full_path);
else
{
char tmp_buf[MAX_PATH];
int headlen = 1 + tail - path_copy;
- p = sym_buf - headlen;
+ p = sym.contents - headlen;
memcpy (p, path_copy, headlen);
MALLOC_CHECK;
error = cygwin_shared->mount.conv_to_posix_path (p, tmp_buf, 1);
@@ -364,13 +372,13 @@ path_conv::path_conv (const char *src, symlink_follow follow_mode,
}
fillin:
- if (*sym_buf)
+ if (sym.known_suffix)
+ known_suffix = this->path + (sym.known_suffix - path_copy);
+ else if (sym.ext_here && follow_mode != SYMLINK_CONTENTS)
{
known_suffix = strchr (this->path, '\0');
- strcpy (known_suffix, sym_buf);
+ strcpy (known_suffix, sym.ext_here);
}
- else if (known_suffix)
- known_suffix = this->path + (known_suffix - path_copy);
out:
DWORD serial, volflags;
@@ -2126,14 +2134,12 @@ next_suffix (char *ext_here, const suffix_info *&suffixes)
Return -1 on error, 0 if PATH is not a symlink, or the length
stored into BUF if PATH is a symlink. */
-static int
-symlink_check_one (const char *in_path, char *buf, int buflen, DWORD& fileattr,
- unsigned *pflags, const suffix_info *suffixes, char *&known_suffix)
+int
+symlink_info::check (const char *in_path, const suffix_info *suffixes)
{
HANDLE h;
int res = 0;
- char extbuf[buflen + 5];
- char *ext_here;
+ char extbuf[MAX_PATH + 5];
const char *path = in_path;
if (!suffixes)
@@ -2149,7 +2155,8 @@ symlink_check_one (const char *in_path, char *buf, int buflen, DWORD& fileattr,
ext_here = strchr (path, '\0');
}
- *buf = '\0';
+ is_symlink = TRUE;
+
do
{
if (!next_suffix (ext_here, suffixes))
@@ -2178,7 +2185,7 @@ symlink_check_one (const char *in_path, char *buf, int buflen, DWORD& fileattr,
/* A symlink will have the `system' file attribute. */
/* Only files can be symlinks (which can be symlinks to directories). */
- if (!(*pflags & PATH_SYMLINK) && !SYMLINKATTR (fileattr))
+ if (!(pflags & PATH_SYMLINK) && !SYMLINKATTR (fileattr))
goto file_not_symlink;
/* Check the file's extended attributes, if it has any. */
@@ -2189,7 +2196,7 @@ symlink_check_one (const char *in_path, char *buf, int buflen, DWORD& fileattr,
if (!get_file_attribute (TRUE, path, &unixattr))
{
if (unixattr & STD_XBITS)
- *pflags |= PATH_EXEC;
+ pflags |= PATH_EXEC;
}
/* Open the file. */
@@ -2215,9 +2222,9 @@ syscall_printf ("ReadFile");
sizeof (cookie_buf)) == 0)
{
/* It's a symlink. */
- *pflags = PATH_SYMLINK;
+ pflags = PATH_SYMLINK;
- res = ReadFile (h, buf, buflen, &got, 0);
+ res = ReadFile (h, contents, MAX_PATH + 1, &got, 0);
if (!res)
set_errno (EIO);
else
@@ -2228,8 +2235,8 @@ syscall_printf ("ReadFile");
NUL. The length returned is the path without
*any* trailing NULs. We also have to handle (or
at least not die from) corrupted paths. */
- if (memchr (buf, 0, got) != NULL)
- res = strlen (buf);
+ if (memchr (contents, 0, got) != NULL)
+ res = strlen (contents);
else
res = got;
}
@@ -2238,16 +2245,16 @@ syscall_printf ("ReadFile");
&& memcmp (cookie_buf, SOCKET_COOKIE,
sizeof (cookie_buf)) == 0)
{
- *pflags |= PATH_SOCKET;
+ pflags |= PATH_SOCKET;
goto close_and_return;
}
else
{
/* Not a symlink, see if executable. */
- if (!(*pflags & PATH_EXEC) && got >= 2 &&
+ if (!(pflags & PATH_EXEC) && got >= 2 &&
((cookie_buf[0] == '#' && cookie_buf[1] == '!') ||
(cookie_buf[0] == ':' && cookie_buf[1] == '\n')))
- *pflags |= PATH_EXEC;
+ pflags |= PATH_EXEC;
close_and_return:
syscall_printf ("close_and_return");
CloseHandle (h);
@@ -2264,14 +2271,13 @@ syscall_printf ("breaking from loop");
file_not_symlink:
set_errno (EINVAL);
+ is_symlink = FALSE;
syscall_printf ("not a symlink");
- if (ext_here)
- strcpy (buf, ext_here);
res = 0;
out:
- syscall_printf ("%d = symlink_check_one (%s, %p, %d) (%p)",
- res, path, buf, buflen, *pflags);
+ syscall_printf ("%d = symlink.check (%s, %p) (%p)",
+ res, path, contents, pflags);
return res;
}
@@ -2282,7 +2288,9 @@ extern "C"
int
readlink (const char *path, char *buf, int buflen)
{
- path_conv pathbuf (path, SYMLINK_CONTENTS);
+ extern suffix_info stat_suffixes[];
+ path_conv pathbuf (path, SYMLINK_CONTENTS, 0, stat_suffixes);
+
if (pathbuf.error)
{
set_errno (pathbuf.error);
@@ -2306,7 +2314,7 @@ readlink (const char *path, char *buf, int buflen)
memcpy (buf, pathbuf.get_win32 (), len);
buf[len] = '\0';
- /* errno set by symlink_check_one if error */
+ /* errno set by symlink.check if error */
return len;
}
diff --git a/winsup/cygwin/syscalls.cc b/winsup/cygwin/syscalls.cc
index b2ac1e262..65583a330 100644
--- a/winsup/cygwin/syscalls.cc
+++ b/winsup/cygwin/syscalls.cc
@@ -960,7 +960,7 @@ stat_dev (DWORD devn, int unit, unsigned long ino, struct stat *buf)
return 0;
}
-static suffix_info stat_suffixes[] =
+suffix_info stat_suffixes[] =
{
suffix_info ("", 1),
suffix_info (".exe", 1),