changeset 16383:531aa00a1e80

acl: Don't use ACL_CNT and similar ops, since they are unreliable. * lib/file-has-acl.c (file_has_acl) [HP-UX, NonStop Kernel]: Read the entries into a stack-allocated buffer directly. * lib/copy-acl.c (qcopy_acl) [HP-UX, NonStop Kernel]: Likewise.
author Paul Eggert <eggert@cs.ucla.edu>
date Mon, 20 Feb 2012 01:55:37 +0100
parents cc05dad27529
children dde8c368829d
files ChangeLog lib/copy-acl.c lib/file-has-acl.c
diffstat 3 files changed, 123 insertions(+), 164 deletions(-) [+]
line wrap: on
line diff
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,11 @@
+2012-02-19  Paul Eggert  <eggert@cs.ucla.edu>
+	    Bruno Haible  <bruno@clisp.org>
+
+	acl: Don't use ACL_CNT and similar ops, since they are unreliable.
+	* lib/file-has-acl.c (file_has_acl) [HP-UX, NonStop Kernel]: Read the
+	entries into a stack-allocated buffer directly.
+	* lib/copy-acl.c (qcopy_acl) [HP-UX, NonStop Kernel]: Likewise.
+
 2012-02-19  Paul Eggert  <eggert@cs.ucla.edu>
 	    Bruno Haible  <bruno@clisp.org>
 
--- a/lib/copy-acl.c
+++ b/lib/copy-acl.c
@@ -377,77 +377,49 @@
 
 #elif USE_ACL && HAVE_GETACL /* HP-UX */
 
+  struct acl_entry entries[NACLENTRIES];
   int count;
-  struct acl_entry entries[NACLENTRIES];
 # if HAVE_ACLV_H
+  struct acl aclv_entries[NACLVENTRIES];
   int aclv_count;
-  struct acl aclv_entries[NACLVENTRIES];
 # endif
   int did_chmod;
   int saved_errno;
   int ret;
 
-  for (;;)
-    {
-      count = (source_desc != -1
-               ? fgetacl (source_desc, 0, NULL)
-               : getacl (src_name, 0, NULL));
+  count = (source_desc != -1
+           ? fgetacl (source_desc, NACLENTRIES, entries)
+           : getacl (src_name, NACLENTRIES, entries));
 
-      if (count < 0)
-        {
-          if (errno == ENOSYS || errno == EOPNOTSUPP || errno == ENOTSUP)
-            {
-              count = 0;
-              break;
-            }
-          else
-            return -2;
-        }
-
-      if (count == 0)
-        break;
-
+  if (count < 0)
+    {
+      if (errno == ENOSYS || errno == EOPNOTSUPP || errno == ENOTSUP)
+        count = 0;
+      else
+        return -2;
+    }
+  else if (count > 0)
+    {
       if (count > NACLENTRIES)
         /* If NACLENTRIES cannot be trusted, use dynamic memory allocation.  */
         abort ();
-
-      if ((source_desc != -1
-           ? fgetacl (source_desc, count, entries)
-           : getacl (src_name, count, entries))
-          == count)
-        break;
-      /* Huh? The number of ACL entries changed since the last call.
-         Repeat.  */
     }
 
 # if HAVE_ACLV_H
-  for (;;)
-    {
-      aclv_count = acl ((char *) src_name, ACL_CNT, NACLVENTRIES, aclv_entries);
+  aclv_count = acl ((char *) src_name, ACL_GET, NACLVENTRIES, aclv_entries);
 
-      if (aclv_count < 0)
-        {
-          if (errno == ENOSYS || errno == EOPNOTSUPP || errno == EINVAL)
-            {
-              count = 0;
-              break;
-            }
-          else
-            return -2;
-        }
-
-      if (aclv_count == 0)
-        break;
-
+  if (aclv_count < 0)
+    {
+      if (errno == ENOSYS || errno == EOPNOTSUPP || errno == EINVAL)
+        count = 0;
+      else
+        return -2;
+    }
+  else if (aclv_count > 0)
+    {
       if (aclv_count > NACLVENTRIES)
         /* If NACLVENTRIES cannot be trusted, use dynamic memory allocation.  */
         abort ();
-
-      if (acl ((char *) src_name, ACL_GET, aclv_count, aclv_entries)
-          == aclv_count)
-        break;
-      /* Huh? The number of ACL entries changed since the last call.
-         Repeat.  */
     }
 # endif
 
@@ -558,36 +530,24 @@
 
 #elif USE_ACL && HAVE_ACLSORT /* NonStop Kernel */
 
+  struct acl entries[NACLENTRIES];
   int count;
-  struct acl entries[NACLENTRIES];
   int ret;
 
-  for (;;)
-    {
-      count = acl ((char *) src_name, ACL_CNT, NACLENTRIES, NULL);
+  count = acl ((char *) src_name, ACL_GET, NACLENTRIES, entries);
 
-      if (count < 0)
-        {
-          if (0)
-            {
-              count = 0;
-              break;
-            }
-          else
-            return -2;
-        }
-
-      if (count == 0)
-        break;
-
+  if (count < 0)
+    {
+      if (0)
+        count = 0;
+      else
+        return -2;
+    }
+  else if (count > 0)
+    {
       if (count > NACLENTRIES)
         /* If NACLENTRIES cannot be trusted, use dynamic memory allocation.  */
         abort ();
-
-      if (acl ((char *) src_name, ACL_GET, count, entries) == count)
-        break;
-      /* Huh? The number of ACL entries changed since the last call.
-         Repeat.  */
     }
 
   if (count == 0)
--- a/lib/file-has-acl.c
+++ b/lib/file-has-acl.c
@@ -728,38 +728,36 @@
 
 # elif HAVE_GETACL /* HP-UX */
 
-      for (;;)
-        {
-          int count;
-          struct acl_entry entries[NACLENTRIES];
+      {
+        struct acl_entry entries[NACLENTRIES];
+        int count;
 
-          count = getacl (name, 0, NULL);
+        count = getacl (name, NACLENTRIES, entries);
 
-          if (count < 0)
-            {
-              /* ENOSYS is seen on newer HP-UX versions.
-                 EOPNOTSUPP is typically seen on NFS mounts.
-                 ENOTSUP was seen on Quantum StorNext file systems (cvfs).  */
-              if (errno == ENOSYS || errno == EOPNOTSUPP || errno == ENOTSUP)
-                break;
-              else
-                return -1;
-            }
+        if (count < 0)
+          {
+            /* ENOSYS is seen on newer HP-UX versions.
+               EOPNOTSUPP is typically seen on NFS mounts.
+               ENOTSUP was seen on Quantum StorNext file systems (cvfs).  */
+            if (errno == ENOSYS || errno == EOPNOTSUPP || errno == ENOTSUP)
+              ;
+            else
+              return -1;
+          }
+        else if (count == 0)
+          return 0;
+        else /* count > 0 */
+          {
+            if (count > NACLENTRIES)
+              /* If NACLENTRIES cannot be trusted, use dynamic memory
+                 allocation.  */
+              abort ();
 
-          if (count == 0)
-            return 0;
+            /* If there are more than 3 entries, there cannot be only the
+               (uid,%), (%,gid), (%,%) entries.  */
+            if (count > 3)
+              return 1;
 
-          if (count > NACLENTRIES)
-            /* If NACLENTRIES cannot be trusted, use dynamic memory
-               allocation.  */
-            abort ();
-
-          /* If there are more than 3 entries, there cannot be only the
-             (uid,%), (%,gid), (%,%) entries.  */
-          if (count > 3)
-            return 1;
-
-          if (getacl (name, count, entries) == count)
             {
               struct stat statbuf;
 
@@ -768,47 +766,43 @@
 
               return acl_nontrivial (count, entries, &statbuf);
             }
-          /* Huh? The number of ACL entries changed since the last call.
-             Repeat.  */
-        }
+          }
+      }
 
 #  if HAVE_ACLV_H /* HP-UX >= 11.11 */
 
-      for (;;)
-        {
-          int count;
-          struct acl entries[NACLVENTRIES];
-
-          count = acl ((char *) name, ACL_CNT, NACLVENTRIES, entries);
+      {
+        struct acl entries[NACLVENTRIES];
+        int count;
 
-          if (count < 0)
-            {
-              /* EOPNOTSUPP is seen on NFS in HP-UX 11.11, 11.23.
-                 EINVAL is seen on NFS in HP-UX 11.31.  */
-              if (errno == ENOSYS || errno == EOPNOTSUPP || errno == EINVAL)
-                break;
-              else
-                return -1;
-            }
+        count = acl ((char *) name, ACL_GET, NACLVENTRIES, entries);
 
-          if (count == 0)
-            return 0;
-
-          if (count > NACLVENTRIES)
-            /* If NACLVENTRIES cannot be trusted, use dynamic memory
-               allocation.  */
-            abort ();
+        if (count < 0)
+          {
+            /* EOPNOTSUPP is seen on NFS in HP-UX 11.11, 11.23.
+               EINVAL is seen on NFS in HP-UX 11.31.  */
+            if (errno == ENOSYS || errno == EOPNOTSUPP || errno == EINVAL)
+              ;
+            else
+              return -1;
+          }
+        else if (count == 0)
+          return 0;
+        else /* count > 0 */
+          {
+            if (count > NACLVENTRIES)
+              /* If NACLVENTRIES cannot be trusted, use dynamic memory
+                 allocation.  */
+              abort ();
 
-          /* If there are more than 4 entries, there cannot be only the
-             four base ACL entries.  */
-          if (count > 4)
-            return 1;
+            /* If there are more than 4 entries, there cannot be only the
+               four base ACL entries.  */
+            if (count > 4)
+              return 1;
 
-          if (acl ((char *) name, ACL_GET, count, entries) == count)
             return aclv_nontrivial (count, entries);
-          /* Huh? The number of ACL entries changed since the last call.
-             Repeat.  */
-        }
+          }
+      }
 
 #  endif
 
@@ -885,39 +879,36 @@
 
 # elif HAVE_ACLSORT /* NonStop Kernel */
 
-      int count;
-      struct acl entries[NACLENTRIES];
-
-      for (;;)
-        {
-          count = acl ((char *) name, ACL_CNT, NACLENTRIES, NULL);
+      {
+        struct acl entries[NACLENTRIES];
+        int count;
 
-          if (count < 0)
-            {
-              if (errno == ENOSYS || errno == ENOTSUP)
-                break;
-              else
-                return -1;
-            }
+        count = acl ((char *) name, ACL_GET, NACLENTRIES, entries);
 
-          if (count == 0)
-            return 0;
-
-          if (count > NACLENTRIES)
-            /* If NACLENTRIES cannot be trusted, use dynamic memory
-               allocation.  */
-            abort ();
+        if (count < 0)
+          {
+            if (errno == ENOSYS || errno == ENOTSUP)
+              ;
+            else
+              return -1;
+          }
+        else if (count == 0)
+          return 0;
+        else /* count > 0 */
+          {
+            if (count > NACLENTRIES)
+              /* If NACLENTRIES cannot be trusted, use dynamic memory
+                 allocation.  */
+              abort ();
 
-          /* If there are more than 4 entries, there cannot be only the
-             four base ACL entries.  */
-          if (count > 4)
-            return 1;
+            /* If there are more than 4 entries, there cannot be only the
+               four base ACL entries.  */
+            if (count > 4)
+              return 1;
 
-          if (acl ((char *) name, ACL_GET, count, entries) == count)
             return acl_nontrivial (count, entries);
-          /* Huh? The number of ACL entries changed since the last call.
-             Repeat.  */
-        }
+          }
+      }
 
 # endif
     }