[newlib-cygwin] Revamp acl_extended_fd/acl_extended_file to avoid open(2) call

Corinna Vinschen corinna@sourceware.org
Thu Mar 10 09:36:00 GMT 2016


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

commit f368589492fa19e62049f2f654e4127216515bc6
Author: Corinna Vinschen <corinna@vinschen.de>
Date:   Thu Mar 10 10:36:00 2016 +0100

    Revamp acl_extended_fd/acl_extended_file to avoid open(2) call
    
    Calling open from acl_extended_file{_nofollow} indiscriminately may hang
    if the file is a FIFO.  Ultimately the FIFO implementation needs a thorough
    rewrite, but for the time being we better do what stat(2) and friends do:
    Just create an fhandler directly.
    
    	* sec_posixacl.cc (__acl_extended_fh): New static function calling
    	fhandler::facl.
    	(acl_extended_fd): Just call __acl_extended_fh.
    	(__acl_extended_file): Take just a path_conv as parameter and
    	create temporary fhandler to call __acl_extended_fh.
    	(acl_extended_file): Create path_conv from incoming path and
    	call __acl_extended_file on it.
    	(acl_extended_file_nofollow): Ditto.
    
    Signed-off-by: Corinna Vinschen <corinna@vinschen.de>

Diff:
---
 winsup/cygwin/sec_posixacl.cc | 58 ++++++++++++++++++++++++++++++++-----------
 1 file changed, 44 insertions(+), 14 deletions(-)

diff --git a/winsup/cygwin/sec_posixacl.cc b/winsup/cygwin/sec_posixacl.cc
index 8760ad5..6345220 100644
--- a/winsup/cygwin/sec_posixacl.cc
+++ b/winsup/cygwin/sec_posixacl.cc
@@ -953,6 +953,22 @@ acl_error (int code)
   return acl_err_txt[code - ACL_MULTI_ERROR];
 }
 
+static int
+__acl_extended_fh (fhandler_base *fh)
+{
+  int ret = -1;
+
+  if (!fh->pc.has_acls ())
+    set_errno (ENOTSUP);
+  else
+    {
+      ret = fh->facl (GETACLCNT, 0, NULL);
+      if (ret >= 0)
+	ret = (ret > MIN_ACL_ENTRIES) ? 1 : 0;
+    }
+  return ret;
+}
+
 extern "C" int
 acl_extended_fd (int fd)
 {
@@ -961,12 +977,7 @@ acl_extended_fd (int fd)
       cygheap_fdget cfd (fd);
       if (cfd < 0)
 	__leave;
-      if (!cfd->pc.has_acls ())
-	{
-	  set_errno (ENOTSUP);
-	  __leave;
-	}
-      return cfd->facl (GETACLCNT, 0, NULL);
+      return __acl_extended_fh (cfd);
     }
   __except (EBADF) {}
   __endtry
@@ -974,26 +985,45 @@ acl_extended_fd (int fd)
 }
 
 static int
-__acl_extended_file (const char *path_p, mode_t follow)
+__acl_extended_file (path_conv &pc)
 {
-  int fd = open (path_p, O_RDONLY | O_CLOEXEC | follow);
-  if (fd < 0)
-    return -1;
-  int ret = acl_extended_fd (fd);
-  close (fd);
+  int ret = -1;
+
+  __try
+    {
+      if (pc.error)
+	set_errno (pc.error);
+      else if (!pc.exists ())
+	set_errno (ENOENT);
+      else
+	{
+	  fhandler_base *fh;
+
+	  if (!(fh = build_fh_pc (pc)))
+	    __leave;
+	  ret = __acl_extended_fh (fh);
+	  delete fh;
+	}
+    }
+  __except (EFAULT) {}
+  __endtry
   return ret;
 }
 
 extern "C" int
 acl_extended_file (const char *path_p)
 {
-  return __acl_extended_file (path_p, 0);
+  path_conv pc (path_p, PC_SYM_FOLLOW | PC_POSIX | PC_KEEP_HANDLE,
+		stat_suffixes);
+  return __acl_extended_file (pc);
 }
 
 extern "C" int
 acl_extended_file_nofollow (const char *path_p)
 {
-  return __acl_extended_file (path_p, O_NOFOLLOW);
+  path_conv pc (path_p, PC_SYM_NOFOLLOW | PC_POSIX | PC_KEEP_HANDLE,
+		stat_suffixes);
+  return __acl_extended_file (pc);
 }
 
 extern "C" acl_t



More information about the Cygwin-cvs mailing list