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