Home | History | Annotate | Line # | Download | only in libpthread
pthread_cancelstub.c revision 1.45.2.1
      1 /*	$NetBSD: pthread_cancelstub.c,v 1.45.2.1 2025/08/02 05:54:55 perseant 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 /* Disable namespace mangling, Fortification is useless here anyway. */
     33 #undef _FORTIFY_SOURCE
     34 
     35 #include <sys/cdefs.h>
     36 __RCSID("$NetBSD: pthread_cancelstub.c,v 1.45.2.1 2025/08/02 05:54:55 perseant Exp $");
     37 
     38 /* Need to use libc-private names for atomic operations. */
     39 #include "../../common/lib/libc/atomic/atomic_op_namespace.h"
     40 
     41 #ifndef lint
     42 
     43 
     44 /*
     45  * This is necessary because the names are always weak (they are not
     46  * POSIX functions).
     47  */
     48 #define	fsync_range	_fsync_range
     49 #define	pollts		_pollts
     50 
     51 /*
     52  * XXX this is necessary to get the prototypes for the __sigsuspend14
     53  * XXX and __msync13 internal names, instead of the application-visible
     54  * XXX sigsuspend and msync names. It's kind of gross, but we're pretty
     55  * XXX intimate with libc already.
     56  */
     57 #define __LIBC12_SOURCE__
     58 
     59 #include <sys/msg.h>
     60 #include <sys/types.h>
     61 #include <sys/uio.h>
     62 #include <sys/wait.h>
     63 #include <aio.h>
     64 #include <errno.h>
     65 #include <fcntl.h>
     66 #include <mqueue.h>
     67 #include <poll.h>
     68 #include <stdatomic.h>
     69 #include <stdarg.h>
     70 #include <termios.h>
     71 #include <unistd.h>
     72 
     73 #include <signal.h>
     74 #include <sys/mman.h>
     75 #include <sys/select.h>
     76 #include <sys/socket.h>
     77 #include <sys/event.h>
     78 #include <sys/resource.h>
     79 
     80 #include <compat/sys/mman.h>
     81 #include <compat/sys/poll.h>
     82 #include <compat/sys/select.h>
     83 #include <compat/sys/event.h>
     84 #include <compat/sys/wait.h>
     85 #include <compat/sys/resource.h>
     86 #include <compat/include/aio.h>
     87 #include <compat/include/mqueue.h>
     88 #include <compat/include/signal.h>
     89 #include <compat/include/time.h>
     90 
     91 #include "pthread.h"
     92 #include "pthread_int.h"
     93 #include "reentrant.h"
     94 
     95 #define	atomic_load_relaxed(p)						      \
     96 	atomic_load_explicit(p, memory_order_relaxed)
     97 
     98 int	pthread__cancel_stub_binder;
     99 
    100 /*
    101  * Provide declarations for the underlying libc syscall stubs.  These
    102  * _sys_* functions are symbols defined by libc which invoke the system
    103  * call, without testing for cancellation.  Below, we define non-_sys_*
    104  * wrappers which surround calls to _sys_* by the equivalent of
    105  * pthread_testcancel().  Both libc and libpthread define the
    106  * non-_sys_* wrappers, but they are weak in libc and strong in
    107  * libpthread, so programs linked against both will get the libpthread
    108  * wrappers that test for cancellation.
    109  */
    110 __typeof(accept) _sys_accept;
    111 __typeof(__aio_suspend50) _sys___aio_suspend50;
    112 __typeof(clock_nanosleep) _sys_clock_nanosleep;
    113 __typeof(close) _sys_close;
    114 __typeof(connect) _sys_connect;
    115 __typeof(fcntl) _sys_fcntl;
    116 __typeof(fdatasync) _sys_fdatasync;
    117 __typeof(fsync) _sys_fsync;
    118 __typeof(fsync_range) _sys_fsync_range;
    119 __typeof(__kevent100) _sys___kevent100;
    120 __typeof(mq_receive) _sys_mq_receive;
    121 __typeof(mq_send) _sys_mq_send;
    122 __typeof(__mq_timedreceive50) _sys___mq_timedreceive50;
    123 __typeof(__mq_timedsend50) _sys___mq_timedsend50;
    124 __typeof(msgrcv) _sys_msgrcv;
    125 __typeof(msgsnd) _sys_msgsnd;
    126 __typeof(__msync13) _sys___msync13;
    127 __typeof(__nanosleep50) _sys___nanosleep50;
    128 __typeof(open) _sys_open;
    129 __typeof(openat) _sys_openat;
    130 __typeof(paccept) _sys_paccept;
    131 __typeof(poll) _sys_poll;
    132 __typeof(__pollts50) _sys___pollts50;
    133 __typeof(pread) _sys_pread;
    134 __typeof(__pselect50) _sys___pselect50;
    135 __typeof(pwrite) _sys_pwrite;
    136 __typeof(read) _sys_read;
    137 __typeof(readv) _sys_readv;
    138 __typeof(recvfrom) _sys_recvfrom;
    139 __typeof(recvmmsg) _sys_recvmmsg;
    140 __typeof(recvmsg) _sys_recvmsg;
    141 __typeof(__select50) _sys___select50;
    142 __typeof(sendmmsg) _sys_sendmmsg;
    143 __typeof(sendmsg) _sys_sendmsg;
    144 __typeof(sendto) _sys_sendto;
    145 __typeof(__sigsuspend14) _sys___sigsuspend14;
    146 __typeof(__wait450) _sys___wait450;
    147 __typeof(write) _sys_write;
    148 __typeof(writev) _sys_writev;
    149 
    150 #define TESTCANCEL(id) 	do {						\
    151 	if (__predict_true(!__uselibcstub) &&				\
    152 	    __predict_false(atomic_load_relaxed(&(id)->pt_cancel) &	\
    153 		PT_CANCEL_CANCELLED)) {					\
    154 		membar_acquire();					\
    155 		pthread__cancelled();					\
    156 	}								\
    157 	} while (0)
    158 
    159 
    160 int
    161 accept(int s, struct sockaddr *addr, socklen_t *addrlen)
    162 {
    163 	int retval;
    164 	pthread_t self;
    165 
    166 	self = pthread__self();
    167 	TESTCANCEL(self);
    168 	retval = _sys_accept(s, addr, addrlen);
    169 	TESTCANCEL(self);
    170 
    171 	return retval;
    172 }
    173 
    174 int
    175 accept4(int s, struct sockaddr *addr, socklen_t *addrlen, int flags)
    176 {
    177 	int retval;
    178 	pthread_t self;
    179 
    180 	self = pthread__self();
    181 	TESTCANCEL(self);
    182 	retval = _sys_paccept(s, addr, addrlen, NULL, flags);
    183 	TESTCANCEL(self);
    184 
    185 	return retval;
    186 }
    187 
    188 int
    189 __aio_suspend50(const struct aiocb * const list[], int nent,
    190     const struct timespec *timeout)
    191 {
    192 	int retval;
    193 	pthread_t self;
    194 
    195 	self = pthread__self();
    196 	TESTCANCEL(self);
    197 	retval = _sys___aio_suspend50(list, nent, timeout);
    198 	TESTCANCEL(self);
    199 
    200 	return retval;
    201 }
    202 
    203 int
    204 clock_nanosleep(clockid_t clock_id, int flags,
    205     const struct timespec *rqtp, struct timespec *rmtp)
    206 {
    207 	int retval;
    208 	pthread_t self;
    209 
    210 	self = pthread__self();
    211 	TESTCANCEL(self);
    212 	retval = _sys_clock_nanosleep(clock_id, flags, rqtp, rmtp);
    213 	TESTCANCEL(self);
    214 
    215 	return retval;
    216 }
    217 
    218 int
    219 close(int d)
    220 {
    221 	int retval;
    222 	pthread_t self;
    223 
    224 	self = pthread__self();
    225 	TESTCANCEL(self);
    226 	retval = _sys_close(d);
    227 	TESTCANCEL(self);
    228 
    229 	return retval;
    230 }
    231 
    232 int
    233 connect(int s, const struct sockaddr *addr, socklen_t namelen)
    234 {
    235 	int retval;
    236 	pthread_t self;
    237 
    238 	self = pthread__self();
    239 	TESTCANCEL(self);
    240 	retval = _sys_connect(s, addr, namelen);
    241 	TESTCANCEL(self);
    242 
    243 	return retval;
    244 }
    245 
    246 int
    247 fcntl(int fd, int cmd, ...)
    248 {
    249 	int retval;
    250 	pthread_t self;
    251 	va_list ap;
    252 
    253 	self = pthread__self();
    254 	TESTCANCEL(self);
    255 	va_start(ap, cmd);
    256 	retval = _sys_fcntl(fd, cmd, va_arg(ap, void *));
    257 	va_end(ap);
    258 	TESTCANCEL(self);
    259 
    260 	return retval;
    261 }
    262 
    263 int
    264 fdatasync(int d)
    265 {
    266 	int retval;
    267 	pthread_t self;
    268 
    269 	self = pthread__self();
    270 	TESTCANCEL(self);
    271 	retval = _sys_fdatasync(d);
    272 	TESTCANCEL(self);
    273 
    274 	return retval;
    275 }
    276 
    277 int
    278 fsync(int d)
    279 {
    280 	int retval;
    281 	pthread_t self;
    282 
    283 	self = pthread__self();
    284 	TESTCANCEL(self);
    285 	retval = _sys_fsync(d);
    286 	TESTCANCEL(self);
    287 
    288 	return retval;
    289 }
    290 
    291 int
    292 fsync_range(int d, int f, off_t s, off_t e)
    293 {
    294 	int retval;
    295 	pthread_t self;
    296 
    297 	self = pthread__self();
    298 	TESTCANCEL(self);
    299 	retval = _sys_fsync_range(d, f, s, e);
    300 	TESTCANCEL(self);
    301 
    302 	return retval;
    303 }
    304 
    305 int
    306 __kevent100(int fd, const struct kevent *ev, size_t nev, struct kevent *rev,
    307     size_t nrev, const struct timespec *ts)
    308 {
    309 	int retval;
    310 	pthread_t self;
    311 
    312 	self = pthread__self();
    313 	TESTCANCEL(self);
    314 	retval = _sys___kevent100(fd, ev, nev, rev, nrev, ts);
    315 	TESTCANCEL(self);
    316 
    317 	return retval;
    318 }
    319 
    320 ssize_t
    321 mq_receive(mqd_t mqdes, char *msg_ptr, size_t msg_len, unsigned *msg_prio)
    322 {
    323 	ssize_t retval;
    324 	pthread_t self;
    325 
    326 	self = pthread__self();
    327 	TESTCANCEL(self);
    328 	retval = _sys_mq_receive(mqdes, msg_ptr, msg_len, msg_prio);
    329 	TESTCANCEL(self);
    330 
    331 	return retval;
    332 }
    333 
    334 int
    335 mq_send(mqd_t mqdes, const char *msg_ptr, size_t msg_len, unsigned msg_prio)
    336 {
    337 	int retval;
    338 	pthread_t self;
    339 
    340 	self = pthread__self();
    341 	TESTCANCEL(self);
    342 	retval = _sys_mq_send(mqdes, msg_ptr, msg_len, msg_prio);
    343 	TESTCANCEL(self);
    344 
    345 	return retval;
    346 }
    347 
    348 ssize_t
    349 __mq_timedreceive50(mqd_t mqdes, char *msg_ptr, size_t msg_len,
    350     unsigned *msg_prio, const struct timespec *abst)
    351 {
    352 	ssize_t retval;
    353 	pthread_t self;
    354 
    355 	self = pthread__self();
    356 	TESTCANCEL(self);
    357 	retval = _sys___mq_timedreceive50(mqdes, msg_ptr, msg_len, msg_prio,
    358 	    abst);
    359 	TESTCANCEL(self);
    360 
    361 	return retval;
    362 }
    363 
    364 int
    365 __mq_timedsend50(mqd_t mqdes, const char *msg_ptr, size_t msg_len,
    366     unsigned msg_prio, const struct timespec *abst)
    367 {
    368 	int retval;
    369 	pthread_t self;
    370 
    371 	self = pthread__self();
    372 	TESTCANCEL(self);
    373 	retval = _sys___mq_timedsend50(mqdes, msg_ptr, msg_len, msg_prio,
    374 	    abst);
    375 	TESTCANCEL(self);
    376 
    377 	return retval;
    378 }
    379 
    380 ssize_t
    381 msgrcv(int msgid, void *msgp, size_t msgsz, long msgtyp, int msgflg)
    382 {
    383 	ssize_t retval;
    384 	pthread_t self;
    385 
    386 	self = pthread__self();
    387 	TESTCANCEL(self);
    388 	retval = _sys_msgrcv(msgid, msgp, msgsz, msgtyp, msgflg);
    389 	TESTCANCEL(self);
    390 
    391 	return retval;
    392 }
    393 
    394 int
    395 msgsnd(int msgid, const void *msgp, size_t msgsz, int msgflg)
    396 {
    397 	int retval;
    398 	pthread_t self;
    399 
    400 	self = pthread__self();
    401 	TESTCANCEL(self);
    402 	retval = _sys_msgsnd(msgid, msgp, msgsz, msgflg);
    403 	TESTCANCEL(self);
    404 
    405 	return retval;
    406 }
    407 
    408 int
    409 __msync13(void *addr, size_t len, int flags)
    410 {
    411 	int retval;
    412 	pthread_t self;
    413 
    414 	self = pthread__self();
    415 	TESTCANCEL(self);
    416 	retval = _sys___msync13(addr, len, flags);
    417 	TESTCANCEL(self);
    418 
    419 	return retval;
    420 }
    421 
    422 int
    423 __nanosleep50(const struct timespec *rqtp, struct timespec *rmtp)
    424 {
    425 	int retval;
    426 	pthread_t self;
    427 
    428 	self = pthread__self();
    429 	TESTCANCEL(self);
    430 	/*
    431 	 * For now, just nanosleep.  In the future, maybe pass a ucontext_t
    432 	 * to _lwp_nanosleep() and allow it to recycle our kernel stack.
    433 	 */
    434 	retval = _sys___nanosleep50(rqtp, rmtp);
    435 	TESTCANCEL(self);
    436 
    437 	return retval;
    438 }
    439 
    440 int
    441 open(const char *path, int flags, ...)
    442 {
    443 	int retval;
    444 	pthread_t self;
    445 	va_list ap;
    446 
    447 	self = pthread__self();
    448 	TESTCANCEL(self);
    449 	va_start(ap, flags);
    450 	retval = _sys_open(path, flags, va_arg(ap, mode_t));
    451 	va_end(ap);
    452 	TESTCANCEL(self);
    453 
    454 	return retval;
    455 }
    456 
    457 int
    458 openat(int fd, const char *path, int flags, ...)
    459 {
    460 	int retval;
    461 	pthread_t self;
    462 	va_list ap;
    463 
    464 	self = pthread__self();
    465 	TESTCANCEL(self);
    466 	va_start(ap, flags);
    467 	retval = _sys_openat(fd, path, flags, va_arg(ap, mode_t));
    468 	va_end(ap);
    469 	TESTCANCEL(self);
    470 
    471 	return retval;
    472 }
    473 
    474 int
    475 poll(struct pollfd *fds, nfds_t nfds, int timeout)
    476 {
    477 	int retval;
    478 	pthread_t self;
    479 
    480 	self = pthread__self();
    481 	TESTCANCEL(self);
    482 	retval = _sys_poll(fds, nfds, timeout);
    483 	TESTCANCEL(self);
    484 
    485 	return retval;
    486 }
    487 
    488 int
    489 __pollts50(struct pollfd *fds, nfds_t nfds, const struct timespec *ts,
    490     const sigset_t *sigmask)
    491 {
    492 	int retval;
    493 	pthread_t self;
    494 
    495 	self = pthread__self();
    496 	TESTCANCEL(self);
    497 	retval = _sys___pollts50(fds, nfds, ts, sigmask);
    498 	TESTCANCEL(self);
    499 
    500 	return retval;
    501 }
    502 
    503 ssize_t
    504 pread(int d, void *buf, size_t nbytes, off_t offset)
    505 {
    506 	ssize_t retval;
    507 	pthread_t self;
    508 
    509 	self = pthread__self();
    510 	TESTCANCEL(self);
    511 	retval = _sys_pread(d, buf, nbytes, offset);
    512 	TESTCANCEL(self);
    513 
    514 	return retval;
    515 }
    516 
    517 int
    518 __pselect50(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
    519     const struct timespec *timeout, const sigset_t *sigmask)
    520 {
    521 	int retval;
    522 	pthread_t self;
    523 
    524 	self = pthread__self();
    525 	TESTCANCEL(self);
    526 	retval = _sys___pselect50(nfds, readfds, writefds, exceptfds, timeout,
    527 	    sigmask);
    528 	TESTCANCEL(self);
    529 
    530 	return retval;
    531 }
    532 
    533 ssize_t
    534 pwrite(int d, const void *buf, size_t nbytes, off_t offset)
    535 {
    536 	ssize_t retval;
    537 	pthread_t self;
    538 
    539 	self = pthread__self();
    540 	TESTCANCEL(self);
    541 	retval = _sys_pwrite(d, buf, nbytes, offset);
    542 	TESTCANCEL(self);
    543 
    544 	return retval;
    545 }
    546 
    547 ssize_t
    548 read(int d, void *buf, size_t nbytes)
    549 {
    550 	ssize_t retval;
    551 	pthread_t self;
    552 
    553 	self = pthread__self();
    554 	TESTCANCEL(self);
    555 	retval = _sys_read(d, buf, nbytes);
    556 	TESTCANCEL(self);
    557 
    558 	return retval;
    559 }
    560 
    561 ssize_t
    562 readv(int d, const struct iovec *iov, int iovcnt)
    563 {
    564 	ssize_t retval;
    565 	pthread_t self;
    566 
    567 	self = pthread__self();
    568 	TESTCANCEL(self);
    569 	retval = _sys_readv(d, iov, iovcnt);
    570 	TESTCANCEL(self);
    571 
    572 	return retval;
    573 }
    574 
    575 ssize_t
    576 recvfrom(int s, void * restrict buf, size_t len, int flags,
    577     struct sockaddr * restrict from, socklen_t * restrict fromlen)
    578 {
    579 	ssize_t retval;
    580 	pthread_t self;
    581 
    582 	self = pthread__self();
    583 	TESTCANCEL(self);
    584 	retval = _sys_recvfrom(s, buf, len, flags, from, fromlen);
    585 	TESTCANCEL(self);
    586 
    587 	return retval;
    588 }
    589 
    590 int
    591 recvmmsg(int s, struct mmsghdr *mmsg, unsigned int vlen,
    592     unsigned int flags, struct timespec *timeout)
    593 {
    594 	ssize_t retval;
    595 	pthread_t self;
    596 
    597 	self = pthread__self();
    598 	TESTCANCEL(self);
    599 	retval = _sys_recvmmsg(s, mmsg, vlen, flags, timeout);
    600 	TESTCANCEL(self);
    601 
    602 	return retval;
    603 }
    604 
    605 ssize_t
    606 recvmsg(int s, struct msghdr *msg, int flags)
    607 {
    608 	ssize_t retval;
    609 	pthread_t self;
    610 
    611 	self = pthread__self();
    612 	TESTCANCEL(self);
    613 	retval = _sys_recvmsg(s, msg, flags);
    614 	TESTCANCEL(self);
    615 
    616 	return retval;
    617 }
    618 
    619 int
    620 __select50(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
    621     struct timeval *timeout)
    622 {
    623 	int retval;
    624 	pthread_t self;
    625 
    626 	self = pthread__self();
    627 	TESTCANCEL(self);
    628 	retval = _sys___select50(nfds, readfds, writefds, exceptfds, timeout);
    629 	TESTCANCEL(self);
    630 
    631 	return retval;
    632 }
    633 
    634 int
    635 sendmmsg(int s, struct mmsghdr *mmsg, unsigned int vlen,
    636     unsigned int flags)
    637 {
    638 	int retval;
    639 	pthread_t self;
    640 
    641 	self = pthread__self();
    642 	TESTCANCEL(self);
    643 	retval = _sys_sendmmsg(s, mmsg, vlen, flags);
    644 	TESTCANCEL(self);
    645 
    646 	return retval;
    647 }
    648 
    649 ssize_t
    650 sendmsg(int s, const struct msghdr *msg, int flags)
    651 {
    652 	int retval;
    653 	pthread_t self;
    654 
    655 	self = pthread__self();
    656 	TESTCANCEL(self);
    657 	retval = _sys_sendmsg(s, msg, flags);
    658 	TESTCANCEL(self);
    659 
    660 	return retval;
    661 }
    662 
    663 ssize_t
    664 sendto(int s, const void *msg, size_t len, int flags,
    665     const struct sockaddr *to, socklen_t tolen)
    666 {
    667 	int retval;
    668 	pthread_t self;
    669 
    670 	self = pthread__self();
    671 	TESTCANCEL(self);
    672 	retval = _sys_sendto(s, msg, len, flags, to, tolen);
    673 	TESTCANCEL(self);
    674 
    675 	return retval;
    676 }
    677 
    678 int
    679 __sigsuspend14(const sigset_t *sigmask)
    680 {
    681 	pthread_t self;
    682 	int retval;
    683 
    684 	self = pthread__self();
    685 	TESTCANCEL(self);
    686 	retval = _sys___sigsuspend14(sigmask);
    687 	TESTCANCEL(self);
    688 
    689 	return retval;
    690 }
    691 
    692 int
    693 __sigtimedwait50(const sigset_t * restrict set, siginfo_t * restrict info,
    694     const struct timespec * restrict timeout)
    695 {
    696 	pthread_t self;
    697 	int retval;
    698 	struct timespec tout, *tp;
    699 
    700 	if (timeout) {
    701 		tout = *timeout;
    702 		tp = &tout;
    703 	} else
    704 		tp = NULL;
    705 
    706 	self = pthread__self();
    707 	TESTCANCEL(self);
    708 	retval = ____sigtimedwait50(set, info, tp);
    709 	TESTCANCEL(self);
    710 
    711 	return retval;
    712 }
    713 
    714 int
    715 sigwait(const sigset_t * restrict set, int * restrict sig)
    716 {
    717 	pthread_t	self;
    718 	int		saved_errno;
    719 	int		new_errno;
    720 	int		retval;
    721 
    722 	self = pthread__self();
    723 	saved_errno = errno;
    724 	TESTCANCEL(self);
    725 	retval = ____sigtimedwait50(set, NULL, NULL);
    726 	TESTCANCEL(self);
    727 	new_errno = errno;
    728 	errno = saved_errno;
    729 	if (retval < 0) {
    730 		return new_errno;
    731 	}
    732 	*sig = retval;
    733 	return 0;
    734 }
    735 
    736 int
    737 tcdrain(int fd)
    738 {
    739 	int retval;
    740 	pthread_t self;
    741 
    742 	self = pthread__self();
    743 	TESTCANCEL(self);
    744 	retval = ioctl(fd, TIOCDRAIN, 0);
    745 	TESTCANCEL(self);
    746 
    747 	return retval;
    748 }
    749 
    750 pid_t
    751 __wait450(pid_t wpid, int *status, int options, struct rusage *rusage)
    752 {
    753 	pid_t retval;
    754 	pthread_t self;
    755 
    756 	self = pthread__self();
    757 	TESTCANCEL(self);
    758 	retval = _sys___wait450(wpid, status, options, rusage);
    759 	TESTCANCEL(self);
    760 
    761 	return retval;
    762 }
    763 
    764 ssize_t
    765 write(int d, const void *buf, size_t nbytes)
    766 {
    767 	ssize_t retval;
    768 	pthread_t self;
    769 
    770 	self = pthread__self();
    771 	TESTCANCEL(self);
    772 	retval = _sys_write(d, buf, nbytes);
    773 	TESTCANCEL(self);
    774 
    775 	return retval;
    776 }
    777 
    778 ssize_t
    779 writev(int d, const struct iovec *iov, int iovcnt)
    780 {
    781 	ssize_t retval;
    782 	pthread_t self;
    783 
    784 	self = pthread__self();
    785 	TESTCANCEL(self);
    786 	retval = _sys_writev(d, iov, iovcnt);
    787 	TESTCANCEL(self);
    788 
    789 	return retval;
    790 }
    791 
    792 __strong_alias(_clock_nanosleep, clock_nanosleep)
    793 __strong_alias(_close, close)
    794 __strong_alias(_fcntl, fcntl)
    795 __strong_alias(_fdatasync, fdatasync)
    796 __strong_alias(_fsync, fsync)
    797 __weak_alias(fsync_range, _fsync_range)
    798 __strong_alias(_mq_receive, mq_receive)
    799 __strong_alias(_mq_send, mq_send)
    800 __strong_alias(_msgrcv, msgrcv)
    801 __strong_alias(_msgsnd, msgsnd)
    802 __strong_alias(___msync13, __msync13)
    803 __strong_alias(___nanosleep50, __nanosleep50)
    804 __strong_alias(_open, open)
    805 __strong_alias(_openat, openat)
    806 __strong_alias(_poll, poll)
    807 __strong_alias(_pread, pread)
    808 __strong_alias(_pwrite, pwrite)
    809 __strong_alias(_read, read)
    810 __strong_alias(_readv, readv)
    811 __strong_alias(_recvfrom, recvfrom)
    812 __strong_alias(_recvmmsg, recvmmsg)
    813 __strong_alias(_recvmsg, recvmsg)
    814 __strong_alias(_sendmmsg, sendmmsg)
    815 __strong_alias(_sendmsg, sendmsg)
    816 __strong_alias(_sendto, sendto)
    817 __strong_alias(_sigwait, sigwait)
    818 __strong_alias(_write, write)
    819 __strong_alias(_writev, writev)
    820 
    821 #endif	/* !lint */
    822