From: cgf AT cygnus DOT com (Christopher Faylor) Subject: Re: readlink 17 Nov 1998 05:55:58 -0800 Message-ID: <19981117082650.B18240.cygnus.cygwin32.developers@cygnus.com> References: Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii To: Kazuhiro Fujieda , cygwin32-developers AT cygnus DOT com I don't believe that this patch will handle the case of /a/b/c/d where c and d are both symlinks. -chris On Tue, Nov 17, 1998 at 04:04:47PM +0900, Kazuhiro Fujieda wrote: >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 > | HOKURIKU School of Information Science >o_/ 1990 Japan Advanced Institute of Science and Technology > -- cgf AT cygnus DOT com http://www.cygnus.com/