aboutsummaryrefslogtreecommitdiff
path: root/sysdeps/unix
diff options
context:
space:
mode:
Diffstat (limited to 'sysdeps/unix')
-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