[newlib-cygwin] Cygwin: readlinkat: allow pathname to be empty

Ken Brown kbrown@sourceware.org
Mon Jan 20 14:48:00 GMT 2020


https://sourceware.org/git/gitweb.cgi?p=newlib-cygwin.git;h=6cc05784e16af56750417b73d778efb09c3b122e

commit 6cc05784e16af56750417b73d778efb09c3b122e
Author: Ken Brown <kbrown@cornell.edu>
Date:   Fri Dec 27 17:17:35 2019 -0500

    Cygwin: readlinkat: allow pathname to be empty
    
    Following Linux, allow the pathname argument to be an empty string,
    provided the dirfd argument refers to a symlink opened with
    O_PATH | O_NOFOLLOW.  The readlinkat call then operates on that
    symlink.

Diff:
---
 winsup/cygwin/syscalls.cc | 19 +++++++++++++++++--
 1 file changed, 17 insertions(+), 2 deletions(-)

diff --git a/winsup/cygwin/syscalls.cc b/winsup/cygwin/syscalls.cc
index 038a316..282d9e0 100644
--- a/winsup/cygwin/syscalls.cc
+++ b/winsup/cygwin/syscalls.cc
@@ -4979,8 +4979,23 @@ readlinkat (int dirfd, const char *__restrict pathname, char *__restrict buf,
   __try
     {
       char *path = tp.c_get ();
-      if (gen_full_path_at (path, dirfd, pathname))
-	__leave;
+      int res = gen_full_path_at (path, dirfd, pathname);
+      if (res)
+	{
+	  if (errno != ENOENT)
+	    __leave;
+	  /* pathname is an empty string.  This is OK if dirfd refers
+	     to a symlink that was opened with O_PATH | O_NOFOLLOW.
+	     In this case, readlinkat operates on the symlink. */
+	  cygheap_fdget cfd (dirfd);
+	  if (cfd < 0)
+	    __leave;
+	  if (!(cfd->issymlink ()
+		&& cfd->get_flags () & O_PATH
+		&& cfd->get_flags () & O_NOFOLLOW))
+	    __leave;
+	  strcpy (path, cfd->get_name ());
+	}
       return readlink (path, buf, bufsize);
     }
   __except (EFAULT) {}



More information about the Cygwin-cvs mailing list