delorie.com/archives/browse.cgi   search  
Mail Archives: cygwin-developers/1998/11/16/23:17:55

From: fujieda AT jaist DOT ac DOT jp (Kazuhiro Fujieda)
Subject: readlink
16 Nov 1998 23:17:55 -0800 :
Message-ID: <uaf1qdckw.fsf.cygnus.cygwin32.developers@parvati.will.or.jp>
Mime-Version: 1.0 (generated by SEMI MIME-Edit 0.100 - "Shijima")
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 <fujieda AT jaist DOT ac DOT jp>
  | HOKURIKU  School of Information Science
o_/ 1990      Japan Advanced Institute of Science and Technology

- Raw text -


  webmaster     delorie software   privacy  
  Copyright © 2019   by DJ Delorie     Updated Jul 2019