aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog41
-rw-r--r--nptl/ChangeLog6
-rw-r--r--nptl/sysdeps/unix/sysv/linux/i386/sysdep-cancel.h62
-rw-r--r--sysdeps/generic/pselect.c35
-rw-r--r--sysdeps/generic/sysdep-cancel.h5
-rw-r--r--sysdeps/posix/open64.c12
-rw-r--r--sysdeps/posix/sigpause.c20
-rw-r--r--sysdeps/posix/sigwait.c23
-rw-r--r--sysdeps/posix/system.c12
-rw-r--r--sysdeps/posix/waitid.c31
-rw-r--r--sysdeps/unix/sysv/linux/accept.S1
-rw-r--r--sysdeps/unix/sysv/linux/connect.S1
-rw-r--r--sysdeps/unix/sysv/linux/i386/fcntl.c46
-rw-r--r--sysdeps/unix/sysv/linux/i386/socket.S56
-rw-r--r--sysdeps/unix/sysv/linux/llseek.c23
-rw-r--r--sysdeps/unix/sysv/linux/msgrcv.c15
-rw-r--r--sysdeps/unix/sysv/linux/msgsnd.c16
-rw-r--r--sysdeps/unix/sysv/linux/open64.c53
-rw-r--r--sysdeps/unix/sysv/linux/poll.c50
-rw-r--r--sysdeps/unix/sysv/linux/pread.c30
-rw-r--r--sysdeps/unix/sysv/linux/pread64.c32
-rw-r--r--sysdeps/unix/sysv/linux/pwrite.c35
-rw-r--r--sysdeps/unix/sysv/linux/pwrite64.c30
-rw-r--r--sysdeps/unix/sysv/linux/readv.c25
-rw-r--r--sysdeps/unix/sysv/linux/recv.S1
-rw-r--r--sysdeps/unix/sysv/linux/recvfrom.S1
-rw-r--r--sysdeps/unix/sysv/linux/recvmsg.S1
-rw-r--r--sysdeps/unix/sysv/linux/send.S1
-rw-r--r--sysdeps/unix/sysv/linux/sendmsg.S1
-rw-r--r--sysdeps/unix/sysv/linux/sendto.S1
-rw-r--r--sysdeps/unix/sysv/linux/sigsuspend.c45
-rw-r--r--sysdeps/unix/sysv/linux/sigtimedwait.c18
-rw-r--r--sysdeps/unix/sysv/linux/sigwait.c25
-rw-r--r--sysdeps/unix/sysv/linux/sigwaitinfo.c18
-rw-r--r--sysdeps/unix/sysv/linux/tcdrain.c16
-rw-r--r--sysdeps/unix/sysv/linux/wait.c48
-rw-r--r--sysdeps/unix/sysv/linux/waitpid.c16
-rw-r--r--sysdeps/unix/sysv/linux/writev.c27
38 files changed, 730 insertions, 149 deletions
diff --git a/ChangeLog b/ChangeLog
index f45ba51..f7d344f 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,44 @@
+2002-12-15 Ulrich Drepper <drepper@redhat.com>
+
+ * sysdeps/generic/sysdep-cancel.h: Add dummy definitions for
+ SINGLE_THREAD_P, LIBC_CANCEL_ASYNC, and LIBC_CANCEL_RESET.
+
+ * sysdeps/unix/sysv/linux/open64.c: New file.
+
+ * sysdeps/generic/pselect.c: Add support for cancellation handling.
+ * sysdeps/posix/open64.c: Likewise.
+ * sysdeps/posix/sigpause.c: Likewise.
+ * sysdeps/posix/sigwait.c: Likewise.
+ * sysdeps/posix/system.c: Likewise.
+ * sysdeps/posix/waitid.c: Likewise.
+ * sysdeps/unix/sysv/linux/accept.S: Likewise.
+ * sysdeps/unix/sysv/linux/connect.S: Likewise.
+ * sysdeps/unix/sysv/linux/llseek.c: Likewise.
+ * sysdeps/unix/sysv/linux/msgrcv.c: Likewise.
+ * sysdeps/unix/sysv/linux/msgsnd.c: Likewise.
+ * sysdeps/unix/sysv/linux/poll.c: Likewise.
+ * sysdeps/unix/sysv/linux/pread.c: Likewise.
+ * sysdeps/unix/sysv/linux/pread64.c: Likewise.
+ * sysdeps/unix/sysv/linux/pwrite.c: Likewise.
+ * sysdeps/unix/sysv/linux/pwrite64.c: Likewise.
+ * sysdeps/unix/sysv/linux/readv.c: Likewise.
+ * sysdeps/unix/sysv/linux/recv.S: Likewise.
+ * sysdeps/unix/sysv/linux/recvfrom.S: Likewise.
+ * sysdeps/unix/sysv/linux/recvmsg.S: Likewise.
+ * sysdeps/unix/sysv/linux/send.S: Likewise.
+ * sysdeps/unix/sysv/linux/sendmsg.S: Likewise.
+ * sysdeps/unix/sysv/linux/sendto.S: Likewise.
+ * sysdeps/unix/sysv/linux/sigsuspend.c: Likewise.
+ * sysdeps/unix/sysv/linux/sigtimedwait.c: Likewise.
+ * sysdeps/unix/sysv/linux/sigwait.c: Likewise.
+ * sysdeps/unix/sysv/linux/sigwaitinfo.c: Likewise.
+ * sysdeps/unix/sysv/linux/tcdrain.c: Likewise.
+ * sysdeps/unix/sysv/linux/wait.c: Likewise.
+ * sysdeps/unix/sysv/linux/waitpid.c: Likewise.
+ * sysdeps/unix/sysv/linux/writev.c: Likewise.
+ * sysdeps/unix/sysv/linux/i386/fcntl.c: Likewise.
+ * sysdeps/unix/sysv/linux/i386/socket.S: Likewise.
+
2002-12-14 Jakub Jelinek <jakub@redhat.com>
* sysdeps/generic/sysdep-cancel.h: New file.
diff --git a/nptl/ChangeLog b/nptl/ChangeLog
index 24abd2b..2296c17 100644
--- a/nptl/ChangeLog
+++ b/nptl/ChangeLog
@@ -1,3 +1,9 @@
+2002-12-15 Ulrich Drepper <drepper@redhat.com>
+
+ * sysdeps/unix/sysv/linux/i386/sysdep-cancel.h: Define
+ SINGLE_THREAD_P. If in libc or libpthread examine multiple_thread
+ member of thread decriptor, otherwise return unconditionally 1.
+
2002-12-14 Ulrich Drepper <drepper@redhat.com>
* sysdeps/unix/sysv/linux/i386/pt-socket.S: Changes folded into the
diff --git a/nptl/sysdeps/unix/sysv/linux/i386/sysdep-cancel.h b/nptl/sysdeps/unix/sysv/linux/i386/sysdep-cancel.h
index ed9f942..39bdfbe 100644
--- a/nptl/sysdeps/unix/sysv/linux/i386/sysdep-cancel.h
+++ b/nptl/sysdeps/unix/sysv/linux/i386/sysdep-cancel.h
@@ -19,11 +19,14 @@
#include <sysdep.h>
#include <tls.h>
+#ifndef ASSEMBLER
+# include <nptl/pthreadP.h>
+#endif
#if !defined NOT_IN_libc || defined IS_IN_libpthread
-#undef PSEUDO
-#define PSEUDO(name, syscall_name, args) \
+# undef PSEUDO
+# define PSEUDO(name, syscall_name, args) \
.text; \
ENTRY (name) \
cmpl $0, %gs:MULTIPLE_THREADS_OFFSET; \
@@ -33,7 +36,7 @@
jae SYSCALL_ERROR_LABEL; \
ret; \
L(pseudo_cancel): \
- call __libc_enable_asynccancel; \
+ CENABLE \
SAVE_OLDTYPE_##args \
PUSHARGS_##args \
DOCARGS_##args \
@@ -45,26 +48,41 @@
jae SYSCALL_ERROR_LABEL; \
L(pseudo_end):
-#define SAVE_OLDTYPE_0 movl %eax, %ecx;
-#define SAVE_OLDTYPE_1 SAVE_OLDTYPE_0
-#define SAVE_OLDTYPE_2 pushl %eax;
-#define SAVE_OLDTYPE_3 SAVE_OLDTYPE_2
-#define SAVE_OLDTYPE_4 SAVE_OLDTYPE_2
-#define SAVE_OLDTYPE_5 SAVE_OLDTYPE_2
+# define SAVE_OLDTYPE_0 movl %eax, %edx;
+# define SAVE_OLDTYPE_1 SAVE_OLDTYPE_0
+# define SAVE_OLDTYPE_2 pushl %eax;
+# define SAVE_OLDTYPE_3 SAVE_OLDTYPE_2
+# define SAVE_OLDTYPE_4 SAVE_OLDTYPE_2
+# define SAVE_OLDTYPE_5 SAVE_OLDTYPE_2
+
+# define DOCARGS_0 DOARGS_0
+# define DOCARGS_1 DOARGS_1
+# define DOCARGS_2 _DOARGS_2 (12)
+# define DOCARGS_3 _DOARGS_3 (20)
+# define DOCARGS_4 _DOARGS_4 (28)
+# define DOCARGS_5 _DOARGS_5 (36)
+
+# ifdef IS_IN_libpthread
+# define CENABLE call __pthread_enable_asynccancel;
+# define CDISABLE call __pthread_disable_asynccancel
+# else
+# define CENABLE call __libc_enable_asynccancel;
+# define CDISABLE call __libc_disable_asynccancel
+# endif
+# define POPCARGS_0 pushl %eax; movl %ecx, %eax; CDISABLE; popl %eax;
+# define POPCARGS_1 POPCARGS_0
+# define POPCARGS_2 xchgl (%esp), %eax; CDISABLE; popl %eax;
+# define POPCARGS_3 POPCARGS_2
+# define POPCARGS_4 POPCARGS_2
+# define POPCARGS_5 POPCARGS_2
+
+# define SINGLE_THREAD_P \
+ __builtin_expect (THREAD_GETMEM (THREAD_SELF, \
+ header.data.multiple_threads) == 0, 1)
-#define DOCARGS_0 DOARGS_0
-#define DOCARGS_1 DOARGS_1
-#define DOCARGS_2 _DOARGS_2 (12)
-#define DOCARGS_3 _DOARGS_3 (20)
-#define DOCARGS_4 _DOARGS_4 (28)
-#define DOCARGS_5 _DOARGS_5 (36)
+#else
-#define DISABLE call __libc_disable_asynccancel
-#define POPCARGS_0 pushl %eax; movl %ecx, %eax; DISABLE; popl %eax;
-#define POPCARGS_1 POPCARGS_0
-#define POPCARGS_2 xchgl (%esp), %eax; DISABLE; popl %eax;
-#define POPCARGS_3 POPCARGS_2
-#define POPCARGS_4 POPCARGS_2
-#define POPCARGS_5 POPCARGS_2
+/* This code should never be used but we define it anyhow. */
+# define SINGLE_THREAD_P (1)
#endif
diff --git a/sysdeps/generic/pselect.c b/sysdeps/generic/pselect.c
index 6aa60e8..e090d6e 100644
--- a/sysdeps/generic/pselect.c
+++ b/sysdeps/generic/pselect.c
@@ -22,6 +22,7 @@
#include <stddef.h> /* For NULL. */
#include <sys/time.h>
#include <sys/select.h>
+#include <sysdep-cancel.h>
/* Check the first NFDS descriptors each in READFDS (if not NULL) for read
readiness, in WRITEFDS (if not NULL) for write readiness, and in EXCEPTFDS
@@ -29,14 +30,9 @@
after waiting the interval specified therein. Additionally set the sigmask
SIGMASK for this call. Returns the number of ready descriptors, or -1 for
errors. */
-int
-__pselect (nfds, readfds, writefds, exceptfds, timeout, sigmask)
- int nfds;
- fd_set *readfds;
- fd_set *writefds;
- fd_set *exceptfds;
- const struct timespec *timeout;
- const sigset_t *sigmask;
+static int
+do_pselect (int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
+ const struct timespec *timeout, const sigset_t *sigmask)
{
struct timeval tval;
int retval;
@@ -62,5 +58,28 @@ __pselect (nfds, readfds, writefds, exceptfds, timeout, sigmask)
return retval;
}
+
+
+int
+__pselect (nfds, readfds, writefds, exceptfds, timeout, sigmask)
+ int nfds;
+ fd_set *readfds;
+ fd_set *writefds;
+ fd_set *exceptfds;
+ const struct timespec *timeout;
+ const sigset_t *sigmask;
+{
+ if (SINGLE_THREAD_P)
+ return do_pselect (nfds, readfds, writefds, exceptfds, timeout, sigmask);
+
+ int oldtype = LIBC_CANCEL_ASYNC ();
+
+ int result = do_pselect (nfds, readfds, writefds, exceptfds, timeout,
+ sigmask);
+
+ LIBC_CANCEL_RESET (oldtype);
+
+ return result;
+}
weak_alias (__pselect, pselect)
strong_alias (__pselect, __libc_pselect)
diff --git a/sysdeps/generic/sysdep-cancel.h b/sysdeps/generic/sysdep-cancel.h
index 0eca1e9..f065e6e 100644
--- a/sysdeps/generic/sysdep-cancel.h
+++ b/sysdeps/generic/sysdep-cancel.h
@@ -1 +1,6 @@
#include <sysdep.h>
+
+/* No multi-thread handling enabled. */
+#define SINGLE_THREAD_P (1)
+#define LIBC_CANCEL_ASYNC() 0 /* Just a dummy value. */
+#define LIBC_CANCEL_RESET(val) /* Nothing. */
diff --git a/sysdeps/posix/open64.c b/sysdeps/posix/open64.c
index 3db5292..8d8bdba 100644
--- a/sysdeps/posix/open64.c
+++ b/sysdeps/posix/open64.c
@@ -19,6 +19,7 @@
#include <fcntl.h>
#include <stdarg.h>
#include <bp-sym.h>
+#include <sysdep-cancel.h>
/* Open FILE with access OFLAG. If OFLAG includes O_CREAT,
a third argument is the file protection. */
@@ -35,7 +36,16 @@ __libc_open64 (const char *file, int oflag, ...)
va_end (arg);
}
- return __libc_open (file, oflag | O_LARGEFILE, mode);
+ if (SINGLE_THREAD_P)
+ return __libc_open (file, oflag | O_LARGEFILE, mode);
+
+ int oldtype = LIBC_CANCEL_ASYNC ();
+
+ int result = __libc_open (file, oflag | O_LARGEFILE, mode);
+
+ LIBC_CANCEL_RESET (oldtype);
+
+ return result;
}
weak_alias (__libc_open64, BP_SYM (__open64))
libc_hidden_weak (BP_SYM (__open64))
diff --git a/sysdeps/posix/sigpause.c b/sysdeps/posix/sigpause.c
index dba6912..e85a813 100644
--- a/sysdeps/posix/sigpause.c
+++ b/sysdeps/posix/sigpause.c
@@ -19,13 +19,14 @@
#include <errno.h>
#include <signal.h>
#include <stddef.h> /* For NULL. */
+#include <sysdep-cancel.h>
#include <sigset-cvt-mask.h>
/* Set the mask of blocked signals to MASK,
wait for a signal to arrive, and then restore the mask. */
-int
-__sigpause (int sig_or_mask, int is_sig)
+static int
+do_sigpause (int sig_or_mask, int is_sig)
{
sigset_t set;
@@ -42,6 +43,21 @@ __sigpause (int sig_or_mask, int is_sig)
return __sigsuspend (&set);
}
+
+int
+__sigpause (int sig_or_mask, int is_sig)
+{
+ if (SINGLE_THREAD_P)
+ return do_sigpause (sig_or_mask, is_sig);
+
+ int oldtype = LIBC_CANCEL_ASYNC ();
+
+ int result = do_sigpause (sig_or_mask, is_sig);
+
+ LIBC_CANCEL_RESET (oldtype);
+
+ return result;
+}
libc_hidden_def (__sigpause)
/* We have to provide a default version of this function since the
diff --git a/sysdeps/posix/sigwait.c b/sysdeps/posix/sigwait.c
index f2be322..8b422d2 100644
--- a/sysdeps/posix/sigwait.c
+++ b/sysdeps/posix/sigwait.c
@@ -1,5 +1,5 @@
/* Implementation of sigwait function from POSIX.1c.
- Copyright (C) 1996, 1997, 1999, 2000 Free Software Foundation, Inc.
+ Copyright (C) 1996, 1997, 1999, 2000, 2002 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996.
@@ -21,6 +21,7 @@
#include <errno.h>
#include <signal.h>
#include <stddef.h> /* For NULL. */
+#include <sysdep-cancel.h>
/* This is our dummy signal handler we use here. */
static void ignore_signal (int sig);
@@ -31,8 +32,8 @@ static void ignore_signal (int sig);
static int was_sig;
-int
-__sigwait (const sigset_t *set, int *sig)
+static int
+do_sigwait (const sigset_t *set, int *sig)
{
sigset_t tmp_mask;
struct sigaction saved[NSIG];
@@ -80,6 +81,22 @@ __sigwait (const sigset_t *set, int *sig)
*sig = was_sig;
return was_sig == -1 ? -1 : 0;
}
+
+
+int
+__sigwait (const sigset_t *set, int *sig)
+{
+ if (SINGLE_THREAD_P)
+ return do_sigwait (set, sig);
+
+ int oldtype = LIBC_CANCEL_ASYNC ();
+
+ int result = do_sigwait (set, sig);
+
+ LIBC_CANCEL_RESET (oldtype);
+
+ return result;
+}
libc_hidden_def (__sigwait)
weak_alias (__sigwait, sigwait)
diff --git a/sysdeps/posix/system.c b/sysdeps/posix/system.c
index 0881a3a..bca1c2e 100644
--- a/sysdeps/posix/system.c
+++ b/sysdeps/posix/system.c
@@ -24,6 +24,7 @@
#include <sys/types.h>
#include <sys/wait.h>
#include <bits/libc-lock.h>
+#include <sysdep-cancel.h>
#ifndef HAVE_GNU_LD
@@ -185,6 +186,15 @@ __libc_system (const char *line)
not be available after a chroot(), for example. */
return do_system ("exit 0") == 0;
- return do_system (line);
+ if (SINGLE_THREAD_P)
+ return do_system (line);
+
+ int oldtype = LIBC_CANCEL_ASYNC ();
+
+ int result = do_system (line);
+
+ LIBC_CANCEL_RESET (oldtype);
+
+ return result;
}
weak_alias (__libc_system, system)
diff --git a/sysdeps/posix/waitid.c b/sysdeps/posix/waitid.c
index ef2ab2e..679d97d 100644
--- a/sysdeps/posix/waitid.c
+++ b/sysdeps/posix/waitid.c
@@ -18,21 +18,18 @@
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA. */
+#include <assert.h>
#include <errno.h>
#include <signal.h>
#define __need_NULL
#include <stddef.h>
#include <sys/wait.h>
#include <sys/types.h>
+#include <sysdep-cancel.h>
-#include <assert.h>
-int
-__waitid (idtype, id, infop, options)
- idtype_t idtype;
- id_t id;
- siginfo_t *infop;
- int options;
+static int
+do_waitid (idtype_t idtype, id_t id, siginfo_t *infop, int options)
{
pid_t pid, child;
int status;
@@ -118,5 +115,25 @@ __waitid (idtype, id, infop, options)
return 0;
}
+
+
+int
+__waitid (idtype, id, infop, options)
+ idtype_t idtype;
+ id_t id;
+ siginfo_t *infop;
+ int options;
+{
+ if (SINGLE_THREAD_P)
+ return do_waitid (idtype, id, infop, options);
+
+ int oldtype = LIBC_CANCEL_ASYNC ();
+
+ int result = do_waitid (idtype, id, infop, options);
+
+ LIBC_CANCEL_RESET (oldtype);
+
+ return result;
+}
weak_alias (__waitid, waitid)
strong_alias (__waitid, __libc_waitid)
diff --git a/sysdeps/unix/sysv/linux/accept.S b/sysdeps/unix/sysv/linux/accept.S
index 431dec0..75d5736 100644
--- a/sysdeps/unix/sysv/linux/accept.S
+++ b/sysdeps/unix/sysv/linux/accept.S
@@ -1,4 +1,5 @@
#define socket accept
#define __socket __libc_accept
#define NARGS 3
+#define NEED_CANCELLATION
#include <socket.S>
diff --git a/sysdeps/unix/sysv/linux/connect.S b/sysdeps/unix/sysv/linux/connect.S
index 2de3518..7d1fa12 100644
--- a/sysdeps/unix/sysv/linux/connect.S
+++ b/sysdeps/unix/sysv/linux/connect.S
@@ -1,6 +1,7 @@
#define socket connect
#define __socket __libc_connect
#define NARGS 3
+#define NEED_CANCELLATION
#include <socket.S>
strong_alias (__libc_connect, __connect_internal)
weak_alias (__libc_connect, __connect)
diff --git a/sysdeps/unix/sysv/linux/i386/fcntl.c b/sysdeps/unix/sysv/linux/i386/fcntl.c
index 12bb291..4ff5ee3 100644
--- a/sysdeps/unix/sysv/linux/i386/fcntl.c
+++ b/sysdeps/unix/sysv/linux/i386/fcntl.c
@@ -21,7 +21,7 @@
#include <fcntl.h>
#include <stdarg.h>
-#include <sysdep.h>
+#include <sysdep-cancel.h>
#include <sys/syscall.h>
#include "../kernel-features.h"
@@ -33,21 +33,11 @@ extern int __syscall_fcntl64 (int __fd, int __cmd, ...);
#if __ASSUME_FCNTL64 == 0
/* This variable is shared with all files that check for fcntl64. */
int __have_no_fcntl64;
-#endif
+
int
__libc_fcntl (int fd, int cmd, ...)
{
- va_list ap;
- void *arg;
-
- va_start (ap, cmd);
- arg = va_arg (ap, void *);
- va_end (ap);
-
-#if __ASSUME_FCNTL64 > 0
- return INLINE_SYSCALL (fcntl64, 3, fd, cmd, arg);
-#else
# ifdef __NR_fcntl64
if (! __have_no_fcntl64)
{
@@ -128,7 +118,39 @@ __libc_fcntl (int fd, int cmd, ...)
return INLINE_SYSCALL (fcntl, 3, fd, cmd, arg);
}
return -1;
+}
#endif /* __ASSUME_FCNTL64 */
+
+
+int
+__libc_fcntl (int fd, int cmd, ...)
+{
+ va_list ap;
+ void *arg;
+
+ va_start (ap, cmd);
+ arg = va_arg (ap, void *);
+ va_end (ap);
+
+#if __ASSUME_FCNTL64 > 0
+ if (SINGLE_THREAD_P)
+ return INLINE_SYSCALL (fcntl64, 3, fd, cmd, arg);
+
+ int oldtype = LIBC_CANCEL_ASYNC ();
+
+ int result = INLINE_SYSCALL (fcntl64, 3, fd, cmd, arg);
+#else
+ if (SINGLE_THREAD_P)
+ return do_fcntl (fd, cmd, arg);
+
+ int oldtype = LIBC_CANCEL_ASYNC ();
+
+ int result = do_fcntl (fd, cmd, arg);
+#endif
+
+ LIBC_CANCEL_RESET (oldtype);
+
+ return result;
}
libc_hidden_def (__libc_fcntl)
diff --git a/sysdeps/unix/sysv/linux/i386/socket.S b/sysdeps/unix/sysv/linux/i386/socket.S
index d060792..866a674 100644
--- a/sysdeps/unix/sysv/linux/i386/socket.S
+++ b/sysdeps/unix/sysv/linux/i386/socket.S
@@ -1,4 +1,4 @@
-/* Copyright (C) 1995, 1996, 1997, 1998 Free Software Foundation, Inc.
+/* Copyright (C) 1995, 1996, 1997, 1998, 2002 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
@@ -16,8 +16,9 @@
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA. */
-#include <sysdep.h>
+#include <sysdep-cancel.h>
#include <socketcall.h>
+#include <tls.h>
#define P(a, b) P2(a, b)
#define P2(a, b) a##b
@@ -32,15 +33,19 @@
The .S files for the other calls just #define socket and #include this. */
#ifndef __socket
-#ifndef NO_WEAK_ALIAS
-#define __socket P(__,socket)
-#else
-#define __socket socket
-#endif
+# ifndef NO_WEAK_ALIAS
+# define __socket P(__,socket)
+# else
+# define __socket socket
+# endif
#endif
.globl __socket
ENTRY (__socket)
+#if defined NEED_CANCELLATION && defined CENABLE
+ cmpl $0, %gs:MULTIPLE_THREADS_OFFSET
+ jne 1f
+#endif
/* Save registers. */
movl %ebx, %edx
@@ -65,6 +70,43 @@ ENTRY (__socket)
L(pseudo_end):
ret
+
+#if defined NEED_CANCELLATION && defined CENABLE
+ /* We need one more register. */
+1: pushl %esi
+
+ /* Enable asynchronous cancellation. */
+ call __libc_enable_asynccancel /* No @plt */
+ movl %eax, %esi
+
+ /* Save registers. */
+ movl %ebx, %edx
+
+ movl $SYS_ify(socketcall), %eax /* System call number in %eax. */
+
+ /* Use ## so `socket' is a separate token that might be #define'd. */
+ movl $P(SOCKOP_,socket), %ebx /* Subcode is first arg to syscall. */
+ lea 8(%esp), %ecx /* Address of args is 2nd arg. */
+
+ /* Do the system call trap. */
+ int $0x80
+
+ /* Restore the cancellation. */
+ xchgl %esi, %eax
+ call __libc_disable_asynccancel /* No @plt */
+
+ /* Restore registers. */
+ movl %esi, %eax
+ movl %edx, %ebx
+ popl %esi
+
+ /* %eax is < 0 if there was an error. */
+ cmpl $-125, %eax
+ jae SYSCALL_ERROR_LABEL
+
+ /* Successful; return the syscall's value. */
+ ret
+#endif
PSEUDO_END (__socket)
#ifndef NO_WEAK_ALIAS
diff --git a/sysdeps/unix/sysv/linux/llseek.c b/sysdeps/unix/sysv/linux/llseek.c
index fa83f10..9ee340d 100644
--- a/sysdeps/unix/sysv/linux/llseek.c
+++ b/sysdeps/unix/sysv/linux/llseek.c
@@ -1,5 +1,5 @@
/* Long-long seek operation.
- Copyright (C) 1996, 1997, 1998, 1999, 2000 Free Software Foundation, Inc.
+ Copyright (C) 1996,1997,1998,1999,2000,2002 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
@@ -20,7 +20,7 @@
#include <errno.h>
#include <sys/types.h>
-#include <sysdep.h>
+#include <sysdep-cancel.h>
#include <sys/syscall.h>
extern int __syscall__llseek (int fd, off_t offset_hi, off_t offset_lo,
@@ -32,11 +32,22 @@ extern loff_t __llseek (int fd, loff_t offset, int whence);
loff_t
__llseek (int fd, loff_t offset, int whence)
{
- loff_t result;
+ loff_t retval;
- return (loff_t) (INLINE_SYSCALL (_llseek, 5, fd, (off_t) (offset >> 32),
- (off_t) (offset & 0xffffffff),
- __ptrvalue (&result), whence) ?: result);
+ if (SINGLE_THREAD_P)
+ return (loff_t) (INLINE_SYSCALL (_llseek, 5, fd, (off_t) (offset >> 32),
+ (off_t) (offset & 0xffffffff),
+ __ptrvalue (&retval), whence) ?: retval);
+
+ int oldtype = LIBC_CANCEL_ASYNC ();
+
+ int result = (loff_t) INLINE_SYSCALL (_llseek, 5, fd, (off_t) (offset >> 32),
+ (off_t) (offset & 0xffffffff),
+ __ptrvalue (&retval), whence);
+
+ LIBC_CANCEL_RESET (oldtype);
+
+ return (loff_t) result ?: retval;
}
weak_alias (__llseek, llseek)
strong_alias (__llseek, __libc_lseek64)
diff --git a/sysdeps/unix/sysv/linux/msgrcv.c b/sysdeps/unix/sysv/linux/msgrcv.c
index fdc13ff..7d8a8e7 100644
--- a/sysdeps/unix/sysv/linux/msgrcv.c
+++ b/sysdeps/unix/sysv/linux/msgrcv.c
@@ -21,7 +21,7 @@
#include <sys/msg.h>
#include <ipc_priv.h>
-#include <sysdep.h>
+#include <sysdep-cancel.h>
#include <sys/syscall.h>
#include <bp-checks.h>
@@ -50,6 +50,17 @@ __libc_msgrcv (msqid, msgp, msgsz, msgtyp, msgflg)
tmp.msgp = CHECK_N (msgp, msgsz);
tmp.msgtyp = msgtyp;
- return INLINE_SYSCALL (ipc, 5, IPCOP_msgrcv, msqid, msgsz, msgflg, __ptrvalue (&tmp));
+ if (SINGLE_THREAD_P)
+ return INLINE_SYSCALL (ipc, 5, IPCOP_msgrcv, msqid, msgsz, msgflg,
+ __ptrvalue (&tmp));
+
+ int oldtype = LIBC_CANCEL_ASYNC ();
+
+ int result = INLINE_SYSCALL (ipc, 5, IPCOP_msgrcv, msqid, msgsz, msgflg,
+ __ptrvalue (&tmp));
+
+ LIBC_CANCEL_RESET (oldtype);
+
+ return result;
}
weak_alias (__libc_msgrcv, msgrcv)
diff --git a/sysdeps/unix/sysv/linux/msgsnd.c b/sysdeps/unix/sysv/linux/msgsnd.c
index 7beba6b..c2031be 100644
--- a/sysdeps/unix/sysv/linux/msgsnd.c
+++ b/sysdeps/unix/sysv/linux/msgsnd.c
@@ -21,7 +21,7 @@
#include <sys/msg.h>
#include <ipc_priv.h>
-#include <sysdep.h>
+#include <sysdep-cancel.h>
#include <sys/syscall.h>
#include <bp-checks.h>
@@ -33,7 +33,17 @@ __libc_msgsnd (msqid, msgp, msgsz, msgflg)
size_t msgsz;
int msgflg;
{
- return INLINE_SYSCALL (ipc, 5, IPCOP_msgsnd, msqid, msgsz,
- msgflg, (void *) CHECK_N (msgp, msgsz));
+ if (SINGLE_THREAD_P)
+ return INLINE_SYSCALL (ipc, 5, IPCOP_msgsnd, msqid, msgsz,
+ msgflg, (void *) CHECK_N (msgp, msgsz));
+
+ int oldtype = LIBC_CANCEL_ASYNC ();
+
+ int result = INLINE_SYSCALL (ipc, 5, IPCOP_msgsnd, msqid, msgsz,
+ msgflg, (void *) CHECK_N (msgp, msgsz));
+
+ LIBC_CANCEL_RESET (oldtype);
+
+ return result;
}
weak_alias (__libc_msgsnd, msgsnd)
diff --git a/sysdeps/unix/sysv/linux/open64.c b/sysdeps/unix/sysv/linux/open64.c
new file mode 100644
index 0000000..5fb5363
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/open64.c
@@ -0,0 +1,53 @@
+/* Copyright (C) 1991,1995-1997,1999,2000,2002 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 <errno.h>
+#include <fcntl.h>
+#include <stdarg.h>
+#include <bp-sym.h>
+#include <sysdep-cancel.h>
+
+/* Open FILE with access OFLAG. If OFLAG includes O_CREAT,
+ a third argument is the file protection. */
+int
+__libc_open64 (const char *file, int oflag, ...)
+{
+ int mode = 0;
+
+ if (oflag & O_CREAT)
+ {
+ va_list arg;
+ va_start (arg, oflag);
+ mode = va_arg (arg, int);
+ va_end (arg);
+ }
+
+ if (SINGLE_THREAD_P)
+ return INLINE_SYSCALL (open, 3, file, oflag | O_LARGEFILE, mode);
+
+ int oldtype = LIBC_CANCEL_ASYNC ();
+
+ int result = INLINE_SYSCALL (open, 3, file, oflag | O_LARGEFILE, mode);
+
+ LIBC_CANCEL_RESET (oldtype);
+
+ return result;
+}
+weak_alias (__libc_open64, BP_SYM (__open64))
+libc_hidden_weak (BP_SYM (__open64))
+weak_alias (__libc_open64, BP_SYM (open64))
diff --git a/sysdeps/unix/sysv/linux/poll.c b/sysdeps/unix/sysv/linux/poll.c
index 296893d..c136c21 100644
--- a/sysdeps/unix/sysv/linux/poll.c
+++ b/sysdeps/unix/sysv/linux/poll.c
@@ -20,7 +20,7 @@
#include <errno.h>
#include <sys/poll.h>
-#include <sysdep.h>
+#include <sysdep-cancel.h>
#include <sys/syscall.h>
#include <bp-checks.h>
@@ -36,20 +36,19 @@ static int __emulate_poll (struct pollfd *fds, nfds_t nfds,
int timeout) internal_function;
# endif
-/* The real implementation. */
-int
-__poll (fds, nfds, timeout)
- struct pollfd *fds;
- nfds_t nfds;
- int timeout;
-{
+
# if __ASSUME_POLL_SYSCALL == 0
+/* For loser kernels. */
+static int
+loser_poll (struct pollfd *fds, nfds_t nfds, int timeout)
+{
static int must_emulate;
if (!must_emulate)
{
int errno_saved = errno;
- int retval = INLINE_SYSCALL (poll, 3, CHECK_N (fds, nfds), nfds, timeout);
+ int retval = INLINE_SYSCALL (poll, 3, CHECK_N (fds, nfds), nfds,
+ timeout);
if (retval >= 0 || errno != ENOSYS)
return retval;
@@ -59,8 +58,39 @@ __poll (fds, nfds, timeout)
}
return __emulate_poll (fds, nfds, timeout);
+}
+# endif
+
+
+/* The real implementation. */
+int
+__poll (fds, nfds, timeout)
+ struct pollfd *fds;
+ nfds_t nfds;
+ int timeout;
+{
+# if __ASSUME_POLL_SYSCALL == 0
+ if (SINGLE_THREAD_P)
+ return loser_poll (CHECK_N (fds, nfds), nfds, timeout);
+
+ int oldtype = LIBC_CANCEL_ASYNC ();
+
+ int result = loser_poll (CHECK_N (fds, nfds), nfds, timeout);
+
+ LIBC_CANCEL_RESET (oldtype);
+
+ return result;
# else
- return INLINE_SYSCALL (poll, 3, CHECK_N (fds, nfds), nfds, timeout);
+ if (SINGLE_THREAD_P)
+ return INLINE_SYSCALL (poll, 3, CHECK_N (fds, nfds), nfds, timeout);
+
+ int oldtype = LIBC_CANCEL_ASYNC ();
+
+ int result = INLINE_SYSCALL (poll, 3, CHECK_N (fds, nfds), nfds, timeout);
+
+ LIBC_CANCEL_RESET (oldtype);
+
+ return result;
# endif
}
libc_hidden_def (__poll)
diff --git a/sysdeps/unix/sysv/linux/pread.c b/sysdeps/unix/sysv/linux/pread.c
index 31abf7e..a506c17 100644
--- a/sysdeps/unix/sysv/linux/pread.c
+++ b/sysdeps/unix/sysv/linux/pread.c
@@ -22,7 +22,7 @@
#include <endian.h>
#include <unistd.h>
-#include <sysdep.h>
+#include <sysdep-cancel.h>
#include <sys/syscall.h>
#include <bp-checks.h>
@@ -47,12 +47,8 @@ static ssize_t __emulate_pread (int fd, void *buf, size_t count,
# endif
-ssize_t
-__libc_pread (fd, buf, count, offset)
- int fd;
- void *buf;
- size_t count;
- off_t offset;
+static ssize_t
+do_pread (int fd, void *buf, size_t count, off_t offset)
{
ssize_t result;
@@ -69,6 +65,26 @@ __libc_pread (fd, buf, count, offset)
return result;
}
+
+ssize_t
+__libc_pread (fd, buf, count, offset)
+ int fd;
+ void *buf;
+ size_t count;
+ off_t offset;
+{
+ if (SINGLE_THREAD_P)
+ return do_pread (fd, buf, count, offset);
+
+ int oldtype = LIBC_CANCEL_ASYNC ();
+
+ ssize_t result = do_pread (fd, buf, count, offset);
+
+ LIBC_CANCEL_RESET (oldtype);
+
+ return result;
+}
+
strong_alias (__libc_pread, __pread)
weak_alias (__libc_pread, pread)
diff --git a/sysdeps/unix/sysv/linux/pread64.c b/sysdeps/unix/sysv/linux/pread64.c
index d27f9af..61ff7f5 100644
--- a/sysdeps/unix/sysv/linux/pread64.c
+++ b/sysdeps/unix/sysv/linux/pread64.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1997, 1998, 1999, 2000 Free Software Foundation, Inc.
+/* Copyright (C) 1997, 1998, 1999, 2000, 2002 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
@@ -21,7 +21,7 @@
#include <endian.h>
#include <unistd.h>
-#include <sysdep.h>
+#include <sysdep-cancel.h>
#include <sys/syscall.h>
#include <bp-checks.h>
@@ -45,12 +45,8 @@ static ssize_t __emulate_pread64 (int fd, void *buf, size_t count,
# endif
-ssize_t
-__libc_pread64 (fd, buf, count, offset)
- int fd;
- void *buf;
- size_t count;
- off64_t offset;
+static ssize_t
+do_pread64 (int fd, void *buf, size_t count, off64_t offset)
{
ssize_t result;
@@ -67,6 +63,26 @@ __libc_pread64 (fd, buf, count, offset)
return result;
}
+
+ssize_t
+__libc_pread64 (fd, buf, count, offset)
+ int fd;
+ void *buf;
+ size_t count;
+ off64_t offset;
+{
+ if (SINGLE_THREAD_P)
+ return do_pread64 (fd, buf, count, offset);
+
+ int oldtype = LIBC_CANCEL_ASYNC ();
+
+ ssize_t result = do_pread64 (fd, buf, count, offset);
+
+ LIBC_CANCEL_RESET (oldtype);
+
+ return result;
+}
+
weak_alias (__libc_pread64, __pread64)
weak_alias (__libc_pread64, pread64)
diff --git a/sysdeps/unix/sysv/linux/pwrite.c b/sysdeps/unix/sysv/linux/pwrite.c
index 13bbc76..af4ac36 100644
--- a/sysdeps/unix/sysv/linux/pwrite.c
+++ b/sysdeps/unix/sysv/linux/pwrite.c
@@ -22,7 +22,7 @@
#include <endian.h>
#include <unistd.h>
-#include <sysdep.h>
+#include <sysdep-cancel.h>
#include <sys/syscall.h>
#include <bp-checks.h>
@@ -38,8 +38,9 @@
#if defined __NR_pwrite || __ASSUME_PWRITE_SYSCALL > 0
/* The order of hi, lo depends on endianness. */
-extern ssize_t __syscall_pwrite (int fd, const void *__unbounded buf, size_t count,
- off_t offset_hi, off_t offset_lo);
+extern ssize_t __syscall_pwrite (int fd, const void *__unbounded buf,
+ size_t count, off_t offset_hi,
+ off_t offset_lo);
# if __ASSUME_PWRITE_SYSCALL == 0
static ssize_t __emulate_pwrite (int fd, const void *buf, size_t count,
@@ -47,12 +48,8 @@ static ssize_t __emulate_pwrite (int fd, const void *buf, size_t count,
# endif
-ssize_t
-__libc_pwrite (fd, buf, count, offset)
- int fd;
- const void *buf;
- size_t count;
- off_t offset;
+static ssize_t
+do_pwrite (int fd, const void *buf, size_t count, off_t offset)
{
ssize_t result;
@@ -69,6 +66,26 @@ __libc_pwrite (fd, buf, count, offset)
return result;
}
+
+ssize_t
+__libc_pwrite (fd, buf, count, offset)
+ int fd;
+ const void *buf;
+ size_t count;
+ off_t offset;
+{
+ if (SINGLE_THREAD_P)
+ return do_pwrite (fd, buf, count, offset);
+
+ int oldtype = LIBC_CANCEL_ASYNC ();
+
+ ssize_t result = do_pwrite (fd, buf, count, offset);
+
+ LIBC_CANCEL_RESET (oldtype);
+
+ return result;
+}
+
strong_alias (__libc_pwrite, __pwrite)
weak_alias (__libc_pwrite, pwrite)
diff --git a/sysdeps/unix/sysv/linux/pwrite64.c b/sysdeps/unix/sysv/linux/pwrite64.c
index dc81cd6..91f4895 100644
--- a/sysdeps/unix/sysv/linux/pwrite64.c
+++ b/sysdeps/unix/sysv/linux/pwrite64.c
@@ -21,7 +21,7 @@
#include <endian.h>
#include <unistd.h>
-#include <sysdep.h>
+#include <sysdep-cancel.h>
#include <sys/syscall.h>
#include <bp-checks.h>
@@ -45,12 +45,8 @@ static ssize_t __emulate_pwrite64 (int fd, const void *buf, size_t count,
# endif
-ssize_t
-__libc_pwrite64 (fd, buf, count, offset)
- int fd;
- const void *buf;
- size_t count;
- off64_t offset;
+static ssize_t
+do_pwrite64 (int fd, const void *buf, size_t count, off64_t offset)
{
ssize_t result;
@@ -67,6 +63,26 @@ __libc_pwrite64 (fd, buf, count, offset)
return result;
}
+
+ssize_t
+__libc_pwrite64 (fd, buf, count, offset)
+ int fd;
+ const void *buf;
+ size_t count;
+ off64_t offset;
+{
+ if (SINGLE_THREAD_P)
+ return do_pwrite64 (fd, buf, count, offset);
+
+ int oldtype = LIBC_CANCEL_ASYNC ();
+
+ ssize_t result = do_pwrite64 (fd, buf, count, offset);
+
+ LIBC_CANCEL_RESET (oldtype);
+
+ return result;
+}
+
weak_alias (__libc_pwrite64, __pwrite64)
libc_hidden_weak (__pwrite64)
weak_alias (__libc_pwrite64, pwrite64)
diff --git a/sysdeps/unix/sysv/linux/readv.c b/sysdeps/unix/sysv/linux/readv.c
index eeba46a..e6f9fb0 100644
--- a/sysdeps/unix/sysv/linux/readv.c
+++ b/sysdeps/unix/sysv/linux/readv.c
@@ -22,7 +22,7 @@
#include <sys/param.h>
#include <sys/uio.h>
-#include <sysdep.h>
+#include <sysdep-cancel.h>
#include <sys/syscall.h>
#include <bp-checks.h>
@@ -39,8 +39,8 @@ static ssize_t __atomic_readv_replacement (int, __const struct iovec *,
/* We should deal with kernel which have a smaller UIO_FASTIOV as well
as a very big count. */
-ssize_t
-__libc_readv (fd, vector, count)
+static ssize_t
+do_readv (fd, vector, count)
int fd;
const struct iovec *vector;
int count;
@@ -54,6 +54,25 @@ __libc_readv (fd, vector, count)
return __atomic_readv_replacement (fd, vector, count);
}
+
+
+ssize_t
+__libc_readv (fd, vector, count)
+ int fd;
+ const struct iovec *vector;
+ int count;
+{
+ if (SINGLE_THREAD_P)
+ return do_readv (fd, vector, count);
+
+ int oldtype = LIBC_CANCEL_ASYNC ();
+
+ int result = do_readv (fd, vector, count);
+
+ LIBC_CANCEL_RESET (oldtype);
+
+ return result;
+}
strong_alias (__libc_readv, __readv)
weak_alias (__libc_readv, readv)
diff --git a/sysdeps/unix/sysv/linux/recv.S b/sysdeps/unix/sysv/linux/recv.S
index cb9eb91..331844a 100644
--- a/sysdeps/unix/sysv/linux/recv.S
+++ b/sysdeps/unix/sysv/linux/recv.S
@@ -1,5 +1,6 @@
#define socket recv
#define __socket __libc_recv
#define NARGS 4
+#define NEED_CANCELLATION
#include <socket.S>
weak_alias (__libc_recv, __recv)
diff --git a/sysdeps/unix/sysv/linux/recvfrom.S b/sysdeps/unix/sysv/linux/recvfrom.S
index 93a3110..ccbb0a7 100644
--- a/sysdeps/unix/sysv/linux/recvfrom.S
+++ b/sysdeps/unix/sysv/linux/recvfrom.S
@@ -1,5 +1,6 @@
#define socket recvfrom
#define __socket __libc_recvfrom
#define NARGS 6
+#define NEED_CANCELLATION
#include <socket.S>
weak_alias (__libc_recvfrom, __recvfrom)
diff --git a/sysdeps/unix/sysv/linux/recvmsg.S b/sysdeps/unix/sysv/linux/recvmsg.S
index 98be36b..d44bc39 100644
--- a/sysdeps/unix/sysv/linux/recvmsg.S
+++ b/sysdeps/unix/sysv/linux/recvmsg.S
@@ -1,5 +1,6 @@
#define socket recvmsg
#define __socket __libc_recvmsg
#define NARGS 3
+#define NEED_CANCELLATION
#include <socket.S>
weak_alias (__libc_recvmsg, __recvmsg)
diff --git a/sysdeps/unix/sysv/linux/send.S b/sysdeps/unix/sysv/linux/send.S
index 83d5938..259748f 100644
--- a/sysdeps/unix/sysv/linux/send.S
+++ b/sysdeps/unix/sysv/linux/send.S
@@ -1,6 +1,7 @@
#define socket send
#define __socket __libc_send
#define NARGS 4
+#define NEED_CANCELLATION
#include <socket.S>
weak_alias (__libc_send, __send)
libc_hidden_def (__send)
diff --git a/sysdeps/unix/sysv/linux/sendmsg.S b/sysdeps/unix/sysv/linux/sendmsg.S
index c01d9b6..a220894 100644
--- a/sysdeps/unix/sysv/linux/sendmsg.S
+++ b/sysdeps/unix/sysv/linux/sendmsg.S
@@ -1,5 +1,6 @@
#define socket sendmsg
#define __socket __libc_sendmsg
#define NARGS 3
+#define NEED_CANCELLATION
#include <socket.S>
weak_alias (__libc_sendmsg, __sendmsg)
diff --git a/sysdeps/unix/sysv/linux/sendto.S b/sysdeps/unix/sysv/linux/sendto.S
index 8717b2b..a65e44f 100644
--- a/sysdeps/unix/sysv/linux/sendto.S
+++ b/sysdeps/unix/sysv/linux/sendto.S
@@ -1,5 +1,6 @@
#define socket sendto
#define __socket __libc_sendto
#define NARGS 6
+#define NEED_CANCELLATION
#include <socket.S>
weak_alias (__libc_sendto, __sendto)
diff --git a/sysdeps/unix/sysv/linux/sigsuspend.c b/sysdeps/unix/sysv/linux/sigsuspend.c
index 443c855..71c2bae 100644
--- a/sysdeps/unix/sysv/linux/sigsuspend.c
+++ b/sysdeps/unix/sysv/linux/sigsuspend.c
@@ -20,7 +20,7 @@
#include <signal.h>
#include <unistd.h>
-#include <sysdep.h>
+#include <sysdep-cancel.h>
#include <sys/syscall.h>
#include <bp-checks.h>
@@ -30,20 +30,15 @@ extern int __syscall_sigsuspend (int, unsigned long int, unsigned long int);
extern int __syscall_rt_sigsuspend (const sigset_t *__unbounded, size_t);
+#if !__ASSUME_REALTIME_SIGNALS
/* The variable is shared between all wrappers around signal handling
functions which have RT equivalents. The definition is in sigaction.c. */
extern int __libc_missing_rt_sigs;
-/* Change the set of blocked signals to SET,
- wait until a signal arrives, and restore the set of blocked signals. */
-int
-__sigsuspend (set)
- const sigset_t *set;
+static int
+do_sigsuspend (const sigset_t *set)
{
-#if __ASSUME_REALTIME_SIGNALS
- return INLINE_SYSCALL (rt_sigsuspend, 2, CHECK_SIGSET (set), _NSIG / 8);
-#else
# ifdef __NR_rt_sigsuspend
/* First try the RT signals. */
if (!__libc_missing_rt_sigs)
@@ -62,6 +57,38 @@ __sigsuspend (set)
# endif
return INLINE_SYSCALL (sigsuspend, 3, 0, 0, set->__val[0]);
+}
+#endif
+
+/* Change the set of blocked signals to SET,
+ wait until a signal arrives, and restore the set of blocked signals. */
+int
+__sigsuspend (set)
+ const sigset_t *set;
+{
+#if __ASSUME_REALTIME_SIGNALS
+ if (SINGLE_THREAD_P)
+ return INLINE_SYSCALL (rt_sigsuspend, 2, CHECK_SIGSET (set), _NSIG / 8);
+
+ int oldtype = LIBC_CANCEL_ASYNC ();
+
+ int result = INLINE_SYSCALL (rt_sigsuspend, 2, CHECK_SIGSET (set),
+ _NSIG / 8);
+
+ LIBC_CANCEL_RESET (oldtype);
+
+ return result;
+#else
+ if (SINGLE_THREAD_P)
+ return do_sigsuspend (set);
+
+ int oldtype = LIBC_CANCEL_ASYNC ();
+
+ int result = do_sigsuspend (set);
+
+ LIBC_CANCEL_RESET (oldtype);
+
+ return result;
#endif
}
libc_hidden_def (__sigsuspend)
diff --git a/sysdeps/unix/sysv/linux/sigtimedwait.c b/sysdeps/unix/sysv/linux/sigtimedwait.c
index c374287..5ace261 100644
--- a/sysdeps/unix/sysv/linux/sigtimedwait.c
+++ b/sysdeps/unix/sysv/linux/sigtimedwait.c
@@ -19,7 +19,7 @@
#include <errno.h>
#include <signal.h>
-#include <sysdep.h>
+#include <sysdep-cancel.h>
#include <sys/syscall.h>
#include <bp-checks.h>
@@ -35,10 +35,22 @@ __sigtimedwait (set, info, timeout)
siginfo_t *info;
const struct timespec *timeout;
{
+ if (SINGLE_THREAD_P)
+ /* XXX The size argument hopefully will have to be changed to the
+ real size of the user-level sigset_t. */
+ return INLINE_SYSCALL (rt_sigtimedwait, 4, CHECK_SIGSET (set),
+ CHECK_1 (info), timeout, _NSIG / 8);
+
+ int oldtype = LIBC_CANCEL_ASYNC ();
+
/* XXX The size argument hopefully will have to be changed to the
real size of the user-level sigset_t. */
- return INLINE_SYSCALL (rt_sigtimedwait, 4, CHECK_SIGSET (set),
- CHECK_1 (info), timeout, _NSIG / 8);
+ int result = INLINE_SYSCALL (rt_sigtimedwait, 4, CHECK_SIGSET (set),
+ CHECK_1 (info), timeout, _NSIG / 8);
+
+ LIBC_CANCEL_RESET (oldtype);
+
+ return result;
}
libc_hidden_def (__sigtimedwait)
weak_alias (__sigtimedwait, sigtimedwait)
diff --git a/sysdeps/unix/sysv/linux/sigwait.c b/sysdeps/unix/sysv/linux/sigwait.c
index 78e5852..f99c640 100644
--- a/sysdeps/unix/sysv/linux/sigwait.c
+++ b/sysdeps/unix/sysv/linux/sigwait.c
@@ -21,7 +21,7 @@
#define __need_NULL
#include <stddef.h>
-#include <sysdep.h>
+#include <sysdep-cancel.h>
#include <sys/syscall.h>
#include <bp-checks.h>
@@ -31,10 +31,8 @@ extern int __syscall_rt_sigtimedwait (const sigset_t *__unbounded, siginfo_t *__
/* Return any pending signal or wait for one for the given time. */
-int
-__sigwait (set, sig)
- const sigset_t *set;
- int *sig;
+static int
+do_sigwait (const sigset_t *set, int *sig)
{
int ret;
@@ -64,6 +62,23 @@ __sigwait (set, sig)
return ret;
}
+
+int
+__sigwait (set, sig)
+ const sigset_t *set;
+ int *sig;
+{
+ if (SINGLE_THREAD_P)
+ return do_sigwait (set, sig);
+
+ int oldtype = LIBC_CANCEL_ASYNC ();
+
+ int result = do_sigwait (set, sig);
+
+ LIBC_CANCEL_RESET (oldtype);
+
+ return result;
+}
libc_hidden_def (__sigwait)
weak_alias (__sigwait, sigwait)
#else
diff --git a/sysdeps/unix/sysv/linux/sigwaitinfo.c b/sysdeps/unix/sysv/linux/sigwaitinfo.c
index d1e7a8d..102b924 100644
--- a/sysdeps/unix/sysv/linux/sigwaitinfo.c
+++ b/sysdeps/unix/sysv/linux/sigwaitinfo.c
@@ -21,7 +21,7 @@
#define __need_NULL
#include <stddef.h>
-#include <sysdep.h>
+#include <sysdep-cancel.h>
#include <sys/syscall.h>
#include <bp-checks.h>
@@ -36,10 +36,22 @@ __sigwaitinfo (set, info)
const sigset_t *set;
siginfo_t *info;
{
+ if (SINGLE_THREAD_P)
+ /* XXX The size argument hopefully will have to be changed to the
+ real size of the user-level sigset_t. */
+ return INLINE_SYSCALL (rt_sigtimedwait, 4, CHECK_SIGSET (set),
+ CHECK_1 (info), NULL, _NSIG / 8);
+
+ int oldtype = LIBC_CANCEL_ASYNC ();
+
/* XXX The size argument hopefully will have to be changed to the
real size of the user-level sigset_t. */
- return INLINE_SYSCALL (rt_sigtimedwait, 4, CHECK_SIGSET (set),
- CHECK_1 (info), NULL, _NSIG / 8);
+ int result = INLINE_SYSCALL (rt_sigtimedwait, 4, CHECK_SIGSET (set),
+ CHECK_1 (info), NULL, _NSIG / 8);
+
+ LIBC_CANCEL_RESET (oldtype);
+
+ return result;
}
libc_hidden_def (__sigwaitinfo)
weak_alias (__sigwaitinfo, sigwaitinfo)
diff --git a/sysdeps/unix/sysv/linux/tcdrain.c b/sysdeps/unix/sysv/linux/tcdrain.c
index a7234b0..4868565 100644
--- a/sysdeps/unix/sysv/linux/tcdrain.c
+++ b/sysdeps/unix/sysv/linux/tcdrain.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1995, 1996, 1997 Free Software Foundation, Inc.
+/* Copyright (C) 1995, 1996, 1997, 2002 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
@@ -16,14 +16,26 @@
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA. */
+#include <errno.h>
#include <termios.h>
#include <sys/ioctl.h>
+#include <sysdep-cancel.h>
/* Wait for pending output to be written on FD. */
int
__libc_tcdrain (int fd)
{
+ if (SINGLE_THREAD_P)
+ /* With an argument of 1, TCSBRK for output to be drain. */
+ return INLINE_SYSCALL (ioctl, 3, fd, TCSBRK, 1);
+
+ int oldtype = LIBC_CANCEL_ASYNC ();
+
/* With an argument of 1, TCSBRK for output to be drain. */
- return __ioctl (fd, TCSBRK, 1);
+ int result = INLINE_SYSCALL (ioctl, 3, fd, TCSBRK, 1);
+
+ LIBC_CANCEL_RESET (oldtype);
+
+ return result;
}
weak_alias (__libc_tcdrain, tcdrain)
diff --git a/sysdeps/unix/sysv/linux/wait.c b/sysdeps/unix/sysv/linux/wait.c
index 79d5458..f01d75c 100644
--- a/sysdeps/unix/sysv/linux/wait.c
+++ b/sysdeps/unix/sysv/linux/wait.c
@@ -1 +1,47 @@
-#include <sysdeps/unix/bsd/bsd4.4/wait.c>
+/* Copyright (C) 1991, 1995, 1996, 1997, 2002 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 <sys/wait.h>
+#include <errno.h>
+#include <sys/resource.h>
+#include <stddef.h>
+#include <sysdep-cancel.h>
+#include <nptl/pthreadP.h>
+#include <tls.h>
+
+/* Wait for a child to die. When one does, put its status in *STAT_LOC
+ and return its process ID. For errors, return (pid_t) -1. */
+__pid_t
+__libc_wait (__WAIT_STATUS_DEFN stat_loc)
+{
+ if (SINGLE_THREAD_P)
+ return INLINE_SYSCALL (wait4, 4, WAIT_ANY, stat_loc, 0,
+ (struct rusage *) NULL);
+
+ int oldtype = LIBC_CANCEL_ASYNC ();
+
+ int result = INLINE_SYSCALL (wait4, 4, WAIT_ANY, stat_loc, 0,
+ (struct rusage *) NULL);
+
+ LIBC_CANCEL_RESET (oldtype);
+
+ return result;
+}
+
+weak_alias (__libc_wait, __wait)
+weak_alias (__libc_wait, wait)
diff --git a/sysdeps/unix/sysv/linux/waitpid.c b/sysdeps/unix/sysv/linux/waitpid.c
index 43a63f6..275fb82 100644
--- a/sysdeps/unix/sysv/linux/waitpid.c
+++ b/sysdeps/unix/sysv/linux/waitpid.c
@@ -16,14 +16,26 @@
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA. */
-#include <sysdep.h>
+#include <errno.h>
+#include <sysdep-cancel.h>
#include <stdlib.h>
#include <sys/wait.h>
+#include <nptl/pthreadP.h>
+#include <tls.h>
__pid_t
__libc_waitpid (__pid_t pid, int *stat_loc, int options)
{
- return __wait4 (pid, stat_loc, options, NULL);
+ if (SINGLE_THREAD_P)
+ return INLINE_SYSCALL (wait4, 4, pid, stat_loc, options, NULL);
+
+ int oldtype = LIBC_CANCEL_ASYNC ();
+
+ int result = INLINE_SYSCALL (wait4, 4, pid, stat_loc, options, NULL);
+
+ LIBC_CANCEL_RESET (oldtype);
+
+ return result;
}
weak_alias (__libc_waitpid, __waitpid)
libc_hidden_weak (__waitpid)
diff --git a/sysdeps/unix/sysv/linux/writev.c b/sysdeps/unix/sysv/linux/writev.c
index 76cc920..c8ecf50 100644
--- a/sysdeps/unix/sysv/linux/writev.c
+++ b/sysdeps/unix/sysv/linux/writev.c
@@ -22,7 +22,7 @@
#include <sys/param.h>
#include <sys/uio.h>
-#include <sysdep.h>
+#include <sysdep-cancel.h>
#include <sys/syscall.h>
#include <bp-checks.h>
@@ -39,11 +39,8 @@ static ssize_t __atomic_writev_replacement (int, const struct iovec *,
/* We should deal with kernel which have a smaller UIO_FASTIOV as well
as a very big count. */
-ssize_t
-__libc_writev (fd, vector, count)
- int fd;
- const struct iovec *vector;
- int count;
+static ssize_t
+do_writev (int fd, const struct iovec *vector, int count)
{
ssize_t bytes_written;
@@ -54,6 +51,24 @@ __libc_writev (fd, vector, count)
return __atomic_writev_replacement (fd, vector, count);
}
+
+ssize_t
+__libc_writev (fd, vector, count)
+ int fd;
+ const struct iovec *vector;
+ int count;
+{
+ if (SINGLE_THREAD_P)
+ return do_writev (fd, vector, count);
+
+ int oldtype = LIBC_CANCEL_ASYNC ();
+
+ ssize_t result = do_writev (fd, vector, count);
+
+ LIBC_CANCEL_RESET (oldtype);
+
+ return result;
+}
strong_alias (__libc_writev, __writev)
weak_alias (__libc_writev, writev)