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