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