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