about summary refs log tree commit diff
path: root/sysdeps
diff options
context:
space:
mode:
authorUlrich Drepper <drepper@redhat.com>2003-04-19 16:57:17 +0000
committerUlrich Drepper <drepper@redhat.com>2003-04-19 16:57:17 +0000
commit2c008571c3ad156479307b7e23185ae566b5776a (patch)
treef3bad7f0e95a6d172e6577b7e2d557602e1f446c /sysdeps
parent76a67697c890d292d9f32e88cf24f8a3f74e47b9 (diff)
downloadglibc-2c008571c3ad156479307b7e23185ae566b5776a.tar.gz
glibc-2c008571c3ad156479307b7e23185ae566b5776a.tar.xz
glibc-2c008571c3ad156479307b7e23185ae566b5776a.zip
Update.
2003-04-19  Ulrich Drepper  <drepper@redhat.com>

	* catgets/nl_types.h: Remove __THROW marker from cancellation points.
	* dirent/dirent.h: Likewise.
	* dlfcn/dlfcn.h: Likewise.
	* grp/grp.h: Likewise.
	* iconv/iconv.h: Likewise.
	* io/fcntl.h: Likewise.
	* io/ftw.h: Likewise.
	* libio/stdio.h: Likewise.
	* misc/sys/mman.h: Likewise.
	* misc/sys/select.h: Likewise.
	* misc/sys/syslog.h: Likewise.
	* misc/sys/uio.h: Likewise.
	* posix/spawn.h: Likewise.
	* posix/unistd.h: Likewise.
	* posix/sys/wait.h: Likewise.
	* pwd/pwd.h: Likewise.
	* resolv/netdb.h: Likewise.
	* rt/aio.h: Likewise.
	* shadow/shadow.h: Likewise.
	* signal/signal.h: Likewise.
	* socket/sys/socket.h: Likewise.
	* stdlib/stdlib.h: Likewise.
	* streams/stropts.h: Likewise.
	* string/string.h: Likewise.
	* sysdeps/gnu/utmpx.h: Likewise.
	* sysvipc/sys/msg.h: Likewise.
	* termios/termios.h: Likewise.
	* time/time.h: Likewise.
	* wcsmbs/wchar.h: Likewise.
	* iconv/gconv_cache.c: Include <not-cancel.h> and use non-cancelable
	functions.
	* misc/daemon.c: Likewise.
	* sysdeps/generic/backtracesymsfd.c: Likewise.
	* sysdeps/generic/check_fds.c: Likewise.
	* sysdeps/unix/sysv/linux/gethostid.c: Likewise.
	* sysdeps/unix/sysv/linux/not-cancel.h: New file.
	* sysdeps/generic/not-cancel.h: New file.
	* csu/Makefile (distribute): Add not-cancel.h.
	* sysdeps/unix/sysv/linux/fatal-prepare.h: New file.
	* sysdeps/unix/sysv/linux/Makefile: Define FATAL_PREPARE_INCLUDE
	for assert.c and assert-perr.c to include <fatal-prepare.h>.
	* sysdeps/unix/sysv/linux/Dist: Add fatal-prepare.h.

	* sysdeps/posix/remove.c (remove): Rewrite.  No need to restore
	errno and unlink first.

	* io/ftw.c (ftw_dir): In all places assume fchdir is available.

2003-04-18  Ulrich Drepper  <drepper@redhat.com>

	* sysdeps/unix/sysv/linux/libc_fatal.c (__libc_fatal): Use
	INTERNAL_SYSCALL instead of INLINE_SYSCALL.
Diffstat (limited to 'sysdeps')
-rw-r--r--sysdeps/generic/backtracesymsfd.c8
-rw-r--r--sysdeps/generic/check_fds.c6
-rw-r--r--sysdeps/generic/not-cancel.h31
-rw-r--r--sysdeps/gnu/utmpx.h80
-rw-r--r--sysdeps/posix/remove.c22
-rw-r--r--sysdeps/unix/sysv/linux/Dist1
-rw-r--r--sysdeps/unix/sysv/linux/Makefile5
-rw-r--r--sysdeps/unix/sysv/linux/fatal-prepare.h39
-rw-r--r--sysdeps/unix/sysv/linux/gethostid.c17
-rw-r--r--sysdeps/unix/sysv/linux/libc_fatal.c10
-rw-r--r--sysdeps/unix/sysv/linux/not-cancel.h54
11 files changed, 223 insertions, 50 deletions
diff --git a/sysdeps/generic/backtracesymsfd.c b/sysdeps/generic/backtracesymsfd.c
index a730607a3d..c704362ec7 100644
--- a/sysdeps/generic/backtracesymsfd.c
+++ b/sysdeps/generic/backtracesymsfd.c
@@ -1,5 +1,5 @@
 /* Write formatted list with names for addresses in backtrace to a file.
-   Copyright (C) 1998 Free Software Foundation, Inc.
+   Copyright (C) 1998, 2003 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@cygnus.com>, 1998.
 
@@ -23,11 +23,12 @@
 #include <sys/uio.h>
 
 #include <stdio-common/_itoa.h>
+#include <not-cancel.h>
 
 #if __ELF_NATIVE_CLASS == 32
 # define WORD_WIDTH 8
 #else
-/* We assyme 64bits.  */
+/* We assume 64bits.  */
 # define WORD_WIDTH 16
 #endif
 
@@ -55,7 +56,8 @@ __backtrace_symbols_fd (array, size, fd)
       iov[2].iov_base = (void *) "]\n";
       iov[2].iov_len = 2;
 
-      __writev (fd, iov, 3);
+      /* We prefer to use the non-cancelable interface if it is available.  */
+      writev_not_cancel_no_status (fd, iov, 3);
     }
 }
 weak_alias (__backtrace_symbols_fd, backtrace_symbols_fd)
diff --git a/sysdeps/generic/check_fds.c b/sysdeps/generic/check_fds.c
index ff9562de08..8a3efd1b37 100644
--- a/sysdeps/generic/check_fds.c
+++ b/sysdeps/generic/check_fds.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2000, 2002 Free Software Foundation, Inc.
+/* Copyright (C) 2000, 2002, 2003 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
@@ -32,6 +32,7 @@
 #endif
 
 #include <device-nrs.h>
+#include <not-cancel.h>
 
 
 /* Should other OSes (e.g., Hurd) have different versions which can
@@ -39,6 +40,7 @@
 static void
 check_one_fd (int fd, int mode)
 {
+  /* Note that fcntl() with this parameter is not a cancellation point.  */
   if (__builtin_expect (__libc_fcntl (fd, F_GETFD), 0) == -1
       && errno == EBADF)
     {
@@ -47,7 +49,7 @@ check_one_fd (int fd, int mode)
       /* Something is wrong with this descriptor, it's probably not
 	 opened.  Open /dev/null so that the SUID program we are
 	 about to start does not accidently use this descriptor.  */
-      int nullfd = __libc_open (_PATH_DEVNULL, mode);
+      int nullfd = open_not_cancel (_PATH_DEVNULL, mode);
       /* We are very paranoid here.  With all means we try to ensure
 	 that we are actually opening the /dev/null device and nothing
 	 else.
diff --git a/sysdeps/generic/not-cancel.h b/sysdeps/generic/not-cancel.h
new file mode 100644
index 0000000000..b87c16034b
--- /dev/null
+++ b/sysdeps/generic/not-cancel.h
@@ -0,0 +1,31 @@
+/* Uncancelable versions of cancelable interfaces.  Generic version.
+   Copyright (C) 2003 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Ulrich Drepper <drepper@redhat.com>, 2003.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 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
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+/* By default we have none.  Map the name to the normal functions.  */
+#define open_not_cancel(name, flags, mode...) \
+  __libc_open (name, flags, ##mode)
+#define close_not_cancel_no_status(fd) \
+  (void) __close (fd)
+#define read_not_cancel(fd, buf, n) \
+  __read (fd, buf, n)
+#define write_not_cancel(fd, buf, n) \
+  __write (fd, buf, n)
+#define writev_not_cancel_no_status(fd, iov, n) \
+  (void) __writev (fd, iov, n)
diff --git a/sysdeps/gnu/utmpx.h b/sysdeps/gnu/utmpx.h
index 1647bfe681..8622916a94 100644
--- a/sysdeps/gnu/utmpx.h
+++ b/sysdeps/gnu/utmpx.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 1997, 1998, 1999 Free Software Foundation, Inc.
+/* Copyright (C) 1997, 1998, 1999, 2003 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
@@ -47,41 +47,79 @@ struct utmp;
 
 __BEGIN_DECLS
 
-/* Open user accounting database.  */
-extern void setutxent (void) __THROW;
+/* Open user accounting database.
 
-/* Close user accounting database.  */
-extern void endutxent (void) __THROW;
+   This function is a possible cancellation point and therefore not
+   marked with __THROW.  */
+extern void setutxent (void);
 
-/* Get the next entry from the user accounting database.  */
-extern struct utmpx *getutxent (void) __THROW;
+/* Close user accounting database.
 
-/* Get the user accounting database entry corresponding to ID.  */
-extern struct utmpx *getutxid (__const struct utmpx *__id) __THROW;
+   This function is a possible cancellation point and therefore not
+   marked with __THROW.  */
+extern void endutxent (void);
 
-/* Get the user accounting database entry corresponding to LINE.  */
-extern struct utmpx *getutxline (__const struct utmpx *__line) __THROW;
+/* Get the next entry from the user accounting database.
 
-/* Write the entry UTMPX into the user accounting database.  */
-extern struct utmpx *pututxline (__const struct utmpx *__utmpx) __THROW;
+   This function is a possible cancellation point and therefore not
+   marked with __THROW.  */
+extern struct utmpx *getutxent (void);
+
+/* Get the user accounting database entry corresponding to ID.
+
+   This function is a possible cancellation point and therefore not
+   marked with __THROW.  */
+extern struct utmpx *getutxid (__const struct utmpx *__id);
+
+/* Get the user accounting database entry corresponding to LINE.
+
+   This function is a possible cancellation point and therefore not
+   marked with __THROW.  */
+extern struct utmpx *getutxline (__const struct utmpx *__line);
+
+/* Write the entry UTMPX into the user accounting database.
+
+   This function is a possible cancellation point and therefore not
+   marked with __THROW.  */
+extern struct utmpx *pututxline (__const struct utmpx *__utmpx);
 
 
 #ifdef __USE_GNU
-/* Change name of the utmpx file to be examined.  */
-extern int utmpxname (__const char *__file) __THROW;
+/* Change name of the utmpx file to be examined.
+
+   This function is not part of POSIX and therefore no official
+   cancellation point.  But due to similarity with an POSIX interface
+   or due to the implementation it is a cancellation point and
+   therefore not marked with __THROW.  */
+extern int utmpxname (__const char *__file);
+
+/* Append entry UTMP to the wtmpx-like file WTMPX_FILE.
 
-/* Append entry UTMP to the wtmpx-like file WTMPX_FILE.  */
+   This function is not part of POSIX and therefore no official
+   cancellation point.  But due to similarity with an POSIX interface
+   or due to the implementation it is a cancellation point and
+   therefore not marked with __THROW.  */
 extern void updwtmpx (__const char *__wtmpx_file,
-		      __const struct utmpx *__utmpx) __THROW;
+		      __const struct utmpx *__utmpx);
 
 
-/* Copy the information in UTMPX to UTMP. */
+/* Copy the information in UTMPX to UTMP.
+
+   This function is not part of POSIX and therefore no official
+   cancellation point.  But due to similarity with an POSIX interface
+   or due to the implementation it is a cancellation point and
+   therefore not marked with __THROW.  */
 extern void getutmp (__const struct utmpx *__utmpx,
-		     struct utmp *__utmp) __THROW;
+		     struct utmp *__utmp);
+
+/* Copy the information in UTMP to UTMPX.
 
-/* Copy the information in UTMP to UTMPX. */
+   This function is not part of POSIX and therefore no official
+   cancellation point.  But due to similarity with an POSIX interface
+   or due to the implementation it is a cancellation point and
+   therefore not marked with __THROW.  */
 extern void getutmpx (__const struct utmp *__utmp,
-		      struct utmpx *__utmpx) __THROW;
+		      struct utmpx *__utmpx);
 #endif
 
 __END_DECLS
diff --git a/sysdeps/posix/remove.c b/sysdeps/posix/remove.c
index 7473ee14f4..c44af92d74 100644
--- a/sysdeps/posix/remove.c
+++ b/sysdeps/posix/remove.c
@@ -1,5 +1,5 @@
 /* ANSI C `remove' function to delete a file or directory.  POSIX.1 version.
-   Copyright (C) 1995,96,97,2002 Free Software Foundation, Inc.
+   Copyright (C) 1995,96,97,2002,2003 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
@@ -25,17 +25,15 @@ int
 remove (file)
      const char *file;
 {
-  int save;
+  /* First try to unlink since this is more frequently the necessary action. */
+  if (__unlink (file) != 0
+      /* If it is indeed a directory...  */
+      && (errno != EISDIR
+	  /* ...try to remove it.  */
+	  || __rmdir (file) != 0))
+    /* Cannot remove the object for whatever reason.  */
+    return -1;
 
-  save = errno;
-  if (__rmdir (file) == 0)
-    return 0;
-  else if (errno == ENOTDIR && __unlink (file) == 0)
-    {
-      __set_errno (save);
-      return 0;
-    }
-
-  return -1;
+  return 0;
 }
 libc_hidden_def (remove)
diff --git a/sysdeps/unix/sysv/linux/Dist b/sysdeps/unix/sysv/linux/Dist
index b5b91c2059..6cae4ca0b5 100644
--- a/sysdeps/unix/sysv/linux/Dist
+++ b/sysdeps/unix/sysv/linux/Dist
@@ -3,6 +3,7 @@ cmsg_nxthdr.c
 dl-brk.c
 dl-sbrk.c
 exit-thread.S
+fatal-prepare.h
 getdirentries.c
 getdirentries64.c
 ipc_priv.h
diff --git a/sysdeps/unix/sysv/linux/Makefile b/sysdeps/unix/sysv/linux/Makefile
index eaa6e2a083..dcffc97986 100644
--- a/sysdeps/unix/sysv/linux/Makefile
+++ b/sysdeps/unix/sysv/linux/Makefile
@@ -2,6 +2,11 @@ ifeq ($(subdir),csu)
 sysdep_routines += errno-loc
 endif
 
+ifeq ($(subdir),assert)
+CFLAGS-assert.c += -DFATAL_PREPARE_INCLUDE='<fatal-prepare.h>'
+CFLAGS-assert-perr.c += -DFATAL_PREPARE_INCLUDE='<fatal-prepare.h>'
+endif
+
 ifeq ($(subdir),malloc)
 CFLAGS-malloc.c += -DMORECORE_CLEARS=2
 endif
diff --git a/sysdeps/unix/sysv/linux/fatal-prepare.h b/sysdeps/unix/sysv/linux/fatal-prepare.h
new file mode 100644
index 0000000000..d48ae625ee
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/fatal-prepare.h
@@ -0,0 +1,39 @@
+/* Copyright (C) 2003 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 Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 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
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#include <pthread.h>
+
+/* We have to completely disable cancellation.  assert() must not be a
+   cancellation point but the implementation uses write() etc.  */
+#ifdef SHARED
+# include <pthread-functions.h>
+# define FATAL_PREPARE \
+  {									      \
+    int (*fp) (int, int *);						      \
+    fp = __libc_pthread_functions.ptr_pthread_setcancelstate;		      \
+    if (fp != NULL)							      \
+      fp (PTHREAD_CANCEL_DISABLE, NULL);				      \
+  }
+#else
+# pragma weak pthread_setcancelstate
+# define FATAL_PREPARE \
+  {									      \
+    if (pthread_setcancelstate != NULL)					      \
+      pthread_setcancelstate (PTHREAD_CANCEL_DISABLE, NULL);		      \
+  }
+#endif
diff --git a/sysdeps/unix/sysv/linux/gethostid.c b/sysdeps/unix/sysv/linux/gethostid.c
index 96a78c6da1..4b587ceab3 100644
--- a/sysdeps/unix/sysv/linux/gethostid.c
+++ b/sysdeps/unix/sysv/linux/gethostid.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1995,1996,1998,1999,2000,2001 Free Software Foundation, Inc.
+/* Copyright (C) 1995,1996,1998-2001,2003 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
@@ -21,6 +21,7 @@
 #include <fcntl.h>
 #include <unistd.h>
 #include <netdb.h>
+#include <not-cancel.h>
 
 #define HOSTIDFILE "/etc/hostid"
 #define OLD_HOSTIDFILE "/etc/hostid"
@@ -41,13 +42,13 @@ sethostid (id)
     }
 
   /* Open file for writing.  Everybody is allowed to read this file.  */
-  fd = __open64 (HOSTIDFILE, O_CREAT|O_WRONLY|O_TRUNC, 0644);
+  fd = open_not_cancel (HOSTIDFILE, O_CREAT|O_WRONLY|O_TRUNC, 0644);
   if (fd < 0)
     return -1;
 
-  written = __write (fd, &id, sizeof (id));
+  written = write_not_cancel (fd, &id, sizeof (id));
 
-  __close (fd);
+  close_not_cancel_no_status (fd);
 
   return written != sizeof (id) ? -1 : 0;
 }
@@ -71,14 +72,14 @@ gethostid ()
   int fd;
 
   /* First try to get the ID from a former invocation of sethostid.  */
-  fd = __open64 (HOSTIDFILE, O_RDONLY);
+  fd = open_not_cancel (HOSTIDFILE, O_RDONLY|O_LARGEFILE);
   if (fd < 0)
-    fd = __open64 (OLD_HOSTIDFILE, O_RDONLY);
+    fd = open_not_cancel (OLD_HOSTIDFILE, O_RDONLY|O_LARGEFILE);
   if (fd >= 0)
     {
-      ssize_t n = __read (fd, &id, sizeof (id));
+      ssize_t n = read_not_cancel (fd, &id, sizeof (id));
 
-      __close (fd);
+      close_not_cancel_no_status (fd);
 
       if (n == sizeof (id))
 	return id;
diff --git a/sysdeps/unix/sysv/linux/libc_fatal.c b/sysdeps/unix/sysv/linux/libc_fatal.c
index 5043f62880..bb4d61a836 100644
--- a/sysdeps/unix/sysv/linux/libc_fatal.c
+++ b/sysdeps/unix/sysv/linux/libc_fatal.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1993,1994,1995,1997,2000,2002 Free Software Foundation, Inc.
+/* Copyright (C) 1993-1995,1997,2000,2002, 2003 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
@@ -37,13 +37,15 @@ __libc_fatal (message)
 
   while (len > 0)
     {
-      ssize_t count = INLINE_SYSCALL (write, 3, STDERR_FILENO, message, len);
-      if (count > 0)
+      INTERNAL_SYSCALL_DECL (err);
+      ssize_t count = INTERNAL_SYSCALL (write, err, 3, STDERR_FILENO,
+					message, len);
+      if (! INTERNAL_SYSCALL_ERROR_P (count, err))
 	{
 	  message += count;
 	  len -= count;
 	}
-      else if (count < 0 && errno != EINTR)
+      else if (INTERNAL_SYSCALL_ERRNO (count, err) != EINTR)
 	break;
     }
 
diff --git a/sysdeps/unix/sysv/linux/not-cancel.h b/sysdeps/unix/sysv/linux/not-cancel.h
new file mode 100644
index 0000000000..e2cb3b24a1
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/not-cancel.h
@@ -0,0 +1,54 @@
+/* Uncancelable versions of cancelable interfaces.  Linux version.
+   Copyright (C) 2003 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Ulrich Drepper <drepper@redhat.com>, 2003.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 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
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#include <sysdep.h>
+
+/* Uncancelable open.  */
+#ifdef INLINE_SYSCALL
+# define open_not_cancel(name, flags, mode...) \
+  ({ int _mode = (0, ##mode);						      \
+     INLINE_SYSCALL (open, 3, name, flags, _mode); })
+#endif
+
+/* Uncancelable close.  */
+#ifdef INLINE_SYSCALL
+# define close_not_cancel_no_status(fd) \
+  (void) ({ INTERNAL_SYSCALL_DECL (err);				      \
+	    INTERNAL_SYSCALL (close, err, 1, fd); })
+#endif
+
+/* Uncancelable read.  */
+#ifdef INLINE_SYSCALL
+# define read_not_cancel(fd, buf, n) \
+  INLINE_SYSCALL (read, 3, fd, buf, n)
+#endif
+
+/* Uncancelable write.  */
+#ifdef INLINE_SYSCALL
+# define write_not_cancel(fd, buf, n) \
+  INLINE_SYSCALL (write, 3, fd, buf, n)
+#endif
+
+/* Uncancelable writev.  */
+#ifdef INLINE_SYSCALL
+# define writev_not_cancel_no_status(fd, iov, n) \
+  (void) ({ INTERNAL_SYSCALL_DECL (err);				      \
+	    INTERNAL_SYSCALL (writev, err, 3, fd, iov, n); })
+#endif