From: fujieda AT jaist DOT ac DOT jp (Kazuhiro Fujieda) Subject: readlink 16 Nov 1998 23:17:55 -0800 Message-ID: Mime-Version: 1.0 (generated by SEMI MIME-Edit 0.100 - "Shijima") Content-Type: text/plain; charset=US-ASCII To: cygwin32-developers AT cygnus DOT com 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