public inbox for gentoo-commits@lists.gentoo.org
 help / color / mirror / Atom feed
* [gentoo-commits] gentoo commit in src/patchsets/coreutils/6.10: 020_all_coreutils-6.10-getgrouplist.patch 021_all_coreutils-6.10-getgrouplist.patch 050_all_coreutils-6.10-mv-atomic.patch
@ 2008-04-12 19:10 Mike Frysinger (vapier)
  0 siblings, 0 replies; only message in thread
From: Mike Frysinger (vapier) @ 2008-04-12 19:10 UTC (permalink / raw
  To: gentoo-commits

vapier      08/04/12 19:10:15

  Added:                020_all_coreutils-6.10-getgrouplist.patch
                        021_all_coreutils-6.10-getgrouplist.patch
                        050_all_coreutils-6.10-mv-atomic.patch
  Log:
  some fixes from upstream

Revision  Changes    Path
1.1                  src/patchsets/coreutils/6.10/020_all_coreutils-6.10-getgrouplist.patch

file : http://sources.gentoo.org/viewcvs.py/gentoo/src/patchsets/coreutils/6.10/020_all_coreutils-6.10-getgrouplist.patch?rev=1.1&view=markup
plain: http://sources.gentoo.org/viewcvs.py/gentoo/src/patchsets/coreutils/6.10/020_all_coreutils-6.10-getgrouplist.patch?rev=1.1&content-type=text/plain

Index: 020_all_coreutils-6.10-getgrouplist.patch
===================================================================
commits from upstream to use getgrouplist()
http://bugs.gentoo.org/210133

commit 49f7ebaac45f4d20a70c83c8302444b64259c6d3
Author: James Youngman <jay@gnu.org>
Date:   Thu Feb 21 15:01:15 2008 +0100

    id: use getgrouplist when possible
    
    * gl/m4/mgetgroups.m4: Check for getgrouplist.
    * gl/lib/mgetgroups.c (mgetgroups): Use getgrouplist, if available.
    * TODO: Remove the item about switching to getgrouplist.
    * NEWS: mention this

diff --git a/lib/mgetgroups.c b/lib/mgetgroups.c
index 6a4a422..b63436a 100644
--- a/lib/mgetgroups.c
+++ b/lib/mgetgroups.c
@@ -23,11 +23,27 @@
 
 #include <unistd.h>
 #include <stdint.h>
+#include <string.h>
 #include <errno.h>
-
+#if HAVE_GETGROUPLIST
+#include <grp.h>
+#endif
 #include "getugroups.h"
 #include "xalloc.h"
 
+
+static void *
+allocate_groupbuf (int size)
+{
+  if (xalloc_oversized (size, sizeof (GETGROUPS_T)))
+    {
+      errno = ENOMEM;
+      return NULL;
+    }
+
+  return malloc (size * sizeof (GETGROUPS_T));
+}
+
 /* Like getugroups, but store the result in malloc'd storage.
    Set *GROUPS to the malloc'd list of all group IDs of which USERNAME
    is a member.  If GID is not -1, store it first.  GID should be the
@@ -37,12 +53,51 @@
    the number of groups.  */
 
 int
-mgetgroups (const char *username, gid_t gid, GETGROUPS_T **groups)
+mgetgroups (char const *username, gid_t gid, GETGROUPS_T **groups)
 {
   int max_n_groups;
   int ng;
   GETGROUPS_T *g;
 
+#if HAVE_GETGROUPLIST
+  /* We prefer to use getgrouplist if available, because it has better
+     performance characteristics.
+
+     In glibc 2.3.2, getgrouplist is buggy.  If you pass a zero as the
+     size of the output buffer, getgrouplist will still write to the
+     buffer.  Contrary to what some versions of the getgrouplist
+     manpage say, this doesn't happen with nonzero buffer sizes.
+     Therefore our usage here just avoids a zero sized buffer.  */
+  if (username)
+    {
+      enum { INITIAL_GROUP_BUFSIZE = 1u };
+      /* INITIAL_GROUP_BUFSIZE is initially small to ensure good test coverage */
+      GETGROUPS_T smallbuf[INITIAL_GROUP_BUFSIZE];
+
+      max_n_groups = INITIAL_GROUP_BUFSIZE;
+      ng = getgrouplist (username, gid, smallbuf, &max_n_groups);
+
+      g = allocate_groupbuf (max_n_groups);
+      if (g == NULL)
+	return -1;
+
+      *groups = g;
+      if (INITIAL_GROUP_BUFSIZE < max_n_groups)
+	{
+	  return getgrouplist (username, gid, g, &max_n_groups);
+	  /* XXX: Ignoring the race with group size increase */
+	}
+      else
+	{
+	  /* smallbuf was big enough, so we already have our data */
+	  memcpy (g, smallbuf, max_n_groups * sizeof *g);
+	  return 0;
+	}
+      /* getgrouplist failed, fall through and use getugroups instead. */
+    }
+  /* else no username, so fall through and use getgroups. */
+#endif
+
   max_n_groups = (username
 		  ? getugroups (0, NULL, username, gid)
 		  : getgroups (0, NULL));
@@ -52,13 +107,7 @@ mgetgroups (const char *username, gid_t gid, GETGROUPS_T **groups)
   if (max_n_groups < 0)
       max_n_groups = 5;
 
-  if (xalloc_oversized (max_n_groups, sizeof *g))
-    {
-      errno = ENOMEM;
-      return -1;
-    }
-
-  g = malloc (max_n_groups * sizeof *g);
+  g = allocate_groupbuf (max_n_groups);
   if (g == NULL)
     return -1;
 
diff --git a/m4/mgetgroups.m4 b/m4/mgetgroups.m4
index 8183541..da55731 100644
--- a/m4/mgetgroups.m4
+++ b/m4/mgetgroups.m4
@@ -1,10 +1,11 @@
-#serial 1
-dnl Copyright (C) 2007 Free Software Foundation, Inc.
+#serial 2
+dnl Copyright (C) 2007-2008 Free Software Foundation, Inc.
 dnl This file is free software; the Free Software Foundation
 dnl gives unlimited permission to copy and/or distribute it,
 dnl with or without modifications, as long as this notice is preserved.
 
 AC_DEFUN([gl_MGETGROUPS],
 [
+  AC_CHECK_FUNCS(getgrouplist)
   AC_LIBOBJ([mgetgroups])
 ])



1.1                  src/patchsets/coreutils/6.10/021_all_coreutils-6.10-getgrouplist.patch

file : http://sources.gentoo.org/viewcvs.py/gentoo/src/patchsets/coreutils/6.10/021_all_coreutils-6.10-getgrouplist.patch?rev=1.1&view=markup
plain: http://sources.gentoo.org/viewcvs.py/gentoo/src/patchsets/coreutils/6.10/021_all_coreutils-6.10-getgrouplist.patch?rev=1.1&content-type=text/plain

Index: 021_all_coreutils-6.10-getgrouplist.patch
===================================================================
commits from upstream to use getgrouplist()
http://bugs.gentoo.org/210133

commit a15329798c52c57cc16fc24265327d8b1c73ab41
Author: Jim Meyering <meyering@redhat.com>
Date:   Fri Feb 22 10:01:36 2008 +0100

    id: avoid race when a group is added between getgrouplist calls
    
    * gl/lib/mgetgroups.c (mgetgroups) [N_GROUPS_INIT]: Rename enum.
    Use a larger value.
    Update *groups only upon success.
    Iterate upon failed getgrouplist.

diff --git a/lib/mgetgroups.c b/lib/mgetgroups.c
index b63436a..ba8818e 100644
--- a/lib/mgetgroups.c
+++ b/lib/mgetgroups.c
@@ -26,7 +26,7 @@
 #include <string.h>
 #include <errno.h>
 #if HAVE_GETGROUPLIST
-#include <grp.h>
+# include <grp.h>
 #endif
 #include "getugroups.h"
 #include "xalloc.h"
@@ -70,30 +70,47 @@ mgetgroups (char const *username, gid_t gid, GETGROUPS_T **groups)
      Therefore our usage here just avoids a zero sized buffer.  */
   if (username)
     {
-      enum { INITIAL_GROUP_BUFSIZE = 1u };
-      /* INITIAL_GROUP_BUFSIZE is initially small to ensure good test coverage */
-      GETGROUPS_T smallbuf[INITIAL_GROUP_BUFSIZE];
+      enum { N_GROUPS_INIT = 10 };
+      GETGROUPS_T smallbuf[N_GROUPS_INIT];
 
-      max_n_groups = INITIAL_GROUP_BUFSIZE;
+      max_n_groups = N_GROUPS_INIT;
       ng = getgrouplist (username, gid, smallbuf, &max_n_groups);
 
       g = allocate_groupbuf (max_n_groups);
       if (g == NULL)
 	return -1;
 
-      *groups = g;
-      if (INITIAL_GROUP_BUFSIZE < max_n_groups)
-	{
-	  return getgrouplist (username, gid, g, &max_n_groups);
-	  /* XXX: Ignoring the race with group size increase */
-	}
-      else
+      if (max_n_groups <= N_GROUPS_INIT)
 	{
 	  /* smallbuf was big enough, so we already have our data */
 	  memcpy (g, smallbuf, max_n_groups * sizeof *g);
-	  return 0;
+	  *groups = g;
+	  return max_n_groups;
+	}
+
+      while (1)
+	{
+	  GETGROUPS_T *h;
+	  ng = getgrouplist (username, gid, g, &max_n_groups);
+	  if (0 <= ng)
+	    {
+	      *groups = g;
+	      return ng;
+	    }
+
+	  /* When getgrouplist fails, it guarantees that
+	     max_n_groups reflects the new number of groups.  */
+
+	  if (xalloc_oversized (max_n_groups, sizeof *h)
+	      || (h = realloc (g, max_n_groups * sizeof *h) == NULL))
+	    {
+	      int saved_errno = errno;
+	      free (g);
+	      errno = saved_errno;
+	      return -1;
+	    }
+	  g = h;
 	}
-      /* getgrouplist failed, fall through and use getugroups instead. */
     }
   /* else no username, so fall through and use getgroups. */
 #endif



1.1                  src/patchsets/coreutils/6.10/050_all_coreutils-6.10-mv-atomic.patch

file : http://sources.gentoo.org/viewcvs.py/gentoo/src/patchsets/coreutils/6.10/050_all_coreutils-6.10-mv-atomic.patch?rev=1.1&view=markup
plain: http://sources.gentoo.org/viewcvs.py/gentoo/src/patchsets/coreutils/6.10/050_all_coreutils-6.10-mv-atomic.patch?rev=1.1&content-type=text/plain

Index: 050_all_coreutils-6.10-mv-atomic.patch
===================================================================
fix from upstream

commit 63feb84a2db5246fb71df45884589b914679110c
Author: Jim Meyering <meyering@redhat.com>
Date:   Wed Mar 19 13:37:04 2008 +0100

    mv: never unlink a destination file before calling rename
    
    While cp --preserve=links must unlink certain destination files,
    mv must never do that.
    * src/copy.c (copy_internal): Pull the '! x->move_mode' test "up",
    so it affects the entire condition, and not just DEREF_NEVER mode.
    Reported by James Ralston in <http://bugzilla.redhat.com/438076>.
    * tests/mv/atomic2: New file.  Test for the above fix.
    * tests/mv/Makefile.am (TESTS): Add atomic2.
    * NEWS: Mention the bug-fix.
    [Bug introduced in 367719ba5f1dbd5e2f7fa2466c441f23f66a7c9e]

diff --git a/src/copy.c b/src/copy.c
index fd31b5c..208a674 100644
--- a/src/copy.c
+++ b/src/copy.c
@@ -1339,10 +1339,11 @@ copy_internal (char const *src_name, char const *dst_name,
 	      new_dst = true;
 	    }
 	  else if (! S_ISDIR (dst_sb.st_mode)
+		   /* Never unlink dst_name when in move mode.  */
+		   && ! x->move_mode
 		   && (x->unlink_dest_before_opening
 		       || (x->preserve_links && 1 < dst_sb.st_nlink)
-		       || (!x->move_mode
-			   && x->dereference == DEREF_NEVER
+		       || (x->dereference == DEREF_NEVER
 			   && S_ISLNK (src_sb.st_mode))
 		       ))
 	    {
diff --git a/tests/mv/Makefile.am b/tests/mv/Makefile.am
index c121911..92ec68e 100644
--- a/tests/mv/Makefile.am
+++ b/tests/mv/Makefile.am
@@ -1,7 +1,6 @@
 # Make coreutils tests for "mv".			-*-Makefile-*-
 
-# Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007
-# Free Software Foundation, Inc.
+# Copyright (C) 1998-2008 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
@@ -17,6 +16,7 @@
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
 TESTS = \
+  atomic2 \
   sticky-to-xpart \
   hard-verbose \
   backup-dir \
diff --git a/tests/mv/atomic2 b/tests/mv/atomic2
new file mode 100755
index 0000000..d1029aa
--- /dev/null
+++ b/tests/mv/atomic2
@@ -0,0 +1,50 @@
+#!/bin/sh
+# ensure that mv doesn't first unlink a multi-hard-linked destination
+
+# Copyright (C) 2008 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
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+if test "$VERBOSE" = yes; then
+  set -x
+  mv --version
+fi
+
+. $srcdir/../test-lib.sh
+require_strace_
+
+# Before the fix, mv would unnecessarily unlink the destination symlink:
+#   $ rm -f a b b2; touch a b; ln b b2; strace -e unlink /p/bin/mv a b
+#   unlink("b")                             = 0
+#
+# With the fix, it doesn't call unlink:
+#   $ rm -f a b b2; touch a b; ln b b2; strace -e unlink ./mv a b
+#   $
+
+touch a b || framework_failure
+ln b b2 || framework_failure
+
+fail=0
+
+strace -qe unlink mv a b > out 2>&1 || fail=1
+$EGREP 'unlink.*"b"' out && fail=1
+
+# Ensure that the source, "a", is gone.
+ls -dl a > /dev/null 2>&1 && fail=1
+
+# Ensure that the destination, "b", has link count 1.
+n_links=`stat --printf=%h b` || fail=1
+test "$n_links" = 1 || fail=1
+
+(exit $fail); exit $fail



-- 
gentoo-commits@lists.gentoo.org mailing list



^ permalink raw reply related	[flat|nested] only message in thread

only message in thread, other threads:[~2008-04-12 19:10 UTC | newest]

Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2008-04-12 19:10 [gentoo-commits] gentoo commit in src/patchsets/coreutils/6.10: 020_all_coreutils-6.10-getgrouplist.patch 021_all_coreutils-6.10-getgrouplist.patch 050_all_coreutils-6.10-mv-atomic.patch Mike Frysinger (vapier)

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox