Home | History | Annotate | Line # | Download | only in libpthread
pthread_cancelstub.c revision 1.37.2.1
      1 /*	$NetBSD: pthread_cancelstub.c,v 1.37.2.1 2013/06/23 06:21:08 tls Exp $	*/
      2 
      3 /*-
      4  * Copyright (c) 2002, 2007 The NetBSD Foundation, Inc.
      5  * All rights reserved.
      6  *
      7  * This code is derived from software contributed to The NetBSD Foundation
      8  * by Nathan J. Williams and Andrew Doran.
      9  *
     10  * Redistribution and use in source and binary forms, with or without
     11  * modification, are permitted provided that the following conditions
     12  * are met:
     13  * 1. Redistributions of source code must retain the above copyright
     14  *    notice, this list of conditions and the following disclaimer.
     15  * 2. Redistributions in binary form must reproduce the above copyright
     16  *    notice, this list of conditions and the following disclaimer in the
     17  *    documentation and/or other materials provided with the distribution.
     18  *
     19  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
     20  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
     21  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     22  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
     23  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     24  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     25  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     26  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     27  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     28  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     29  * POSSIBILITY OF SUCH DAMAGE.
     30  */
     31 
     32 /* Disable namespace mangling, Fortification is useless here anyway. */
     33 #undef _FORTIFY_SOURCE
     34 
     35 #include <sys/cdefs.h>
     36 __RCSID("$NetBSD: pthread_cancelstub.c,v 1.37.2.1 2013/06/23 06:21:08 tls Exp $");
     37 
     38 #ifndef lint
     39 
     40 
     41 /*
     42  * This is necessary because the names are always weak (they are not
     43  * POSIX functions).
     44  */
     45 #define	fsync_range	_fsync_range
     46 #define	pollts		_pollts
     47 
     48 /*
     49  * XXX this is necessary to get the prototypes for the __sigsuspend14
     50  * XXX and __msync13 internal names, instead of the application-visible
     51  * XXX sigsuspend and msync names. It's kind of gross, but we're pretty
     52  * XXX intimate with libc already.
     53  */
     54 #define __LIBC12_SOURCE__
     55 
     56 #include <sys/msg.h>
     57 #include <sys/types.h>
     58 #include <sys/uio.h>
     59 #include <sys/wait.h>
     60 #include <aio.h>
     61 #include <errno.h>
     62 #include <fcntl.h>
     63 #include <mqueue.h>
     64 #include <poll.h>
     65 #include <stdarg.h>
     66 #include <unistd.h>
     67 
     68 #include <signal.h>
     69 #include <sys/mman.h>
     70 #include <sys/select.h>
     71 #include <sys/socket.h>
     72 #include <sys/event.h>
     73 
     74 #include <compat/sys/mman.h>
     75 #include <compat/sys/poll.h>
     76 #include <compat/sys/select.h>
     77 #include <compat/sys/event.h>
     78 #include <compat/sys/wait.h>
     79 #include <compat/include/mqueue.h>
     80 #include <compat/include/signal.h>
     81 
     82 #include "pthread.h"
     83 #include "pthread_int.h"
     84 #include "reentrant.h"
     85 
     86 int	pthread__cancel_stub_binder;
     87 
     88 int	_sys_accept(int, struct sockaddr *, socklen_t *);
     89 int	_sys___aio_suspend50(const struct aiocb * const [], int,
     90 	    const struct timespec *);
     91 int	__aio_suspend50(const struct aiocb * const [], int,
     92 	    const struct timespec *);
     93 int	_sys_close(int);
     94 int	_sys_connect(int, const struct sockaddr *, socklen_t);
     95 int	_sys_fcntl(int, int, ...);
     96 int	_sys_fdatasync(int);
     97 int	_sys_fsync(int);
     98 int	_sys_fsync_range(int, int, off_t, off_t);
     99 int	_sys___kevent50(int, const struct kevent *, size_t, struct kevent *,
    100 	    size_t, const struct timespec *);
    101 int	_sys_mq_send(mqd_t, const char *, size_t, unsigned);
    102 ssize_t	_sys_mq_receive(mqd_t, char *, size_t, unsigned *);
    103 int	_sys___mq_timedsend50(mqd_t, const char *, size_t, unsigned,
    104 	    const struct timespec *);
    105 ssize_t	_sys___mq_timedreceive50(mqd_t, char *, size_t, unsigned *,
    106 	    const struct timespec *);
    107 ssize_t	_sys_msgrcv(int, void *, size_t, long, int);
    108 int	_sys_msgsnd(int, const void *, size_t, int);
    109 int	_sys___msync13(void *, size_t, int);
    110 int	_sys___nanosleep50(const struct timespec *, struct timespec *);
    111 int	__nanosleep50(const struct timespec *, struct timespec *);
    112 int	_sys_open(const char *, int, ...);
    113 int	_sys_poll(struct pollfd *, nfds_t, int);
    114 int	_sys___pollts50(struct pollfd *, nfds_t, const struct timespec *,
    115 	    const sigset_t *);
    116 ssize_t	_sys_pread(int, void *, size_t, off_t);
    117 int	_sys___pselect50(int, fd_set *, fd_set *, fd_set *,
    118 	    const struct timespec *, const sigset_t *);
    119 ssize_t	_sys_pwrite(int, const void *, size_t, off_t);
    120 ssize_t	_sys_read(int, void *, size_t);
    121 ssize_t	_sys_readv(int, const struct iovec *, int);
    122 int	_sys___select50(int, fd_set *, fd_set *, fd_set *, struct timeval *);
    123 int	_sys___wait450(pid_t, int *, int, struct rusage *);
    124 ssize_t	_sys_write(int, const void *, size_t);
    125 ssize_t	_sys_writev(int, const struct iovec *, int);
    126 int	_sys___sigsuspend14(const sigset_t *);
    127 int	____sigtimedwait50(const sigset_t * __restrict, siginfo_t * __restrict,
    128 	    struct timespec * __restrict);
    129 int	__sigsuspend14(const sigset_t *);
    130 
    131 #define TESTCANCEL(id) 	do {						\
    132 	if (__predict_true(!__uselibcstub) &&				\
    133 	    __predict_false((id)->pt_cancel))				\
    134 		pthread__cancelled();					\
    135 	} while (/*CONSTCOND*/0)
    136 
    137 
    138 int
    139 accept(int s, struct sockaddr *addr, socklen_t *addrlen)
    140 {
    141 	int retval;
    142 	pthread_t self;
    143 
    144 	self = pthread__self();
    145 	TESTCANCEL(self);
    146 	retval = _sys_accept(s, addr, addrlen);
    147 	TESTCANCEL(self);
    148 
    149 	return retval;
    150 }
    151 
    152 int
    153 __aio_suspend50(const struct aiocb * const list[], int nent,
    154     const struct timespec *timeout)
    155 {
    156 	int retval;
    157 	pthread_t self;
    158 
    159 	self = pthread__self();
    160 	TESTCANCEL(self);
    161 	retval = _sys___aio_suspend50(list, nent, timeout);
    162 	TESTCANCEL(self);
    163 
    164 	return retval;
    165 }
    166 
    167 int
    168 __kevent50(int fd, const struct kevent *ev, size_t nev, struct kevent *rev,
    169     size_t nrev, const struct timespec *ts)
    170 {
    171 	int retval;
    172 	pthread_t self;
    173 
    174 	self = pthread__self();
    175 	TESTCANCEL(self);
    176 	retval = _sys___kevent50(fd, ev, nev, rev, nrev, ts);
    177 	TESTCANCEL(self);
    178 
    179 	return retval;
    180 }
    181 
    182 int
    183 close(int d)
    184 {
    185 	int retval;
    186 	pthread_t self;
    187 
    188 	self = pthread__self();
    189 	TESTCANCEL(self);
    190 	retval = _sys_close(d);
    191 	TESTCANCEL(self);
    192 
    193 	return retval;
    194 }
    195 
    196 int
    197 connect(int s, const struct sockaddr *addr, socklen_t namelen)
    198 {
    199 	int retval;
    200 	pthread_t self;
    201 
    202 	self = pthread__self();
    203 	TESTCANCEL(self);
    204 	retval = _sys_connect(s, addr, namelen);
    205 	TESTCANCEL(self);
    206 
    207 	return retval;
    208 }
    209 
    210 int
    211 fcntl(int fd, int cmd, ...)
    212 {
    213 	int retval;
    214 	pthread_t self;
    215 	va_list ap;
    216 
    217 	self = pthread__self();
    218 	TESTCANCEL(self);
    219 	va_start(ap, cmd);
    220 	retval = _sys_fcntl(fd, cmd, va_arg(ap, void *));
    221 	va_end(ap);
    222 	TESTCANCEL(self);
    223 
    224 	return retval;
    225 }
    226 
    227 int
    228 fdatasync(int d)
    229 {
    230 	int retval;
    231 	pthread_t self;
    232 
    233 	self = pthread__self();
    234 	TESTCANCEL(self);
    235 	retval = _sys_fdatasync(d);
    236 	TESTCANCEL(self);
    237 
    238 	return retval;
    239 }
    240 
    241 int
    242 fsync(int d)
    243 {
    244 	int retval;
    245 	pthread_t self;
    246 
    247 	self = pthread__self();
    248 	TESTCANCEL(self);
    249 	retval = _sys_fsync(d);
    250 	TESTCANCEL(self);
    251 
    252 	return retval;
    253 }
    254 
    255 int
    256 fsync_range(int d, int f, off_t s, off_t e)
    257 {
    258 	int retval;
    259 	pthread_t self;
    260 
    261 	self = pthread__self();
    262 	TESTCANCEL(self);
    263 	retval = _sys_fsync_range(d, f, s, e);
    264 	TESTCANCEL(self);
    265 
    266 	return retval;
    267 }
    268 
    269 int
    270 mq_send(mqd_t mqdes, const char *msg_ptr, size_t msg_len, unsigned msg_prio)
    271 {
    272 	int retval;
    273 	pthread_t self;
    274 
    275 	self = pthread__self();
    276 	TESTCANCEL(self);
    277 	retval = _sys_mq_send(mqdes, msg_ptr, msg_len, msg_prio);
    278 	TESTCANCEL(self);
    279 
    280 	return retval;
    281 }
    282 
    283 ssize_t
    284 mq_receive(mqd_t mqdes, char *msg_ptr, size_t msg_len, unsigned *msg_prio)
    285 {
    286 	ssize_t retval;
    287 	pthread_t self;
    288 
    289 	self = pthread__self();
    290 	TESTCANCEL(self);
    291 	retval = _sys_mq_receive(mqdes, msg_ptr, msg_len, msg_prio);
    292 	TESTCANCEL(self);
    293 
    294 	return retval;
    295 }
    296 
    297 int
    298 __mq_timedsend50(mqd_t mqdes, const char *msg_ptr, size_t msg_len,
    299     unsigned msg_prio, const struct timespec *abst)
    300 {
    301 	int retval;
    302 	pthread_t self;
    303 
    304 	self = pthread__self();
    305 	TESTCANCEL(self);
    306 	retval = _sys___mq_timedsend50(mqdes, msg_ptr, msg_len, msg_prio, abst);
    307 	TESTCANCEL(self);
    308 
    309 	return retval;
    310 }
    311 
    312 ssize_t
    313 __mq_timedreceive50(mqd_t mqdes, char *msg_ptr, size_t msg_len, unsigned *msg_prio,
    314     const struct timespec *abst)
    315 {
    316 	ssize_t retval;
    317 	pthread_t self;
    318 
    319 	self = pthread__self();
    320 	TESTCANCEL(self);
    321 	retval = _sys___mq_timedreceive50(mqdes, msg_ptr, msg_len, msg_prio, abst);
    322 	TESTCANCEL(self);
    323 
    324 	return retval;
    325 }
    326 
    327 ssize_t
    328 msgrcv(int msgid, void *msgp, size_t msgsz, long msgtyp, int msgflg)
    329 {
    330 	ssize_t retval;
    331 	pthread_t self;
    332 
    333 	self = pthread__self();
    334 	TESTCANCEL(self);
    335 	retval = _sys_msgrcv(msgid, msgp, msgsz, msgtyp, msgflg);
    336 	TESTCANCEL(self);
    337 
    338 	return retval;
    339 }
    340 
    341 int
    342 msgsnd(int msgid, const void *msgp, size_t msgsz, int msgflg)
    343 {
    344 	int retval;
    345 	pthread_t self;
    346 
    347 	self = pthread__self();
    348 	TESTCANCEL(self);
    349 	retval = _sys_msgsnd(msgid, msgp, msgsz, msgflg);
    350 	TESTCANCEL(self);
    351 
    352 	return retval;
    353 }
    354 
    355 int
    356 __msync13(void *addr, size_t len, int flags)
    357 {
    358 	int retval;
    359 	pthread_t self;
    360 
    361 	self = pthread__self();
    362 	TESTCANCEL(self);
    363 	retval = _sys___msync13(addr, len, flags);
    364 	TESTCANCEL(self);
    365 
    366 	return retval;
    367 }
    368 
    369 int
    370 open(const char *path, int flags, ...)
    371 {
    372 	int retval;
    373 	pthread_t self;
    374 	va_list ap;
    375 
    376 	self = pthread__self();
    377 	TESTCANCEL(self);
    378 	va_start(ap, flags);
    379 	retval = _sys_open(path, flags, va_arg(ap, mode_t));
    380 	va_end(ap);
    381 	TESTCANCEL(self);
    382 
    383 	return retval;
    384 }
    385 
    386 int
    387 __nanosleep50(const struct timespec *rqtp, struct timespec *rmtp)
    388 {
    389 	int retval;
    390 	pthread_t self;
    391 
    392 	self = pthread__self();
    393 	TESTCANCEL(self);
    394 	/*
    395 	 * For now, just nanosleep.  In the future, maybe pass a ucontext_t
    396 	 * to _lwp_nanosleep() and allow it to recycle our kernel stack.
    397 	 */
    398 	retval = _sys___nanosleep50(rqtp, rmtp);
    399 	TESTCANCEL(self);
    400 
    401 	return retval;
    402 }
    403 
    404 int
    405 poll(struct pollfd *fds, nfds_t nfds, int timeout)
    406 {
    407 	int retval;
    408 	pthread_t self;
    409 
    410 	self = pthread__self();
    411 	TESTCANCEL(self);
    412 	retval = _sys_poll(fds, nfds, timeout);
    413 	TESTCANCEL(self);
    414 
    415 	return retval;
    416 }
    417 
    418 int
    419 __pollts50(struct pollfd *fds, nfds_t nfds, const struct timespec *ts,
    420     const sigset_t *sigmask)
    421 {
    422 	int retval;
    423 	pthread_t self;
    424 
    425 	self = pthread__self();
    426 	TESTCANCEL(self);
    427 	retval = _sys___pollts50(fds, nfds, ts, sigmask);
    428 	TESTCANCEL(self);
    429 
    430 	return retval;
    431 }
    432 
    433 ssize_t
    434 pread(int d, void *buf, size_t nbytes, off_t offset)
    435 {
    436 	ssize_t retval;
    437 	pthread_t self;
    438 
    439 	self = pthread__self();
    440 	TESTCANCEL(self);
    441 	retval = _sys_pread(d, buf, nbytes, offset);
    442 	TESTCANCEL(self);
    443 
    444 	return retval;
    445 }
    446 
    447 int
    448 __pselect50(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
    449     const struct timespec *timeout, const sigset_t *sigmask)
    450 {
    451 	int retval;
    452 	pthread_t self;
    453 
    454 	self = pthread__self();
    455 	TESTCANCEL(self);
    456 	retval = _sys___pselect50(nfds, readfds, writefds, exceptfds, timeout,
    457 	    sigmask);
    458 	TESTCANCEL(self);
    459 
    460 	return retval;
    461 }
    462 
    463 ssize_t
    464 pwrite(int d, const void *buf, size_t nbytes, off_t offset)
    465 {
    466 	ssize_t retval;
    467 	pthread_t self;
    468 
    469 	self = pthread__self();
    470 	TESTCANCEL(self);
    471 	retval = _sys_pwrite(d, buf, nbytes, offset);
    472 	TESTCANCEL(self);
    473 
    474 	return retval;
    475 }
    476 
    477 ssize_t
    478 read(int d, void *buf, size_t nbytes)
    479 {
    480 	ssize_t retval;
    481 	pthread_t self;
    482 
    483 	self = pthread__self();
    484 	TESTCANCEL(self);
    485 	retval = _sys_read(d, buf, nbytes);
    486 	TESTCANCEL(self);
    487 
    488 	return retval;
    489 }
    490 
    491 ssize_t
    492 readv(int d, const struct iovec *iov, int iovcnt)
    493 {
    494 	ssize_t retval;
    495 	pthread_t self;
    496 
    497 	self = pthread__self();
    498 	TESTCANCEL(self);
    499 	retval = _sys_readv(d, iov, iovcnt);
    500 	TESTCANCEL(self);
    501 
    502 	return retval;
    503 }
    504 
    505 int
    506 __select50(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
    507     struct timeval *timeout)
    508 {
    509 	int retval;
    510 	pthread_t self;
    511 
    512 	self = pthread__self();
    513 	TESTCANCEL(self);
    514 	retval = _sys___select50(nfds, readfds, writefds, exceptfds, timeout);
    515 	TESTCANCEL(self);
    516 
    517 	return retval;
    518 }
    519 
    520 pid_t
    521 __wait450(pid_t wpid, int *status, int options, struct rusage *rusage)
    522 {
    523 	pid_t retval;
    524 	pthread_t self;
    525 
    526 	self = pthread__self();
    527 	TESTCANCEL(self);
    528 	retval = _sys___wait450(wpid, status, options, rusage);
    529 	TESTCANCEL(self);
    530 
    531 	return retval;
    532 }
    533 
    534 ssize_t
    535 write(int d, const void *buf, size_t nbytes)
    536 {
    537 	ssize_t retval;
    538 	pthread_t self;
    539 
    540 	self = pthread__self();
    541 	TESTCANCEL(self);
    542 	retval = _sys_write(d, buf, nbytes);
    543 	TESTCANCEL(self);
    544 
    545 	return retval;
    546 }
    547 
    548 ssize_t
    549 writev(int d, const struct iovec *iov, int iovcnt)
    550 {
    551 	ssize_t retval;
    552 	pthread_t self;
    553 
    554 	self = pthread__self();
    555 	TESTCANCEL(self);
    556 	retval = _sys_writev(d, iov, iovcnt);
    557 	TESTCANCEL(self);
    558 
    559 	return retval;
    560 }
    561 
    562 int
    563 __sigsuspend14(const sigset_t *sigmask)
    564 {
    565 	pthread_t self;
    566 	int retval;
    567 
    568 	self = pthread__self();
    569 	TESTCANCEL(self);
    570 	retval = _sys___sigsuspend14(sigmask);
    571 	TESTCANCEL(self);
    572 
    573 	return retval;
    574 }
    575 
    576 int
    577 __sigtimedwait50(const sigset_t * __restrict set, siginfo_t * __restrict info,
    578     const struct timespec * __restrict timeout)
    579 {
    580 	pthread_t self;
    581 	int retval;
    582 	struct timespec tout, *tp;
    583 
    584 	if (timeout) {
    585 		tout = *timeout;
    586 		tp = &tout;
    587 	} else
    588 		tp = NULL;
    589 
    590 	self = pthread__self();
    591 	TESTCANCEL(self);
    592 	retval = ____sigtimedwait50(set, info, tp);
    593 	TESTCANCEL(self);
    594 
    595 	return retval;
    596 }
    597 
    598 int
    599 sigwait(const sigset_t * __restrict set, int * __restrict sig)
    600 {
    601 	pthread_t	self;
    602 	int		saved_errno;
    603 	int		new_errno;
    604 	int		retval;
    605 
    606 	self = pthread__self();
    607 	saved_errno = errno;
    608 	TESTCANCEL(self);
    609 	retval = ____sigtimedwait50(set, NULL, NULL);
    610 	TESTCANCEL(self);
    611 	new_errno = errno;
    612 	errno = saved_errno;
    613 	if (retval < 0) {
    614 		return new_errno;
    615 	}
    616 	*sig = retval;
    617 	return 0;
    618 }
    619 
    620 __strong_alias(_close, close)
    621 __strong_alias(_fcntl, fcntl)
    622 __strong_alias(_fdatasync, fdatasync)
    623 __strong_alias(_fsync, fsync)
    624 __weak_alias(fsync_range, _fsync_range)
    625 __strong_alias(_mq_send, mq_send)
    626 __strong_alias(_mq_receive, mq_receive)
    627 __strong_alias(_msgrcv, msgrcv)
    628 __strong_alias(_msgsnd, msgsnd)
    629 __strong_alias(___msync13, __msync13)
    630 __strong_alias(___nanosleep50, __nanosleep50)
    631 __strong_alias(_open, open)
    632 __strong_alias(_poll, poll)
    633 __strong_alias(_pread, pread)
    634 __strong_alias(_pwrite, pwrite)
    635 __strong_alias(_read, read)
    636 __strong_alias(_readv, readv)
    637 __strong_alias(_sigwait, sigwait)
    638 __strong_alias(_write, write)
    639 __strong_alias(_writev, writev)
    640 
    641 #endif	/* !lint */
    642