* [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