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