[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Bug#38048: More glibc2.1 trouble on m68k [PATCH]



Package: glibc
Version: 2.1.1-5

Hi Joel!

Ok, now that glibc finally compiled on m68k, I've installed it in a
chroot environment to compile some other libs (ncurses, libreadline,
...) with it.

But even the first steps failed because dpkg was broken ("Cannot
change ownership of symlink: Function not implemented"). This also
pointed into the direction, and really, the lchown patch for m68k is
in a bad state...

1) It's not applied at all... Applied are only files
debian/patches/*.dpatch, but the m68k patch is named
"m68k-chown.diff".

2) The patch itself partially does the wrong thing: The chown wrapper
is ok, it emulates the new chown semantics under a 2.0 kernel if
needed. But the lchown function just calls syscall 182, which isn't
present under 2.0 kernels. However, our libc contains the lchown
function since some time, so dpkg is configured to use it. The old
glibc contained a compat wrapper, but that is missing from glibc2.1
now. So I've reintroduced the wrapper in a file lchown.c.

Below is a patch that:

 - removes debian/patches/m68k-chown.diff
 - introduces a new debian/patches/m68k-chown.dpatch; it includes
   parts of the old m68k-chown.diff, but some stuff is modified
 - in debian/rules, m68k-chown is added to the list of arch-specific
   patches.

Roman

------------------------------------------------------------------------------
--- glibc-2.1.1/debian/rules	Wed May 19 15:46:18 1999
+++ glibc-2.1.1-mine/debian/rules	Thu May 20 16:48:54 1999
@@ -788,6 +788,9 @@
   ifeq ($(ARCH),sparc)
     debian_patches += sparc32-chown
   endif
+  ifeq ($(ARCH),m68k)
+    debian_patches += m68k-chown
+  endif
   endif
 else
   debian_patches += hurd-ldflags
--- glibc-2.1.1/debian/patches/m68k-chown.diff	Wed May 19 15:46:23 1999
+++ glibc-2.1.1-mine/debian/patches/m68k-chown.diff	Thu May 20 16:57:12 1999
@@ -1,183 +0,0 @@
-diff -Naur --exclude=debian glibc-pre2.1-2.0.106.orig/sysdeps/unix/sysv/linux/m68k/chown.c glibc-pre2.1-2.0.106/sysdeps/unix/sysv/linux/m68k/chown.c
---- glibc-pre2.1-2.0.106.orig/sysdeps/unix/sysv/linux/m68k/chown.c	Thu Jan  1 00:00:00 1970
-+++ glibc-pre2.1-2.0.106/sysdeps/unix/sysv/linux/m68k/chown.c	Mon Aug 24 17:58:59 1998
-@@ -0,0 +1,131 @@
-+/* chown() compatibility.
-+   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 <string.h>
-+#include <unistd.h>
-+#include <limits.h>
-+#include <sys/syscall.h>
-+#include <stdlib.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.
-+  This file emulates chown() under the old kernels.
-+*/
-+
-+extern int __syscall_chown (const char *__file,
-+			    uid_t __owner, gid_t __group);
-+
-+int
-+__chown (const char *file, uid_t owner, gid_t group)
-+{
-+   int err;
-+   int old_errno;
-+   char link[PATH_MAX+2];
-+   char path[2*PATH_MAX+4];
-+   int loopct;
-+   int filelen;
-+   static int libc_old_chown = 0 /* -1=old linux, 1=new linux, 0=unknown */;
-+   
-+   if (libc_old_chown == 1)
-+     return __syscall_chown (file, owner, group);
-+
-+   old_errno = errno;
-+
-+#ifdef __NR_lchown
-+   if (libc_old_chown == 0)
-+     {
-+       err = __syscall_chown (file, owner, group);
-+       if (err != -1 || errno != ENOSYS)
-+	 {
-+	   libc_old_chown = 1;
-+	   return err;
-+	 }
-+       libc_old_chown = -1;
-+     }
-+#endif
-+   
-+   err = __readlink (file, link, PATH_MAX+1);
-+   if (err == -1)
-+     {
-+       errno = old_errno;
-+       return __lchown(file, owner, group);
-+     }
-+
-+   filelen = strlen (file) + 1;
-+   if (filelen > sizeof(path))
-+     {
-+       errno = ENAMETOOLONG;
-+       return -1;
-+     }
-+   memcpy (path, file, filelen);
-+
-+   /* 'The system has an arbitrary limit...'  In practise, we'll hit
-+      ENAMETOOLONG before this, usually.  */
-+   for (loopct = 0; loopct < 128; loopct++)
-+   {
-+     int linklen;
-+     
-+     if (err >= PATH_MAX+1)
-+       {
-+	 errno = ENAMETOOLONG;
-+	 return -1;
-+       }
-+
-+      link[err] = 0;  /* Null-terminate string, just-in-case.  */
-+
-+      linklen = strlen (link) + 1;
-+      
-+      if (link[0] == '/')
-+	memcpy (path, link, linklen);
-+      else
-+	{
-+	  filelen = strlen (path);
-+	  
-+	  while (filelen > 1 && path[filelen-1] == '/')
-+	    filelen--;
-+	  while (filelen > 0 && path[filelen-1] != '/')
-+	    filelen--;
-+	  if (filelen + linklen > sizeof(path))
-+	    {
-+	      errno = ENAMETOOLONG;
-+	      return -1;
-+	    }
-+	  memcpy (path+filelen, link, linklen);
-+	}
-+
-+      err = __readlink(path, link, PATH_MAX+1);
-+      
-+      if (err == -1)
-+      {  
-+	errno = old_errno;
-+	return __lchown(path, owner, group);
-+      }
-+   }
-+   errno = ELOOP;
-+   return -1;
-+}
-+
-+#if defined PIC && defined DO_VERSIONING
-+default_symbol_version (__chown, chown, GLIBC_2.1);
-+#else
-+weak_alias (__chown, chown)
-+#endif
-diff -Naur --exclude=debian glibc-pre2.1-2.0.106.orig/sysdeps/unix/sysv/linux/m68k/lchown.S glibc-pre2.1-2.0.106/sysdeps/unix/sysv/linux/m68k/lchown.S
---- glibc-pre2.1-2.0.106.orig/sysdeps/unix/sysv/linux/m68k/lchown.S	Thu Jan  1 00:00:00 1970
-+++ glibc-pre2.1-2.0.106/sysdeps/unix/sysv/linux/m68k/lchown.S	Mon Aug 24 17:58:59 1998
-@@ -0,0 +1,35 @@
-+/* lchown system call.
-+   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.  */
-+
-+/* Some old kernel headers call lchown() 'chown'.  The number is
-+   the same.  */
-+	
-+#include <sysdep.h>
-+
-+#ifdef __NR_lchown
-+	PSEUDO (__lchown, lchown, 3)
-+#else
-+	PSEUDO (__lchown, chown, 3)
-+#endif
-+	ret
-+	PSEUDO_END(__lchown)
-+	weak_alias (__lchown, lchown)
-+#if defined PIC && defined DO_VERSIONING
-+	symbol_version (__lchown, chown, GLIBC_2.0);
-+#endif
-diff -Naur --exclude=debian glibc-pre2.1-2.0.106.orig/sysdeps/unix/sysv/linux/m68k/syscalls.list glibc-pre2.1-2.0.106/sysdeps/unix/sysv/linux/m68k/syscalls.list
---- glibc-pre2.1-2.0.106.orig/sysdeps/unix/sysv/linux/m68k/syscalls.list	Mon Oct 26 17:39:44 1998
-+++ glibc-pre2.1-2.0.106/sysdeps/unix/sysv/linux/m68k/syscalls.list	Sat Dec 12 02:21:58 1998
-@@ -1,3 +1,5 @@
- # File name	Caller	Syscall name	# args	Strong name	Weak names
- 
- cacheflush	EXTRA	cacheflush	4	__cacheflush	cacheflush
-+
-+s_chown		chown	chown		3	__syscall_chown
--- glibc-2.1.1/debian/patches/m68k-chown.dpatch	Thu May 20 16:57:30 1999
+++ glibc-2.1.1-mine/debian/patches/m68k-chown.dpatch	Thu May 20 16:55:29 1999
@@ -0,0 +1,222 @@
+#! /bin/sh -e
+
+# All lines beginning with `# DPATCH:' are a description of the patch.
+# DP: Fix chown/lchown handling for Linux2.0/2.2 kernels
+
+if [ $# -ne 2 ]; then
+    echo >&2 "`basename $0`: script expects -patch|-unpatch as argument"
+    exit 1
+fi
+case "$1" in
+    -patch) patch -d "$2" -f -p1 < $0;;
+    -unpatch) patch -d "$2" -f -R -p1 < $0;;
+    *)
+	echo >&2 "`basename $0`: script expects -patch|-unpatch as argument"
+	exit 1
+esac
+exit 0
+
+# append the patch here and adjust the -p? flag in the patch calls.
+--- glibc-2.1.1/build/glibc-2.1.1/sysdeps/unix/sysv/linux/m68k/chown.c	Thu May 20 16:53:32 1999
++++ glibc-2.1.1-mine/build/glibc-2.1.1/sysdeps/unix/sysv/linux/m68k/chown.c	Thu May 20 13:24:35 1999
+@@ -0,0 +1,131 @@
++/* chown() compatibility.
++   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 <string.h>
++#include <unistd.h>
++#include <limits.h>
++#include <sys/syscall.h>
++#include <stdlib.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.
++  This file emulates chown() under the old kernels.
++*/
++
++extern int __syscall_chown (const char *__file,
++			    uid_t __owner, gid_t __group);
++
++int
++__chown (const char *file, uid_t owner, gid_t group)
++{
++   int err;
++   int old_errno;
++   char link[PATH_MAX+2];
++   char path[2*PATH_MAX+4];
++   int loopct;
++   int filelen;
++   static int libc_old_chown = 0 /* -1=old linux, 1=new linux, 0=unknown */;
++   
++   if (libc_old_chown == 1)
++     return __syscall_chown (file, owner, group);
++
++   old_errno = errno;
++
++#ifdef __NR_lchown
++   if (libc_old_chown == 0)
++     {
++       err = __syscall_chown (file, owner, group);
++       if (err != -1 || errno != ENOSYS)
++	 {
++	   libc_old_chown = 1;
++	   return err;
++	 }
++       libc_old_chown = -1;
++     }
++#endif
++   
++   err = readlink (file, link, PATH_MAX+1);
++   if (err == -1)
++     {
++       errno = old_errno;
++       return __syscall_chown(file, owner, group);
++     }
++
++   filelen = strlen (file) + 1;
++   if (filelen > sizeof(path))
++     {
++       errno = ENAMETOOLONG;
++       return -1;
++     }
++   memcpy (path, file, filelen);
++
++   /* 'The system has an arbitrary limit...'  In practise, we'll hit
++      ENAMETOOLONG before this, usually.  */
++   for (loopct = 0; loopct < 128; loopct++)
++   {
++     int linklen;
++     
++     if (err >= PATH_MAX+1)
++       {
++	 errno = ENAMETOOLONG;
++	 return -1;
++       }
++
++      link[err] = 0;  /* Null-terminate string, just-in-case.  */
++
++      linklen = strlen (link) + 1;
++      
++      if (link[0] == '/')
++	memcpy (path, link, linklen);
++      else
++	{
++	  filelen = strlen (path);
++	  
++	  while (filelen > 1 && path[filelen-1] == '/')
++	    filelen--;
++	  while (filelen > 0 && path[filelen-1] != '/')
++	    filelen--;
++	  if (filelen + linklen > sizeof(path))
++	    {
++	      errno = ENAMETOOLONG;
++	      return -1;
++	    }
++	  memcpy (path+filelen, link, linklen);
++	}
++
++      err = __readlink(path, link, PATH_MAX+1);
++      
++      if (err == -1)
++      {  
++	errno = old_errno;
++	return __syscall_chown(path, owner, group);
++      }
++   }
++   errno = ELOOP;
++   return -1;
++}
++
++#if defined PIC && defined DO_VERSIONING
++default_symbol_version (__chown, chown, GLIBC_2.1);
++#else
++weak_alias (__chown, chown)
++#endif
+--- glibc-2.1.1/build/glibc-2.1.1/sysdeps/unix/sysv/linux/m68k/lchown.c	Thu May 20 16:53:34 1999
++++ glibc-2.1.1-mine/build/glibc-2.1.1/sysdeps/unix/sysv/linux/m68k/lchown.c	Thu May 20 13:53:30 1999
+@@ -0,0 +1,58 @@
++/* lchown system call.
++   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 <sysdep.h>
++#include <errno.h>
++#include <unistd.h>
++#include <sys/syscall.h>
++
++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);
++
++int
++__lchown (const char *file, uid_t owner, gid_t group)
++{
++   int err;
++   static int libc_old_chown = 0 /* -1=old linux, 1=new linux, 0=unknown */;
++
++   if (libc_old_chown >= 0)
++     {
++       /* New Linux kernel (>= 2.1) or still unknown: try syscall 182 */
++       err = __syscall_lchown (file, owner, group);
++       if (err != -1 || errno != ENOSYS)
++	 {
++	   libc_old_chown = 1;
++	   return err;
++	 }
++       libc_old_chown = -1;
++     }
++
++   /* Old Linux kernel (<2.1): lchown semantics implemented by chown syscall */
++   return __syscall_chown (file, owner, group);
++}
++
++#if defined PIC && defined DO_VERSIONING
++default_symbol_version (__lchown, lchown, GLIBC_2.1);
++#else
++weak_alias (__lchown, lchown)
++#endif
+--- glibc-pre2.1-2.0.106.orig/sysdeps/unix/sysv/linux/m68k/syscalls.list	Mon Oct 26 17:39:44 1998
++++ glibc-pre2.1-2.0.106/sysdeps/unix/sysv/linux/m68k/syscalls.list	Sat Dec 12 02:21:58 1998
+@@ -1,3 +1,5 @@
+ # File name	Caller	Syscall name	# args	Strong name	Weak names
+ 
+ cacheflush	EXTRA	cacheflush	4	__cacheflush	cacheflush
++s_chown		chown	chown		3	__syscall_chown
++s_lchown		lchown	lchown		3	__syscall_lchown


Reply to: