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