Mail Archives: cygwin-developers/1998/11/16/23:17:55
The result of readlink() in Cygwin is obviously different from
it specified by POSIX. readlink() should not follow symlinks nor
expand to its absolute path.
For example, in POSIX environment,
$ ln -s foo bar
$ ln -s foobar foo
$ ls -l bar
lrwxrwxrwx 1 fujieda is 6 Nov 17 14:14 bar -> foo
but in Cygwin environment,
$ ls -l bar
lrw-r--r-- 1 fujieda everyone 17 Nov 17 14:10 bar -> /Home/fujieda/foobar
The following is the dirty patch for winsup-981111 to solve this
problem. Notice that this patch stop setting symlink_p to -1
because readlink() no longer use this flag.
diff -u winsup-981111/fhandler.cc winsup/fhandler.cc
--- winsup-981111/fhandler.cc Sun Oct 25 10:21:32 1998
+++ winsup/fhandler.cc Mon Nov 16 18:55:21 1998
@@ -834,7 +834,7 @@
if (get_file_attribute (get_win32_name (), (int *) &buf->st_mode) > 0)
{
buf->st_mode &= ~S_IFMT;
- if (get_symlink_p () > 0)
+ if (get_symlink_p ())
buf->st_mode |= S_IFLNK;
else
buf->st_mode |= S_IFREG;
@@ -848,7 +848,7 @@
buf->st_mode |= STD_WBITS;
/* | S_IWGRP | S_IWOTH; we don't give write to group etc */
- if (get_symlink_p () > 0)
+ if (get_symlink_p ())
buf->st_mode |= S_IFLNK;
else
switch (GetFileType (get_handle ()))
@@ -1098,7 +1098,7 @@
if (flags & O_APPEND)
SetFilePointer (get_handle(), 0, 0, FILE_END);
- set_symlink_p (real_path.symlink_p > 0);
+ set_symlink_p (real_path.symlink_p);
set_execable_p (real_path.exec_p);
out:
diff -u winsup-981111/path.cc winsup/path.cc
--- winsup-981111/path.cc Wed Oct 28 10:36:29 1998
+++ winsup/path.cc Tue Nov 17 15:59:20 1998
@@ -287,9 +287,7 @@
{
if (component == 0)
{
- if (follow_mode)
- symlink_p = -1;
- else
+ if (!follow_mode)
{
symlink_p = 1; // last component of path was a symlink.
fileattr = attr;
@@ -1606,33 +1604,27 @@
int
readlink (const char *path, char *buf, int buflen)
{
- path_conv pathbuf (path, 1);
+ path_conv pathbuf (path, -1);
if (pathbuf.error)
{
set_errno (pathbuf.error);
- syscall_printf ("-1 = readlink (%s, %p, %d)", path, buf, buflen);
- return -1;
- }
-
- if (!pathbuf.symlink_p)
- return -1;
-
- char *win32_name = pathbuf.get_win32 ();
- if (buflen >= MAX_PATH)
- {
- if (cygwin_shared->mount.conv_to_posix_path (win32_name, buf, 1))
- return -1;
- }
- else
- {
- char buf1[MAX_PATH];
- if (cygwin_shared->mount.conv_to_posix_path (win32_name, buf1, 1))
- return -1;
- strncpy (buf, buf1, buflen);
+ goto out;
}
+ int len;
+ char sym_buf[MAX_PATH];
+ len = symlink_check_one (pathbuf.get_win32(), sym_buf, MAX_PATH,
+ pathbuf.fileattr, &pathbuf.exec_p,
+ NULL, pathbuf.known_suffix);
/* errno set by symlink_check_one if error */
+ if (len <= 0)
+ goto out;
+
+ strncpy (buf, sym_buf, buflen);
return strlen (buf);
+out:
+ syscall_printf ("-1 = readlink (%s, %p, %d)", path, buf, buflen);
+ return -1;
}
/* Mount table system calls.
____
| AIST Kazuhiro Fujieda <fujieda AT jaist DOT ac DOT jp>
| HOKURIKU School of Information Science
o_/ 1990 Japan Advanced Institute of Science and Technology
- Raw text -