summaryrefslogtreecommitdiff
path: root/sysdeps/unix
diff options
context:
space:
mode:
Diffstat (limited to 'sysdeps/unix')
-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
28 files changed, 527 insertions, 105 deletions
diff --git a/sysdeps/unix/sysv/linux/accept.S b/sysdeps/unix/sysv/linux/accept.S
index 431dec0324..75d57368bc 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 2de35180fc..7d1fa12b34 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 12bb291381..4ff5ee35b8 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 d0607921ed..866a67462d 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 fa83f1057c..9ee340d476 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 fdc13ff0fa..7d8a8e7859 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 7beba6b198..c2031be71f 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 0000000000..5fb5363e1e
--- /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 296893d4ca..c136c21dbd 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 31abf7e886..a506c17e95 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 d27f9afad9..61ff7f5dd4 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 13bbc76b3e..af4ac362b8 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 dc81cd6b31..91f48951b0 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 eeba46a09d..e6f9fb0c4e 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 cb9eb91b8c..331844abc1 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 93a3110d0a..ccbb0a75da 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 98be36be5b..d44bc39f92 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 83d5938223..259748f44c 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 c01d9b68e7..a220894cc6 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 8717b2bac1..a65e44fb61 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 443c855d6c..71c2baeda5 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 c374287ea6..5ace26102c 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 78e58524d5..f99c64056f 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 d1e7a8da28..102b924904 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 a7234b07f1..4868565ed1 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 79d54580fd..f01d75cc38 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 43a63f6ce5..275fb826b4 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 76cc920dae..c8ecf5060f 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)