changeset 11546:03ef9ae804c9

acl: Fix infinite loop on FreeBSD.
author David Bartley <dtbartle@csclub.uwaterloo.ca>
date Mon, 04 May 2009 03:30:54 +0200
parents 1eacfad75e69
children 3f43faadaf9d
files ChangeLog lib/acl_entries.c lib/file-has-acl.c
diffstat 3 files changed, 35 insertions(+), 10 deletions(-) [+]
line wrap: on
line diff
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,12 @@
+2009-05-04  David Bartley  <dtbartle@csclub.uwaterloo.ca>
+            Bruno Haible  <bruno@clisp.org>
+
+	acl: Fix infinite loop on FreeBSD.
+	* lib/acl_entries.c (acl_entries) [Linux, FreeBSD]: Fix interpretation
+	of return value from acl_get_entry.
+	* lib/file-has-acl.c (acl_access_nontrivial) [Linux, FreeBSD]:
+	Likewise.
+
 2009-05-03  Bruno Haible  <bruno@clisp.org>
 
 	* lib/acl-internal.h (acl_entries): Clarify return value.
--- a/lib/acl_entries.c
+++ b/lib/acl_entries.c
@@ -35,13 +35,29 @@
   if (acl != NULL)
     {
 #if HAVE_ACL_FIRST_ENTRY /* Linux, FreeBSD, MacOS X */
+# if HAVE_ACL_TYPE_EXTENDED /* MacOS X */
+      /* acl_get_entry returns 0 when it successfully fetches an entry,
+	 and -1/EINVAL at the end.  */
       acl_entry_t ace;
-      int at_end;
+      int got_one;
 
-      for (at_end = acl_get_entry (acl, ACL_FIRST_ENTRY, &ace);
-	   !at_end;
-	   at_end = acl_get_entry (acl, ACL_NEXT_ENTRY, &ace))
+      for (got_one = acl_get_entry (acl, ACL_FIRST_ENTRY, &ace);
+	   got_one >= 0;
+	   got_one = acl_get_entry (acl, ACL_NEXT_ENTRY, &ace))
 	count++;
+# else /* Linux, FreeBSD */
+      /* acl_get_entry returns 1 when it successfully fetches an entry,
+	 and 0 at the end.  */
+      acl_entry_t ace;
+      int got_one;
+
+      for (got_one = acl_get_entry (acl, ACL_FIRST_ENTRY, &ace);
+	   got_one > 0;
+	   got_one = acl_get_entry (acl, ACL_NEXT_ENTRY, &ace))
+	count++;
+      if (got_one < 0)
+	return -1;
+# endif
 #else /* IRIX, Tru64 */
 # if HAVE_ACL_TO_SHORT_TEXT /* IRIX */
       /* Don't use acl_get_entry: it is undocumented.  */
--- a/lib/file-has-acl.c
+++ b/lib/file-has-acl.c
@@ -1,6 +1,6 @@
 /* Test whether a file has a nontrivial access control list.
 
-   Copyright (C) 2002-2003, 2005-2008 Free Software Foundation, Inc.
+   Copyright (C) 2002-2003, 2005-2009 Free Software Foundation, Inc.
 
    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
@@ -55,11 +55,11 @@
 #  if HAVE_ACL_FIRST_ENTRY /* Linux, FreeBSD */
 
   acl_entry_t ace;
-  int at_end;
+  int got_one;
 
-  for (at_end = acl_get_entry (acl, ACL_FIRST_ENTRY, &ace);
-       !at_end;
-       at_end = acl_get_entry (acl, ACL_NEXT_ENTRY, &ace))
+  for (got_one = acl_get_entry (acl, ACL_FIRST_ENTRY, &ace);
+       got_one > 0;
+       got_one = acl_get_entry (acl, ACL_NEXT_ENTRY, &ace))
     {
       acl_tag_t tag;
       if (acl_get_tag_type (ace, &tag) < 0)
@@ -67,7 +67,7 @@
       if (!(tag == ACL_USER_OBJ || tag == ACL_GROUP_OBJ || tag == ACL_OTHER))
 	return 1;
     }
-  return 0;
+  return got_one;
 
 #  else /* IRIX, Tru64 */
 #   if HAVE_ACL_TO_SHORT_TEXT /* IRIX */