Home | History | Annotate | Line # | Download | only in libpthread
pthread_cancelstub.c revision 1.34
      1 /*	$NetBSD: pthread_cancelstub.c,v 1.34 2011/04/21 13:38:14 joerg 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.34 2011/04/21 13:38:14 joerg 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 <fcntl.h>
     62 #include <mqueue.h>
     63 #include <poll.h>
     64 #include <stdarg.h>
     65 #include <unistd.h>
     66 
     67 #include <signal.h>
     68 #include <sys/mman.h>
     69 #include <sys/select.h>
     70 #include <sys/socket.h>
     71 #include <sys/event.h>
     72 
     73 #include <compat/sys/mman.h>
     74 #include <compat/sys/poll.h>
     75 #include <compat/sys/select.h>
     76 #include <compat/sys/event.h>
     77 #include <compat/sys/wait.h>
     78 #include <compat/include/mqueue.h>
     79 #include <compat/include/signal.h>
     80 
     81 #include "pthread.h"
     82 #include "pthread_int.h"
     83 
     84 int	pthread__cancel_stub_binder;
     85 
     86 int	_sys_accept(int, struct sockaddr *, socklen_t *);
     87 int	_sys___aio_suspend50(const struct aiocb * const [], int,
     88 	    const struct timespec *);
     89 int	__aio_suspend50(const struct aiocb * const [], int,
     90 	    const struct timespec *);
     91 int	_sys_close(int);
     92 int	_sys_connect(int, const struct sockaddr *, socklen_t);
     93 int	_sys_fcntl(int, int, ...);
     94 int	_sys_fdatasync(int);
     95 int	_sys_fsync(int);
     96 int	_sys_fsync_range(int, int, off_t, off_t);
     97 int	_sys___kevent50(int, const struct kevent *, size_t, struct kevent *,
     98 	    size_t, const struct timespec *);
     99 int	_sys_mq_send(mqd_t, const char *, size_t, unsigned);
    100 ssize_t	_sys_mq_receive(mqd_t, char *, size_t, unsigned *);
    101 int	_sys___mq_timedsend50(mqd_t, const char *, size_t, unsigned,
    102 	    const struct timespec *);
    103 ssize_t	_sys___mq_timedreceive50(mqd_t, char *, size_t, unsigned *,
    104 	    const struct timespec *);
    105 ssize_t	_sys_msgrcv(int, void *, size_t, long, int);
    106 int	_sys_msgsnd(int, const void *, size_t, int);
    107 int	_sys___msync13(void *, size_t, int);
    108 int	_sys___nanosleep50(const struct timespec *, struct timespec *);
    109 int	__nanosleep50(const struct timespec *, struct timespec *);
    110 int	_sys_open(const char *, int, ...);
    111 int	_sys_poll(struct pollfd *, nfds_t, int);
    112 int	_sys___pollts50(struct pollfd *, nfds_t, const struct timespec *,
    113 	    const sigset_t *);
    114 ssize_t	_sys_pread(int, void *, size_t, off_t);
    115 int	_sys___pselect50(int, fd_set *, fd_set *, fd_set *,
    116 	    const struct timespec *, const sigset_t *);
    117 ssize_t	_sys_pwrite(int, const void *, size_t, off_t);
    118 ssize_t	_sys_read(int, void *, size_t);
    119 ssize_t	_sys_readv(int, const struct iovec *, int);
    120 int	_sys___select50(int, fd_set *, fd_set *, fd_set *, struct timeval *);
    121 int	_sys___wait450(pid_t, int *, int, struct rusage *);
    122 ssize_t	_sys_write(int, const void *, size_t);
    123 ssize_t	_sys_writev(int, const struct iovec *, int);
    124 int	_sys___sigsuspend14(const sigset_t *);
    125 int	____sigtimedwait50(const sigset_t * __restrict, siginfo_t * __restrict,
    126 	    struct timespec * __restrict);
    127 int	__sigsuspend14(const sigset_t *);
    128 
    129 #define TESTCANCEL(id) 	do {						\
    130 	if (__predict_false((id)->pt_cancel))				\
    131 		pthread__cancelled();					\
    132 	} while (/*CONSTCOND*/0)
    133 
    134 
    135 int
    136 accept(int s, struct sockaddr *addr, socklen_t *addrlen)
    137 {
    138 	int retval;
    139 	pthread_t self;
    140 
    141 	self = pthread__self();
    142 	TESTCANCEL(self);
    143 	retval = _sys_accept(s, addr, addrlen);
    144 	TESTCANCEL(self);
    145 
    146 	return retval;
    147 }
    148 
    149 int
    150 __aio_suspend50(const struct aiocb * const list[], int nent,
    151     const struct timespec *timeout)
    152 {
    153 	int retval;
    154 	pthread_t self;
    155 
    156 	self = pthread__self();
    157 	TESTCANCEL(self);
    158 	retval = _sys___aio_suspend50(list, nent, timeout);
    159 	TESTCANCEL(self);
    160 
    161 	return retval;
    162 }
    163 
    164 int
    165 __kevent50(int fd, const struct kevent *ev, size_t nev, struct kevent *rev,
    166     size_t nrev, const struct timespec *ts)
    167 {
    168 	int retval;
    169 	pthread_t self;
    170 
    171 	self = pthread__self();
    172 	TESTCANCEL(self);
    173 	retval = _sys___kevent50(fd, ev, nev, rev, nrev, ts);
    174 	TESTCANCEL(self);
    175 
    176 	return retval;
    177 }
    178 
    179 int
    180 close(int d)
    181 {
    182 	int retval;
    183 	pthread_t self;
    184 
    185 	self = pthread__self();
    186 	TESTCANCEL(self);
    187 	retval = _sys_close(d);
    188 	TESTCANCEL(self);
    189 
    190 	return retval;
    191 }
    192 
    193 int
    194 connect(int s, const struct sockaddr *addr, socklen_t namelen)
    195 {
    196 	int retval;
    197 	pthread_t self;
    198 
    199 	self = pthread__self();
    200 	TESTCANCEL(self);
    201 	retval = _sys_connect(s, addr, namelen);
    202 	TESTCANCEL(self);
    203 
    204 	return retval;
    205 }
    206 
    207 int
    208 fcntl(int fd, int cmd, ...)
    209 {
    210 	int retval;
    211 	pthread_t self;
    212 	va_list ap;
    213 
    214 	self = pthread__self();
    215 	TESTCANCEL(self);
    216 	va_start(ap, cmd);
    217 	retval = _sys_fcntl(fd, cmd, va_arg(ap, void *));
    218 	va_end(ap);
    219 	TESTCANCEL(self);
    220 
    221 	return retval;
    222 }
    223 
    224 int
    225 fdatasync(int d)
    226 {
    227 	int retval;
    228 	pthread_t self;
    229 
    230 	self = pthread__self();
    231 	TESTCANCEL(self);
    232 	retval = _sys_fdatasync(d);
    233 	TESTCANCEL(self);
    234 
    235 	return retval;
    236 }
    237 
    238 int
    239 fsync(int d)
    240 {
    241 	int retval;
    242 	pthread_t self;
    243 
    244 	self = pthread__self();
    245 	TESTCANCEL(self);
    246 	retval = _sys_fsync(d);
    247 	TESTCANCEL(self);
    248 
    249 	return retval;
    250 }
    251 
    252 int
    253 fsync_range(int d, int f, off_t s, off_t e)
    254 {
    255 	int retval;
    256 	pthread_t self;
    257 
    258 	self = pthread__self();
    259 	TESTCANCEL(self);
    260 	retval = _sys_fsync_range(d, f, s, e);
    261 	TESTCANCEL(self);
    262 
    263 	return retval;
    264 }
    265 
    266 int
    267 mq_send(mqd_t mqdes, const char *msg_ptr, size_t msg_len, unsigned msg_prio)
    268 {
    269 	int retval;
    270 	pthread_t self;
    271 
    272 	self = pthread__self();
    273 	TESTCANCEL(self);
    274 	retval = _sys_mq_send(mqdes, msg_ptr, msg_len, msg_prio);
    275 	TESTCANCEL(self);
    276 
    277 	return retval;
    278 }
    279 
    280 ssize_t
    281 mq_receive(mqd_t mqdes, char *msg_ptr, size_t msg_len, unsigned *msg_prio)
    282 {
    283 	ssize_t retval;
    284 	pthread_t self;
    285 
    286 	self = pthread__self();
    287 	TESTCANCEL(self);
    288 	retval = _sys_mq_receive(mqdes, msg_ptr, msg_len, msg_prio);
    289 	TESTCANCEL(self);
    290 
    291 	return retval;
    292 }
    293 
    294 int
    295 __mq_timedsend50(mqd_t mqdes, const char *msg_ptr, size_t msg_len,
    296     unsigned msg_prio, const struct timespec *abst)
    297 {
    298 	int retval;
    299 	pthread_t self;
    300 
    301 	self = pthread__self();
    302 	TESTCANCEL(self);
    303 	retval = _sys___mq_timedsend50(mqdes, msg_ptr, msg_len, msg_prio, abst);
    304 	TESTCANCEL(self);
    305 
    306 	return retval;
    307 }
    308 
    309 ssize_t
    310 __mq_timedreceive50(mqd_t mqdes, char *msg_ptr, size_t msg_len, unsigned *msg_prio,
    311     const struct timespec *abst)
    312 {
    313 	ssize_t retval;
    314 	pthread_t self;
    315 
    316 	self = pthread__self();
    317 	TESTCANCEL(self);
    318 	retval = _sys___mq_timedreceive50(mqdes, msg_ptr, msg_len, msg_prio, abst);
    319 	TESTCANCEL(self);
    320 
    321 	return retval;
    322 }
    323 
    324 ssize_t
    325 msgrcv(int msgid, void *msgp, size_t msgsz, long msgtyp, int msgflg)
    326 {
    327 	ssize_t retval;
    328 	pthread_t self;
    329 
    330 	self = pthread__self();
    331 	TESTCANCEL(self);
    332 	retval = _sys_msgrcv(msgid, msgp, msgsz, msgtyp, msgflg);
    333 	TESTCANCEL(self);
    334 
    335 	return retval;
    336 }
    337 
    338 int
    339 msgsnd(int msgid, const void *msgp, size_t msgsz, int msgflg)
    340 {
    341 	int retval;
    342 	pthread_t self;
    343 
    344 	self = pthread__self();
    345 	TESTCANCEL(self);
    346 	retval = _sys_msgsnd(msgid, msgp, msgsz, msgflg);
    347 	TESTCANCEL(self);
    348 
    349 	return retval;
    350 }
    351 
    352 int
    353 __msync13(void *addr, size_t len, int flags)
    354 {
    355 	int retval;
    356 	pthread_t self;
    357 
    358 	self = pthread__self();
    359 	TESTCANCEL(self);
    360 	retval = _sys___msync13(addr, len, flags);
    361 	TESTCANCEL(self);
    362 
    363 	return retval;
    364 }
    365 
    366 int
    367 open(const char *path, int flags, ...)
    368 {
    369 	int retval;
    370 	pthread_t self;
    371 	va_list ap;
    372 
    373 	self = pthread__self();
    374 	TESTCANCEL(self);
    375 	va_start(ap, flags);
    376 	retval = _sys_open(path, flags, va_arg(ap, mode_t));
    377 	va_end(ap);
    378 	TESTCANCEL(self);
    379 
    380 	return retval;
    381 }
    382 
    383 int
    384 __nanosleep50(const struct timespec *rqtp, struct timespec *rmtp)
    385 {
    386 	int retval;
    387 	pthread_t self;
    388 
    389 	self = pthread__self();
    390 	TESTCANCEL(self);
    391 	/*
    392 	 * For now, just nanosleep.  In the future, maybe pass a ucontext_t
    393 	 * to _lwp_nanosleep() and allow it to recycle our kernel stack.
    394 	 */
    395 	retval = _sys___nanosleep50(rqtp, rmtp);
    396 	TESTCANCEL(self);
    397 
    398 	return retval;
    399 }
    400 
    401 int
    402 poll(struct pollfd *fds, nfds_t nfds, int timeout)
    403 {
    404 	int retval;
    405 	pthread_t self;
    406 
    407 	self = pthread__self();
    408 	TESTCANCEL(self);
    409 	retval = _sys_poll(fds, nfds, timeout);
    410 	TESTCANCEL(self);
    411 
    412 	return retval;
    413 }
    414 
    415 int
    416 __pollts50(struct pollfd *fds, nfds_t nfds, const struct timespec *ts,
    417     const sigset_t *sigmask)
    418 {
    419 	int retval;
    420 	pthread_t self;
    421 
    422 	self = pthread__self();
    423 	TESTCANCEL(self);
    424 	retval = _sys___pollts50(fds, nfds, ts, sigmask);
    425 	TESTCANCEL(self);
    426 
    427 	return retval;
    428 }
    429 
    430 ssize_t
    431 pread(int d, void *buf, size_t nbytes, off_t offset)
    432 {
    433 	ssize_t retval;
    434 	pthread_t self;
    435 
    436 	self = pthread__self();
    437 	TESTCANCEL(self);
    438 	retval = _sys_pread(d, buf, nbytes, offset);
    439 	TESTCANCEL(self);
    440 
    441 	return retval;
    442 }
    443 
    444 int
    445 __pselect50(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
    446     const struct timespec *timeout, const sigset_t *sigmask)
    447 {
    448 	int retval;
    449 	pthread_t self;
    450 
    451 	self = pthread__self();
    452 	TESTCANCEL(self);
    453 	retval = _sys___pselect50(nfds, readfds, writefds, exceptfds, timeout,
    454 	    sigmask);
    455 	TESTCANCEL(self);
    456 
    457 	return retval;
    458 }
    459 
    460 ssize_t
    461 pwrite(int d, const void *buf, size_t nbytes, off_t offset)
    462 {
    463 	ssize_t retval;
    464 	pthread_t self;
    465 
    466 	self = pthread__self();
    467 	TESTCANCEL(self);
    468 	retval = _sys_pwrite(d, buf, nbytes, offset);
    469 	TESTCANCEL(self);
    470 
    471 	return retval;
    472 }
    473 
    474 ssize_t
    475 readv(int d, const struct iovec *iov, int iovcnt)
    476 {
    477 	ssize_t retval;
    478 	pthread_t self;
    479 
    480 	self = pthread__self();
    481 	TESTCANCEL(self);
    482 	retval = _sys_readv(d, iov, iovcnt);
    483 	TESTCANCEL(self);
    484 
    485 	return retval;
    486 }
    487 
    488 int
    489 __select50(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
    490     struct timeval *timeout)
    491 {
    492 	int retval;
    493 	pthread_t self;
    494 
    495 	self = pthread__self();
    496 	TESTCANCEL(self);
    497 	retval = _sys___select50(nfds, readfds, writefds, exceptfds, timeout);
    498 	TESTCANCEL(self);
    499 
    500 	return retval;
    501 }
    502 
    503 pid_t
    504 __wait450(pid_t wpid, int *status, int options, struct rusage *rusage)
    505 {
    506 	pid_t retval;
    507 	pthread_t self;
    508 
    509 	self = pthread__self();
    510 	TESTCANCEL(self);
    511 	retval = _sys___wait450(wpid, status, options, rusage);
    512 	TESTCANCEL(self);
    513 
    514 	return retval;
    515 }
    516 
    517 ssize_t
    518 write(int d, const void *buf, size_t nbytes)
    519 {
    520 	ssize_t retval;
    521 	pthread_t self;
    522 
    523 	self = pthread__self();
    524 	TESTCANCEL(self);
    525 	retval = _sys_write(d, buf, nbytes);
    526 	TESTCANCEL(self);
    527 
    528 	return retval;
    529 }
    530 
    531 ssize_t
    532 writev(int d, const struct iovec *iov, int iovcnt)
    533 {
    534 	ssize_t retval;
    535 	pthread_t self;
    536 
    537 	self = pthread__self();
    538 	TESTCANCEL(self);
    539 	retval = _sys_writev(d, iov, iovcnt);
    540 	TESTCANCEL(self);
    541 
    542 	return retval;
    543 }
    544 
    545 int
    546 __sigsuspend14(const sigset_t *sigmask)
    547 {
    548 	pthread_t self;
    549 	int retval;
    550 
    551 	self = pthread__self();
    552 	TESTCANCEL(self);
    553 	retval = _sys___sigsuspend14(sigmask);
    554 	TESTCANCEL(self);
    555 
    556 	return retval;
    557 }
    558 
    559 int
    560 __sigtimedwait50(const sigset_t * __restrict set, siginfo_t * __restrict info,
    561     const struct timespec * __restrict timeout)
    562 {
    563 	pthread_t self;
    564 	int retval;
    565 	struct timespec tout, *tp;
    566 	if (timeout) {
    567 		tout = *timeout;
    568 		tp = &tout;
    569 	} else
    570 		tp = NULL;
    571 
    572 	self = pthread__self();
    573 	TESTCANCEL(self);
    574 	retval = ____sigtimedwait50(set, info, tp);
    575 	TESTCANCEL(self);
    576 
    577 	return retval;
    578 }
    579 
    580 __strong_alias(_close, close)
    581 __strong_alias(_fcntl, fcntl)
    582 __strong_alias(_fdatasync, fdatasync)
    583 __strong_alias(_fsync, fsync)
    584 __weak_alias(fsync_range, _fsync_range)
    585 __strong_alias(_mq_send, mq_send)
    586 __strong_alias(_mq_receive, mq_receive)
    587 __strong_alias(_msgrcv, msgrcv)
    588 __strong_alias(_msgsnd, msgsnd)
    589 __strong_alias(___msync13, __msync13)
    590 __strong_alias(___nanosleep50, __nanosleep50)
    591 __strong_alias(_open, open)
    592 __strong_alias(_poll, poll)
    593 __strong_alias(_pread, pread)
    594 __strong_alias(_pwrite, pwrite)
    595 __strong_alias(_read, read)
    596 __strong_alias(_readv, readv)
    597 __strong_alias(_write, write)
    598 __strong_alias(_writev, writev)
    599 
    600 #endif	/* !lint */
    601