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