Subject: bug#10639: BUG REPORT coreutils-8.15 Solaris 10 64bit

From: Bruno Haible <[email-masked]>
Date: Wed, 01 Feb 2012 11:22:23 +0100

Paul Eggert wrote:
> Thanks, can you please try the attached patch?

I find it overkill to change the code for HP-UX and NonStop systems
when the report is about Solaris. Also I think the structure of the loop
is not the problem; it is the code's reaction to
  acl("x", ACE_GETACL, 4, 0x3432A16E0)            Err#-1

Please, can you also try this patch?

2012-02-01  Bruno Haible  <[email-masked]>

        * lib/file-has-acl.c (file_has_acl) [Solaris]: Treat a failing
        acl()/facl() call for ACE_GETACL like a failing call for ACE_GETACLCNT.
        * lib/set-mode-acl.c (qset_acl) [Solaris]: Likewise.
        * lib/copy-acl.c (qcopy_acl)[Solaris]: Likewise.

--- lib/copy-acl.c.orig	Wed Feb  1 11:15:51 2012
+++ lib/copy-acl.c	Wed Feb  1 11:10:55 2012
@@ -235,10 +235,22 @@
           return -2;
         }
 
-      if ((source_desc != -1
-           ? facl (source_desc, ACE_GETACL, ace_count, ace_entries)
-           : acl (src_name, ACE_GETACL, ace_count, ace_entries))
-          == ace_count)
+      ret = (source_desc != -1
+             ? facl (source_desc, ACE_GETACL, ace_count, ace_entries)
+             : acl (src_name, ACE_GETACL, ace_count, ace_entries);
+      if (ret < 0)
+        {
+          free (ace_entries);
+          if (errno == ENOSYS || errno == EINVAL)
+            {
+              ace_count = 0;
+              ace_entries = NULL;
+              break;
+            }
+          else
+            return -2;
+        }
+      if (ret == ace_count)
         break;
       /* Huh? The number of ACL entries changed since the last call.
          Repeat.  */
--- lib/file-has-acl.c.orig	Wed Feb  1 11:15:51 2012
+++ lib/file-has-acl.c	Wed Feb  1 11:13:17 2012
@@ -588,6 +588,8 @@
 
         for (;;)
           {
+            int ret;
+
             count = acl (name, ACE_GETACLCNT, 0, NULL);
 
             if (count < 0)
@@ -618,7 +620,16 @@
                 errno = ENOMEM;
                 return -1;
               }
-            if (acl (name, ACE_GETACL, count, entries) == count)
+            ret = acl (name, ACE_GETACL, count, entries);
+            if (ret < 0)
+              {
+                free (entries);
+                if (errno == ENOSYS || errno == EINVAL)
+                  break;
+                else
+                  return -1;
+              }
+            if (ret == count)
               {
                 if (acl_ace_nontrivial (count, entries))
                   {
--- lib/set-mode-acl.c.orig	Wed Feb  1 11:15:51 2012
+++ lib/set-mode-acl.c	Wed Feb  1 11:15:26 2012
@@ -219,6 +219,8 @@
 
     for (;;)
       {
+        int ret;
+
         if (desc != -1)
           count = facl (desc, ACE_GETACLCNT, 0, NULL);
         else
@@ -234,10 +236,16 @@
             errno = ENOMEM;
             return -1;
           }
-        if ((desc != -1
-             ? facl (desc, ACE_GETACL, count, entries)
-             : acl (name, ACE_GETACL, count, entries))
-            == count)
+        ret = (desc != -1
+               ? facl (desc, ACE_GETACL, count, entries)
+               : acl (name, ACE_GETACL, count, entries));
+        if (ret < 0)
+          {
+            free (entries);
+            convention = -1;
+            break;
+          }
+        if (ret == count)
           {
             int i;