aboutsummaryrefslogtreecommitdiff
path: root/sysdeps
diff options
context:
space:
mode:
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