diff options
author | Ulrich Drepper <drepper@redhat.com> | 2002-12-15 10:26:23 +0000 |
---|---|---|
committer | Ulrich Drepper <drepper@redhat.com> | 2002-12-15 10:26:23 +0000 |
commit | 6ee8d3345646ab0bea91891362a2bbf15503edec (patch) | |
tree | 718ea6deebec61e44b09eb25817ee5c14da35f57 /sysdeps/unix/sysv/linux | |
parent | 2fb6444dbb9672aea7766b3790a3cb70a73473d3 (diff) | |
download | glibc-6ee8d3345646ab0bea91891362a2bbf15503edec.tar glibc-6ee8d3345646ab0bea91891362a2bbf15503edec.tar.gz glibc-6ee8d3345646ab0bea91891362a2bbf15503edec.tar.bz2 glibc-6ee8d3345646ab0bea91891362a2bbf15503edec.zip |
Update.
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.
Diffstat (limited to 'sysdeps/unix/sysv/linux')
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) |