summaryrefslogtreecommitdiffstats
path: root/lib/libthr/thread/thr_syscalls.c
diff options
context:
space:
mode:
authorkib <kib@FreeBSD.org>2015-01-03 18:38:46 +0000
committerkib <kib@FreeBSD.org>2015-01-03 18:38:46 +0000
commit8d1dfb4106d37750d526e6b8edca5945f8b0a4d5 (patch)
treee381919bf3f754392eb9a47b256135a1dbb2b2b1 /lib/libthr/thread/thr_syscalls.c
parent7ac15f4b4cebad0f4e9d2094b6ea3fefa77ae568 (diff)
downloadFreeBSD-src-8d1dfb4106d37750d526e6b8edca5945f8b0a4d5.zip
FreeBSD-src-8d1dfb4106d37750d526e6b8edca5945f8b0a4d5.tar.gz
Fix known issues which blow up the process after dlopen("libthr.so")
(or loading a dso linked to libthr.so into process which was not linked against threading library). - Remove libthr interposers of the libc functions, including __error(). Instead, functions calls are indirected through the interposing table, similar to how pthread stubs in libc are already done. Libc by default points either to syscall trampolines or to existing libc implementations. On libthr load, libthr rewrites the pointers to the cancellable implementations already in libthr. The interposition table is separate from pthreads stubs indirection table to not pull pthreads stubs into static binaries. - Postpone the malloc(3) internal mutexes initialization until libthr is loaded. This avoids recursion between calloc(3) and static pthread_mutex_t initialization. - Reinstall signal handlers with wrapper on libthr load. The _rtld_is_dlopened(3) is used to avoid useless calls to sigaction(2) when libthr is statically referenced from the main binary. In the process, fix openat(2), swapcontext(2) and setcontext(2) interposing. The libc symbols were exported at different versions than libthr interposers. Export both libc and libthr versions from libc now, with default set to the higher version from libthr. Remove unused and disconnected swapcontext(3) userspace implementation from libc/gen. No objections from: deischen Tested by: pho, antoine (exp-run) (previous versions) Sponsored by: The FreeBSD Foundation MFC after: 1 week
Diffstat (limited to 'lib/libthr/thread/thr_syscalls.c')
-rw-r--r--lib/libthr/thread/thr_syscalls.c492
1 files changed, 226 insertions, 266 deletions
diff --git a/lib/libthr/thread/thr_syscalls.c b/lib/libthr/thread/thr_syscalls.c
index 7a08302..60427d8 100644
--- a/lib/libthr/thread/thr_syscalls.c
+++ b/lib/libthr/thread/thr_syscalls.c
@@ -1,9 +1,13 @@
/*
+ * Copyright (c) 2014 The FreeBSD Foundation.
* Copyright (C) 2005 David Xu <davidxu@freebsd.org>.
* Copyright (c) 2003 Daniel Eischen <deischen@freebsd.org>.
* Copyright (C) 2000 Jason Evans <jasone@freebsd.org>.
* All rights reserved.
*
+ * Portions of this software were developed by Konstantin Belousov
+ * under sponsorship from the FreeBSD Foundation.
+ *
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
@@ -27,8 +31,6 @@
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * $FreeBSD$
*/
/*
@@ -61,6 +63,9 @@
*
*/
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
#include "namespace.h"
#include <sys/types.h>
#include <sys/mman.h>
@@ -87,85 +92,19 @@
#include <pthread.h>
#include "un-namespace.h"
+#include "libc_private.h"
#include "thr_private.h"
-extern int __creat(const char *, mode_t);
-extern int __pselect(int, fd_set *, fd_set *, fd_set *,
- const struct timespec *, const sigset_t *);
-extern unsigned __sleep(unsigned int);
-extern int __system(const char *);
-extern int __tcdrain(int);
-extern int __usleep(useconds_t);
-extern pid_t __wait(int *);
-extern pid_t __waitpid(pid_t, int *, int);
-extern int __sys_aio_suspend(const struct aiocb * const[], int,
- const struct timespec *);
-extern int __sys_accept(int, struct sockaddr *, socklen_t *);
-extern int __sys_accept4(int, struct sockaddr *, socklen_t *, int);
-extern int __sys_connect(int, const struct sockaddr *, socklen_t);
-extern int __sys_fsync(int);
-extern int __sys_msync(void *, size_t, int);
-extern int __sys_pselect(int, fd_set *, fd_set *, fd_set *,
- const struct timespec *, const sigset_t *);
-extern int __sys_poll(struct pollfd *, unsigned, int);
-extern ssize_t __sys_recv(int, void *, size_t, int);
-extern ssize_t __sys_recvfrom(int, void *, size_t, int, struct sockaddr *, socklen_t *);
-extern ssize_t __sys_recvmsg(int, struct msghdr *, int);
-extern int __sys_select(int, fd_set *, fd_set *, fd_set *, struct timeval *);
-extern int __sys_sendfile(int, int, off_t, size_t, struct sf_hdtr *,
- off_t *, int);
-extern ssize_t __sys_sendmsg(int, const struct msghdr *, int);
-extern ssize_t __sys_sendto(int, const void *,size_t, int, const struct sockaddr *, socklen_t);
-extern ssize_t __sys_readv(int, const struct iovec *, int);
-extern pid_t __sys_wait4(pid_t, int *, int, struct rusage *);
-extern ssize_t __sys_writev(int, const struct iovec *, int);
-
-int ___creat(const char *, mode_t);
-int ___pselect(int, fd_set *, fd_set *, fd_set *,
- const struct timespec *, const sigset_t *);
-unsigned ___sleep(unsigned);
-int ___system(const char *);
-int ___tcdrain(int);
-int ___usleep(useconds_t useconds);
-pid_t ___wait(int *);
-pid_t ___waitpid(pid_t, int *, int);
-int __accept(int, struct sockaddr *, socklen_t *);
-int __accept4(int, struct sockaddr *, socklen_t *, int);
-int __aio_suspend(const struct aiocb * const iocbs[], int,
- const struct timespec *);
-int __close(int);
-int __connect(int, const struct sockaddr *, socklen_t);
-int __fcntl(int, int,...);
#ifdef SYSCALL_COMPAT
-extern int __fcntl_compat(int, int,...);
+extern int __fcntl_compat(int, int, ...);
#endif
-int __fsync(int);
-int __msync(void *, size_t, int);
-int __nanosleep(const struct timespec *, struct timespec *);
-int __open(const char *, int,...);
-int __openat(int, const char *, int,...);
-int __poll(struct pollfd *, unsigned int, int);
-ssize_t __read(int, void *buf, size_t);
-ssize_t __readv(int, const struct iovec *, int);
-ssize_t __recvfrom(int, void *, size_t, int f, struct sockaddr *, socklen_t *);
-ssize_t __recvmsg(int, struct msghdr *, int);
-int __select(int, fd_set *, fd_set *, fd_set *, struct timeval *);
-ssize_t __sendmsg(int, const struct msghdr *, int);
-ssize_t __sendto(int, const void *, size_t, int,
- const struct sockaddr *, socklen_t);
-pid_t __wait3(int *, int, struct rusage *);
-pid_t __wait4(pid_t, int *, int, struct rusage *);
-ssize_t __write(int, const void *, size_t);
-ssize_t __writev(int, const struct iovec *, int);
-
-__weak_reference(__accept, accept);
/*
* Cancellation behavior:
* If thread is canceled, no socket is created.
*/
-int
-__accept(int s, struct sockaddr *addr, socklen_t *addrlen)
+static int
+__thr_accept(int s, struct sockaddr *addr, socklen_t *addrlen)
{
struct pthread *curthread;
int ret;
@@ -178,14 +117,12 @@ __accept(int s, struct sockaddr *addr, socklen_t *addrlen)
return (ret);
}
-__weak_reference(__accept4, accept4);
-
/*
* Cancellation behavior:
* If thread is canceled, no socket is created.
*/
-int
-__accept4(int s, struct sockaddr *addr, socklen_t *addrlen, int flags)
+static int
+__thr_accept4(int s, struct sockaddr *addr, socklen_t *addrlen, int flags)
{
struct pthread *curthread;
int ret;
@@ -198,15 +135,14 @@ __accept4(int s, struct sockaddr *addr, socklen_t *addrlen, int flags)
return (ret);
}
-__weak_reference(__aio_suspend, aio_suspend);
-
-int
-__aio_suspend(const struct aiocb * const iocbs[], int niocb, const struct
+static int
+__thr_aio_suspend(const struct aiocb * const iocbs[], int niocb, const struct
timespec *timeout)
{
- struct pthread *curthread = _get_curthread();
+ struct pthread *curthread;
int ret;
+ curthread = _get_curthread();
_thr_cancel_enter(curthread);
ret = __sys_aio_suspend(iocbs, niocb, timeout);
_thr_cancel_leave(curthread, 1);
@@ -214,8 +150,6 @@ __aio_suspend(const struct aiocb * const iocbs[], int niocb, const struct
return (ret);
}
-__weak_reference(__close, close);
-
/*
* Cancellation behavior:
* According to manual of close(), the file descriptor is always deleted.
@@ -223,12 +157,13 @@ __weak_reference(__close, close);
* descriptor is always deleted despite whether the thread is canceled
* or not.
*/
-int
-__close(int fd)
+static int
+__thr_close(int fd)
{
- struct pthread *curthread = _get_curthread();
- int ret;
+ struct pthread *curthread;
+ int ret;
+ curthread = _get_curthread();
_thr_cancel_enter2(curthread, 0);
ret = __sys_close(fd);
_thr_cancel_leave(curthread, 1);
@@ -236,18 +171,17 @@ __close(int fd)
return (ret);
}
-__weak_reference(__connect, connect);
-
/*
* Cancellation behavior:
* If the thread is canceled, connection is not made.
*/
-int
-__connect(int fd, const struct sockaddr *name, socklen_t namelen)
+static int
+__thr_connect(int fd, const struct sockaddr *name, socklen_t namelen)
{
- struct pthread *curthread = _get_curthread();
+ struct pthread *curthread;
int ret;
+ curthread = _get_curthread();
_thr_cancel_enter(curthread);
ret = __sys_connect(fd, name, namelen);
_thr_cancel_leave(curthread, ret == -1);
@@ -255,27 +189,25 @@ __connect(int fd, const struct sockaddr *name, socklen_t namelen)
return (ret);
}
-__weak_reference(___creat, creat);
/*
* Cancellation behavior:
* If thread is canceled, file is not created.
*/
-int
-___creat(const char *path, mode_t mode)
+static int
+__thr_creat(const char *path, mode_t mode)
{
- struct pthread *curthread = _get_curthread();
+ struct pthread *curthread;
int ret;
+ curthread = _get_curthread();
_thr_cancel_enter(curthread);
- ret = __creat(path, mode);
+ ret = __libc_creat(path, mode);
_thr_cancel_leave(curthread, ret == -1);
- return ret;
+ return (ret);
}
-__weak_reference(__fcntl, fcntl);
-
/*
* Cancellation behavior:
* According to specification, only F_SETLKW is a cancellation point.
@@ -283,13 +215,14 @@ __weak_reference(__fcntl, fcntl);
* is failure, this means the function does not generate side effect
* if it is canceled.
*/
-int
-__fcntl(int fd, int cmd,...)
+static int
+__thr_fcntl(int fd, int cmd, ...)
{
- struct pthread *curthread = _get_curthread();
- int ret;
+ struct pthread *curthread;
+ int ret;
va_list ap;
+ curthread = _get_curthread();
va_start(ap, cmd);
if (cmd == F_OSETLKW || cmd == F_SETLKW) {
_thr_cancel_enter(curthread);
@@ -311,18 +244,17 @@ __fcntl(int fd, int cmd,...)
return (ret);
}
-__weak_reference(__fsync, fsync);
-
/*
* Cancellation behavior:
* Thread may be canceled after system call.
*/
-int
-__fsync(int fd)
+static int
+__thr_fsync(int fd)
{
- struct pthread *curthread = _get_curthread();
- int ret;
+ struct pthread *curthread;
+ int ret;
+ curthread = _get_curthread();
_thr_cancel_enter2(curthread, 0);
ret = __sys_fsync(fd);
_thr_cancel_leave(curthread, 1);
@@ -330,34 +262,32 @@ __fsync(int fd)
return (ret);
}
-__weak_reference(__msync, msync);
-
/*
* Cancellation behavior:
* Thread may be canceled after system call.
*/
-int
-__msync(void *addr, size_t len, int flags)
+static int
+__thr_msync(void *addr, size_t len, int flags)
{
- struct pthread *curthread = _get_curthread();
- int ret;
+ struct pthread *curthread;
+ int ret;
+ curthread = _get_curthread();
_thr_cancel_enter2(curthread, 0);
ret = __sys_msync(addr, len, flags);
_thr_cancel_leave(curthread, 1);
- return ret;
+ return (ret);
}
-__weak_reference(__nanosleep, nanosleep);
-
-int
-__nanosleep(const struct timespec *time_to_sleep,
+static int
+__thr_nanosleep(const struct timespec *time_to_sleep,
struct timespec *time_remaining)
{
- struct pthread *curthread = _get_curthread();
- int ret;
+ struct pthread *curthread;
+ int ret;
+ curthread = _get_curthread();
_thr_cancel_enter(curthread);
ret = __sys_nanosleep(time_to_sleep, time_remaining);
_thr_cancel_leave(curthread, 1);
@@ -365,99 +295,97 @@ __nanosleep(const struct timespec *time_to_sleep,
return (ret);
}
-__weak_reference(__open, open);
-
/*
* Cancellation behavior:
* If the thread is canceled, file is not opened.
*/
-int
-__open(const char *path, int flags,...)
+static int
+__thr_open(const char *path, int flags,...)
{
- struct pthread *curthread = _get_curthread();
- int ret;
- int mode = 0;
+ struct pthread *curthread;
+ int mode, ret;
va_list ap;
/* Check if the file is being created: */
- if (flags & O_CREAT) {
+ if ((flags & O_CREAT) != 0) {
/* Get the creation mode: */
va_start(ap, flags);
mode = va_arg(ap, int);
va_end(ap);
+ } else {
+ mode = 0;
}
+ curthread = _get_curthread();
_thr_cancel_enter(curthread);
ret = __sys_open(path, flags, mode);
_thr_cancel_leave(curthread, ret == -1);
- return ret;
+ return (ret);
}
-__weak_reference(__openat, openat);
-
/*
* Cancellation behavior:
* If the thread is canceled, file is not opened.
*/
-int
-__openat(int fd, const char *path, int flags, ...)
+static int
+__thr_openat(int fd, const char *path, int flags, ...)
{
- struct pthread *curthread = _get_curthread();
- int ret;
- int mode = 0;
+ struct pthread *curthread;
+ int mode, ret;
va_list ap;
/* Check if the file is being created: */
- if (flags & O_CREAT) {
+ if ((flags & O_CREAT) != 0) {
/* Get the creation mode: */
va_start(ap, flags);
mode = va_arg(ap, int);
va_end(ap);
+ } else {
+ mode = 0;
}
+ curthread = _get_curthread();
_thr_cancel_enter(curthread);
ret = __sys_openat(fd, path, flags, mode);
_thr_cancel_leave(curthread, ret == -1);
- return ret;
+ return (ret);
}
-__weak_reference(__poll, poll);
-
/*
* Cancellation behavior:
* Thread may be canceled at start, but if the system call returns something,
* the thread is not canceled.
*/
-int
-__poll(struct pollfd *fds, unsigned int nfds, int timeout)
+static int
+__thr_poll(struct pollfd *fds, unsigned int nfds, int timeout)
{
- struct pthread *curthread = _get_curthread();
+ struct pthread *curthread;
int ret;
+ curthread = _get_curthread();
_thr_cancel_enter(curthread);
ret = __sys_poll(fds, nfds, timeout);
_thr_cancel_leave(curthread, ret == -1);
- return ret;
+ return (ret);
}
-__weak_reference(___pselect, pselect);
-
/*
* Cancellation behavior:
* Thread may be canceled at start, but if the system call returns something,
* the thread is not canceled.
*/
-int
-___pselect(int count, fd_set *rfds, fd_set *wfds, fd_set *efds,
+static int
+__thr_pselect(int count, fd_set *rfds, fd_set *wfds, fd_set *efds,
const struct timespec *timo, const sigset_t *mask)
{
- struct pthread *curthread = _get_curthread();
+ struct pthread *curthread;
int ret;
+ curthread = _get_curthread();
_thr_cancel_enter(curthread);
ret = __sys_pselect(count, rfds, wfds, efds, timo, mask);
_thr_cancel_leave(curthread, ret == -1);
@@ -465,321 +393,353 @@ ___pselect(int count, fd_set *rfds, fd_set *wfds, fd_set *efds,
return (ret);
}
-__weak_reference(__read, read);
-
/*
* Cancellation behavior:
* Thread may be canceled at start, but if the system call got some data,
* the thread is not canceled.
*/
-ssize_t
-__read(int fd, void *buf, size_t nbytes)
+static ssize_t
+__thr_read(int fd, void *buf, size_t nbytes)
{
- struct pthread *curthread = _get_curthread();
+ struct pthread *curthread;
ssize_t ret;
+ curthread = _get_curthread();
_thr_cancel_enter(curthread);
ret = __sys_read(fd, buf, nbytes);
_thr_cancel_leave(curthread, ret == -1);
- return ret;
+ return (ret);
}
-__weak_reference(__readv, readv);
-
/*
* Cancellation behavior:
* Thread may be canceled at start, but if the system call got some data,
* the thread is not canceled.
*/
-ssize_t
-__readv(int fd, const struct iovec *iov, int iovcnt)
+static ssize_t
+__thr_readv(int fd, const struct iovec *iov, int iovcnt)
{
- struct pthread *curthread = _get_curthread();
+ struct pthread *curthread;
ssize_t ret;
+ curthread = _get_curthread();
_thr_cancel_enter(curthread);
ret = __sys_readv(fd, iov, iovcnt);
_thr_cancel_leave(curthread, ret == -1);
- return ret;
+ return (ret);
}
-__weak_reference(__recvfrom, recvfrom);
-
/*
* Cancellation behavior:
* Thread may be canceled at start, but if the system call got some data,
* the thread is not canceled.
*/
-ssize_t
-__recvfrom(int s, void *b, size_t l, int f, struct sockaddr *from,
+static ssize_t
+__thr_recvfrom(int s, void *b, size_t l, int f, struct sockaddr *from,
socklen_t *fl)
{
- struct pthread *curthread = _get_curthread();
+ struct pthread *curthread;
ssize_t ret;
+ curthread = _get_curthread();
_thr_cancel_enter(curthread);
ret = __sys_recvfrom(s, b, l, f, from, fl);
_thr_cancel_leave(curthread, ret == -1);
return (ret);
}
-__weak_reference(__recvmsg, recvmsg);
-
/*
* Cancellation behavior:
* Thread may be canceled at start, but if the system call got some data,
* the thread is not canceled.
*/
-ssize_t
-__recvmsg(int s, struct msghdr *m, int f)
+static ssize_t
+__thr_recvmsg(int s, struct msghdr *m, int f)
{
- struct pthread *curthread = _get_curthread();
+ struct pthread *curthread;
ssize_t ret;
+ curthread = _get_curthread();
_thr_cancel_enter(curthread);
ret = __sys_recvmsg(s, m, f);
_thr_cancel_leave(curthread, ret == -1);
return (ret);
}
-__weak_reference(__select, select);
-
/*
* Cancellation behavior:
* Thread may be canceled at start, but if the system call returns something,
* the thread is not canceled.
*/
-int
-__select(int numfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
+static int
+__thr_select(int numfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
struct timeval *timeout)
{
- struct pthread *curthread = _get_curthread();
+ struct pthread *curthread;
int ret;
+ curthread = _get_curthread();
_thr_cancel_enter(curthread);
ret = __sys_select(numfds, readfds, writefds, exceptfds, timeout);
_thr_cancel_leave(curthread, ret == -1);
- return ret;
+ return (ret);
}
-__weak_reference(__sendmsg, sendmsg);
-
/*
* Cancellation behavior:
* Thread may be canceled at start, but if the system call sent
* data, the thread is not canceled.
*/
-ssize_t
-__sendmsg(int s, const struct msghdr *m, int f)
+static ssize_t
+__thr_sendmsg(int s, const struct msghdr *m, int f)
{
- struct pthread *curthread = _get_curthread();
+ struct pthread *curthread;
ssize_t ret;
+ curthread = _get_curthread();
_thr_cancel_enter(curthread);
ret = __sys_sendmsg(s, m, f);
_thr_cancel_leave(curthread, ret <= 0);
return (ret);
}
-__weak_reference(__sendto, sendto);
-
/*
* Cancellation behavior:
* Thread may be canceled at start, but if the system call sent some
* data, the thread is not canceled.
*/
-ssize_t
-__sendto(int s, const void *m, size_t l, int f, const struct sockaddr *t,
+static ssize_t
+__thr_sendto(int s, const void *m, size_t l, int f, const struct sockaddr *t,
socklen_t tl)
{
- struct pthread *curthread = _get_curthread();
+ struct pthread *curthread;
ssize_t ret;
+ curthread = _get_curthread();
_thr_cancel_enter(curthread);
ret = __sys_sendto(s, m, l, f, t, tl);
_thr_cancel_leave(curthread, ret <= 0);
return (ret);
}
-__weak_reference(___sleep, sleep);
-
-unsigned int
-___sleep(unsigned int seconds)
+static unsigned int
+__thr_sleep(unsigned int seconds)
{
- struct pthread *curthread = _get_curthread();
- unsigned int ret;
+ struct pthread *curthread;
+ unsigned int ret;
+ curthread = _get_curthread();
_thr_cancel_enter(curthread);
- ret = __sleep(seconds);
+ ret = __libc_sleep(seconds);
_thr_cancel_leave(curthread, 1);
-
return (ret);
}
-__weak_reference(___system, system);
-
-int
-___system(const char *string)
+static int
+__thr_system(const char *string)
{
- struct pthread *curthread = _get_curthread();
- int ret;
+ struct pthread *curthread;
+ int ret;
+ curthread = _get_curthread();
_thr_cancel_enter(curthread);
- ret = __system(string);
+ ret = __libc_system(string);
_thr_cancel_leave(curthread, 1);
-
- return ret;
+ return (ret);
}
-__weak_reference(___tcdrain, tcdrain);
-
/*
* Cancellation behavior:
* If thread is canceled, the system call is not completed,
* this means not all bytes were drained.
*/
-int
-___tcdrain(int fd)
+static int
+__thr_tcdrain(int fd)
{
- struct pthread *curthread = _get_curthread();
- int ret;
+ struct pthread *curthread;
+ int ret;
+ curthread = _get_curthread();
_thr_cancel_enter(curthread);
- ret = __tcdrain(fd);
+ ret = __libc_tcdrain(fd);
_thr_cancel_leave(curthread, ret == -1);
return (ret);
}
-__weak_reference(___usleep, usleep);
-
-int
-___usleep(useconds_t useconds)
+static int
+__thr_usleep(useconds_t useconds)
{
- struct pthread *curthread = _get_curthread();
- int ret;
+ struct pthread *curthread;
+ int ret;
+ curthread = _get_curthread();
_thr_cancel_enter(curthread);
- ret = __usleep(useconds);
+ ret = __libc_usleep(useconds);
_thr_cancel_leave(curthread, 1);
-
return (ret);
}
-__weak_reference(___wait, wait);
-
/*
* Cancellation behavior:
* Thread may be canceled at start, but if the system call returns
* a child pid, the thread is not canceled.
*/
-pid_t
-___wait(int *istat)
+static pid_t
+__thr_wait(int *istat)
{
- struct pthread *curthread = _get_curthread();
- pid_t ret;
+ struct pthread *curthread;
+ pid_t ret;
+ curthread = _get_curthread();
_thr_cancel_enter(curthread);
- ret = __wait(istat);
+ ret = __libc_wait(istat);
_thr_cancel_leave(curthread, ret <= 0);
-
- return ret;
+ return (ret);
}
-__weak_reference(__wait3, wait3);
-
/*
* Cancellation behavior:
* Thread may be canceled at start, but if the system call returns
* a child pid, the thread is not canceled.
*/
-pid_t
-__wait3(int *status, int options, struct rusage *rusage)
+static pid_t
+__thr_wait3(int *status, int options, struct rusage *rusage)
{
- struct pthread *curthread = _get_curthread();
+ struct pthread *curthread;
pid_t ret;
+ curthread = _get_curthread();
_thr_cancel_enter(curthread);
- ret = _wait4(WAIT_ANY, status, options, rusage);
+ ret = __libc_wait3(status, options, rusage);
_thr_cancel_leave(curthread, ret <= 0);
-
return (ret);
}
-__weak_reference(__wait4, wait4);
-
/*
* Cancellation behavior:
* Thread may be canceled at start, but if the system call returns
* a child pid, the thread is not canceled.
*/
-pid_t
-__wait4(pid_t pid, int *status, int options, struct rusage *rusage)
+static pid_t
+__thr_wait4(pid_t pid, int *status, int options, struct rusage *rusage)
{
- struct pthread *curthread = _get_curthread();
+ struct pthread *curthread;
pid_t ret;
+ curthread = _get_curthread();
_thr_cancel_enter(curthread);
ret = __sys_wait4(pid, status, options, rusage);
_thr_cancel_leave(curthread, ret <= 0);
-
- return ret;
+ return (ret);
}
-__weak_reference(___waitpid, waitpid);
-
/*
* Cancellation behavior:
* Thread may be canceled at start, but if the system call returns
* a child pid, the thread is not canceled.
*/
-pid_t
-___waitpid(pid_t wpid, int *status, int options)
+static pid_t
+__thr_waitpid(pid_t wpid, int *status, int options)
{
- struct pthread *curthread = _get_curthread();
- pid_t ret;
+ struct pthread *curthread;
+ pid_t ret;
+ curthread = _get_curthread();
_thr_cancel_enter(curthread);
- ret = __waitpid(wpid, status, options);
+ ret = __libc_waitpid(wpid, status, options);
_thr_cancel_leave(curthread, ret <= 0);
-
- return ret;
+ return (ret);
}
-__weak_reference(__write, write);
-
/*
* Cancellation behavior:
* Thread may be canceled at start, but if the thread wrote some data,
* it is not canceled.
*/
-ssize_t
-__write(int fd, const void *buf, size_t nbytes)
+static ssize_t
+__thr_write(int fd, const void *buf, size_t nbytes)
{
- struct pthread *curthread = _get_curthread();
+ struct pthread *curthread;
ssize_t ret;
+ curthread = _get_curthread();
_thr_cancel_enter(curthread);
ret = __sys_write(fd, buf, nbytes);
_thr_cancel_leave(curthread, (ret <= 0));
- return ret;
+ return (ret);
}
-__weak_reference(__writev, writev);
-
/*
* Cancellation behavior:
* Thread may be canceled at start, but if the thread wrote some data,
* it is not canceled.
*/
-ssize_t
-__writev(int fd, const struct iovec *iov, int iovcnt)
+static ssize_t
+__thr_writev(int fd, const struct iovec *iov, int iovcnt)
{
- struct pthread *curthread = _get_curthread();
+ struct pthread *curthread;
ssize_t ret;
+ curthread = _get_curthread();
_thr_cancel_enter(curthread);
ret = __sys_writev(fd, iov, iovcnt);
_thr_cancel_leave(curthread, (ret <= 0));
- return ret;
+ return (ret);
+}
+
+void
+__thr_interpose_libc(void)
+{
+
+ __error_selector = __error_threaded;
+#define SLOT(name) \
+ *(__libc_interposing_slot(INTERPOS_##name)) = \
+ (interpos_func_t)__thr_##name;
+ SLOT(accept);
+ SLOT(accept4);
+ SLOT(aio_suspend);
+ SLOT(close);
+ SLOT(connect);
+ SLOT(creat);
+ SLOT(fcntl);
+ SLOT(fsync);
+ SLOT(fork);
+ SLOT(msync);
+ SLOT(nanosleep);
+ SLOT(open);
+ SLOT(openat);
+ SLOT(poll);
+ SLOT(pselect);
+ SLOT(raise);
+ SLOT(read);
+ SLOT(readv);
+ SLOT(recvfrom);
+ SLOT(recvmsg);
+ SLOT(select);
+ SLOT(sendmsg);
+ SLOT(sendto);
+ SLOT(setcontext);
+ SLOT(sigaction);
+ SLOT(sigprocmask);
+ SLOT(sigsuspend);
+ SLOT(sigwait);
+ SLOT(sigtimedwait);
+ SLOT(sigwaitinfo);
+ SLOT(swapcontext);
+ SLOT(system);
+ SLOT(sleep);
+ SLOT(tcdrain);
+ SLOT(usleep);
+ SLOT(pause);
+ SLOT(wait);
+ SLOT(wait3);
+ SLOT(wait4);
+ SLOT(waitpid);
+ SLOT(write);
+ SLOT(writev);
+#undef SLOT
+ *(__libc_interposing_slot(
+ INTERPOS__pthread_mutex_init_calloc_cb)) =
+ (interpos_func_t)_pthread_mutex_init_calloc_cb;
}
OpenPOWER on IntegriCloud