summary refs log tree commit diff
path: root/sysdeps/unix/sysv
diff options
context:
space:
mode:
Diffstat (limited to 'sysdeps/unix/sysv')
-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
6 files changed, 114 insertions, 12 deletions
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