Re: chown() problem in cp also
Christopher C Chimelis writes:
> Should I go ahead and compile the new glibc package with the current patch
> or do we have a new one? Any disposition yet?
Below is a new hopefully correct patch that also include the
suggestions from Mikolaj about caching the state of chown/lchown.
I have tried to test under 2.0 and 2.1 and it seems to work well,
there also complete deb, the patch and the libc.so file on
http://lhpca.univ-lyon1.fr/glibc
Sorry for the delay (failure of electricity in the building last
night),
Regards,
Loic
diff -N -r -u glibc-2.0.7u/sysdeps//unix/sysv/linux/alpha/Makefile glibc-2.0.7u.new/sysdeps//unix/sysv/linux/alpha/Makefile
--- glibc-2.0.7u/sysdeps//unix/sysv/linux/alpha/Makefile Sat Mar 14 18:44:48 1998
+++ glibc-2.0.7u.new/sysdeps//unix/sysv/linux/alpha/Makefile Sat Dec 12 01:09:13 1998
@@ -2,7 +2,8 @@
sysdep_headers += alpha/ptrace.h alpha/regdef.h
sysdep_routines += ieee_get_fp_control ieee_set_fp_control \
- sethae ioperm osf_sigprocmask fstatfs statfs llseek
+ sethae ioperm osf_sigprocmask fstatfs statfs llseek \
+ s_chown s_lchown
CFLAGS-ioperm.c = -Wa,-m21164a
endif
diff -N -r -u glibc-2.0.7u/sysdeps//unix/sysv/linux/alpha/chown.c glibc-2.0.7u.new/sysdeps//unix/sysv/linux/alpha/chown.c
--- glibc-2.0.7u/sysdeps//unix/sysv/linux/alpha/chown.c Thu Jan 1 01:00:00 1970
+++ glibc-2.0.7u.new/sysdeps//unix/sysv/linux/alpha/chown.c Sat Dec 12 01:09:13 1998
@@ -0,0 +1,41 @@
+/* Copyright (C) 1998 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ The GNU C Library 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
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with the GNU C Library; see the file COPYING.LIB. If not,
+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
+
+#include <errno.h>
+#include <unistd.h>
+#include <sys/syscall.h>
+#include <sys/types.h>
+
+/*
+ In Linux 2.1.x the chown functions have been changed. A new function lchown
+ was introduced. The new chown now follows symlinks - the old chown and the
+ new lchown do not follow symlinks.
+ The new lchown function has the same number as the old chown had and the
+ new chown has a new number. To preserve compatibility with old glibc 2.0
+ versions we always call the syscall with the old semantic.
+*/
+
+extern int __syscall_chown (const char *__file,
+ uid_t __owner, gid_t __group);
+int
+__chown (const char *file, uid_t owner, gid_t group)
+{
+ return __lchown (file, owner, group);
+}
+
+weak_alias (__chown, chown)
diff -N -r -u glibc-2.0.7u/sysdeps//unix/sysv/linux/alpha/lchown.c glibc-2.0.7u.new/sysdeps//unix/sysv/linux/alpha/lchown.c
--- glibc-2.0.7u/sysdeps//unix/sysv/linux/alpha/lchown.c Thu Jan 1 01:00:00 1970
+++ glibc-2.0.7u.new/sysdeps//unix/sysv/linux/alpha/lchown.c Mon Dec 14 23:45:27 1998
@@ -0,0 +1,97 @@
+/* Copyright (C) 1998 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ The GNU C Library 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
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with the GNU C Library; see the file COPYING.LIB. If not,
+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
+
+#include <errno.h>
+#include <unistd.h>
+#include <sys/syscall.h>
+#include <sys/types.h>
+#include <sys/utsname.h>
+#include <errno.h>
+
+/*
+ In Linux 2.1.x the chown functions have been changed. A new function lchown
+ was introduced. The new chown now follows symlinks - the old chown and the
+ new lchown do not follow symlinks.
+ The new lchown function has the same number as the old chown had and the
+ new chown has a new number. To preserve compatibility with old glibc 2.0
+ versions we always call the syscall with the old semantic.
+*/
+
+extern int __syscall_chown (const char *__file,
+ uid_t __owner, gid_t __group);
+
+extern int __syscall_lchown (const char *__file,
+ uid_t __owner, gid_t __group);
+
+enum lchown_status {
+ CHOWN_UNKNOWN,
+ HAS_LCHOWN,
+ NO_LCHOWN
+};
+int
+__lchown (const char *file, uid_t owner, gid_t group)
+{
+ static enum lchown_status state = CHOWN_UNKNOWN;
+ int ret;
+
+ again:
+ switch (state) {
+ case HAS_LCHOWN:
+ return __syscall_lchown (file, owner, group);
+ case NO_LCHOWN:
+ return __syscall_chown (file, owner, group);
+ case CHOWN_UNKNOWN:
+ ret = __syscall_lchown (file, owner, group);
+ if (ret != -1) {
+ state = HAS_LCHOWN;
+ return ret;
+ }
+ if (errno == ENOSYS) {
+ /* probably under a 2.0 kernel */
+ state = NO_LCHOWN;
+ goto again;
+ } else if (errno == EPERM && geteuid() == 0) {
+ /* hack to workaround bug in some 2.0 kernels */
+ struct utsname uts;
+ if (uname(&uts) != 0) {
+ /* should never happen */
+ return -1;
+ }
+ if (uts.release[1] == '.' && /* be sure we are not kernel 10.xxx :-) */
+ (uts.release[0] < '2' ||
+ (uts.release[0] == '2' && uts.release[2] == '0' &&
+ uts.release[3] == '.' ))) {
+ /* we assume we have the kernel bug, if out of luck,
+ it was not the case, that will make only a difference if:
+ - the user was probably trying to use chown on a NFS filesystem with squash_root
+ - somebody implemented lchown in a 2.0 kernel (put him in jail :-)
+ - the same somebody changed the semantics of chown in 2.0 (hang him)
+ - the only unexpected effect will be to chown the linked to file
+ */
+ state = NO_LCHOWN;
+ goto again;
+ } /* uts release <= 2.0 */
+ } /* errno == EPERM */
+ state = HAS_LCHOWN;
+ return ret;
+ } /* end of switch */
+ /* we never arrive here */
+ return -1;
+}
+
+weak_alias (__lchown, lchown)
diff -N -r -u glibc-2.0.7u/sysdeps//unix/sysv/linux/alpha/syscalls.list glibc-2.0.7u.new/sysdeps//unix/sysv/linux/alpha/syscalls.list
--- glibc-2.0.7u/sysdeps//unix/sysv/linux/alpha/syscalls.list Fri Mar 6 18:04:21 1998
+++ glibc-2.0.7u.new/sysdeps//unix/sysv/linux/alpha/syscalls.list Sat Dec 12 01:09:13 1998
@@ -3,6 +3,8 @@
# used to implement inb()/outb() etc.
sethae - sethae 1 __sethae
+s_chown - chown 3 __syscall_chown
+s_lchown - lchown 3 __syscall_lchown
msgctl - msgctl 3 __msgctl msgctl
msgget - msgget 2 __msgget msgget
msgrcv - msgrcv 5 __msgrcv msgrcv
diff -N -r -u glibc-2.0.7u/sysdeps//unix/sysv/linux/alpha/sysdep.h glibc-2.0.7u.new/sysdeps//unix/sysv/linux/alpha/sysdep.h
--- glibc-2.0.7u/sysdeps//unix/sysv/linux/alpha/sysdep.h Wed Jun 19 08:37:59 1996
+++ glibc-2.0.7u.new/sysdeps//unix/sysv/linux/alpha/sysdep.h Sat Dec 12 01:09:13 1998
@@ -26,6 +26,9 @@
/* There is some commonality. */
#include <sysdeps/unix/alpha/sysdep.h>
+#ifndef __NR_lchown
+#define __NR_lchown 208
+#endif
/* For Linux we can use the system call table in the header file
/usr/include/asm/unistd.h
Reply to: