1 /* $NetBSD: pthread_cancelstub.c,v 1.16 2007/11/19 15:12:18 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 * 3. All advertising materials mentioning features or use of this software 19 * must display the following acknowledgement: 20 * This product includes software developed by the NetBSD 21 * Foundation, Inc. and its contributors. 22 * 4. Neither the name of The NetBSD Foundation nor the names of its 23 * contributors may be used to endorse or promote products derived 24 * from this software without specific prior written permission. 25 * 26 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 27 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 28 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 29 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 30 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 31 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 32 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 33 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 34 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 35 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 36 * POSSIBILITY OF SUCH DAMAGE. 37 */ 38 39 #include <sys/cdefs.h> 40 __RCSID("$NetBSD: pthread_cancelstub.c,v 1.16 2007/11/19 15:12:18 ad Exp $"); 41 42 /* 43 * This is necessary because the names are always weak (they are not 44 * POSIX functions). 45 */ 46 #define fsync_range _fsync_range 47 #define pollts _pollts 48 49 /* 50 * XXX this is necessary to get the prototypes for the __sigsuspend14 51 * XXX and __msync13 internal names, instead of the application-visible 52 * XXX sigsuspend and msync names. It's kind of gross, but we're pretty 53 * XXX intimate with libc already. 54 */ 55 #define __LIBC12_SOURCE__ 56 57 #include <sys/msg.h> 58 #include <sys/types.h> 59 #include <sys/uio.h> 60 #include <sys/wait.h> 61 #include <aio.h> 62 #include <fcntl.h> 63 #include <mqueue.h> 64 #include <poll.h> 65 #include <stdarg.h> 66 #include <unistd.h> 67 68 #include <signal.h> 69 #include <sys/mman.h> 70 #include <sys/select.h> 71 #include <sys/socket.h> 72 73 #include <compat/sys/mman.h> 74 75 #include "pthread.h" 76 #include "pthread_int.h" 77 78 int pthread__cancel_stub_binder; 79 80 int _sys_accept(int, struct sockaddr *, socklen_t *); 81 int _sys_aio_suspend(const struct aiocb * const [], int, 82 const struct timespec *); 83 int _sys_close(int); 84 int _sys_connect(int, const struct sockaddr *, socklen_t); 85 int _sys_fcntl(int, int, ...); 86 int _sys_fdatasync(int); 87 int _sys_fsync(int); 88 int _sys_fsync_range(int, int, off_t, off_t); 89 int _sys_mq_send(mqd_t, const char *, size_t, unsigned); 90 ssize_t _sys_mq_receive(mqd_t, char *, size_t, unsigned *); 91 int _sys_mq_timedsend(mqd_t, const char *, size_t, unsigned, 92 const struct timespec *); 93 ssize_t _sys_mq_timedreceive(mqd_t, char *, size_t, unsigned *, 94 const struct timespec *); 95 ssize_t _sys_msgrcv(int, void *, size_t, long, int); 96 int _sys_msgsnd(int, const void *, size_t, int); 97 int _sys___msync13(void *, size_t, int); 98 int _sys_open(const char *, int, ...); 99 int _sys_poll(struct pollfd *, nfds_t, int); 100 int _sys_pollts(struct pollfd *, nfds_t, const struct timespec *, 101 const sigset_t *); 102 ssize_t _sys_pread(int, void *, size_t, off_t); 103 int _sys_pselect(int, fd_set *, fd_set *, fd_set *, 104 const struct timespec *, const sigset_t *); 105 ssize_t _sys_pwrite(int, const void *, size_t, off_t); 106 ssize_t _sys_read(int, void *, size_t); 107 ssize_t _sys_readv(int, const struct iovec *, int); 108 int _sys_select(int, fd_set *, fd_set *, fd_set *, struct timeval *); 109 int _sys_wait4(pid_t, int *, int, struct rusage *); 110 ssize_t _sys_write(int, const void *, size_t); 111 ssize_t _sys_writev(int, const struct iovec *, int); 112 int _sys___sigsuspend14(const sigset_t *); 113 int _sigtimedwait(const sigset_t * __restrict, siginfo_t * __restrict, 114 const struct timespec * __restrict); 115 int __sigsuspend14(const sigset_t *); 116 117 #define TESTCANCEL(id) do { \ 118 if (__predict_false((id)->pt_cancel)) \ 119 pthread_exit(PTHREAD_CANCELED); \ 120 } while (/*CONSTCOND*/0) 121 122 123 int 124 accept(int s, struct sockaddr *addr, socklen_t *addrlen) 125 { 126 int retval; 127 pthread_t self; 128 129 self = pthread__self(); 130 TESTCANCEL(self); 131 retval = _sys_accept(s, addr, addrlen); 132 TESTCANCEL(self); 133 134 return retval; 135 } 136 137 int 138 aio_suspend(const struct aiocb * const list[], int nent, 139 const struct timespec *timeout) 140 { 141 int retval; 142 pthread_t self; 143 144 self = pthread__self(); 145 TESTCANCEL(self); 146 retval = _sys_aio_suspend(list, nent, timeout); 147 TESTCANCEL(self); 148 149 return retval; 150 } 151 152 int 153 close(int d) 154 { 155 int retval; 156 pthread_t self; 157 158 self = pthread__self(); 159 TESTCANCEL(self); 160 retval = _sys_close(d); 161 TESTCANCEL(self); 162 163 return retval; 164 } 165 166 int 167 connect(int s, const struct sockaddr *addr, socklen_t namelen) 168 { 169 int retval; 170 pthread_t self; 171 172 self = pthread__self(); 173 TESTCANCEL(self); 174 retval = _sys_connect(s, addr, namelen); 175 TESTCANCEL(self); 176 177 return retval; 178 } 179 180 int 181 fcntl(int fd, int cmd, ...) 182 { 183 int retval; 184 pthread_t self; 185 va_list ap; 186 187 self = pthread__self(); 188 TESTCANCEL(self); 189 va_start(ap, cmd); 190 retval = _sys_fcntl(fd, cmd, va_arg(ap, void *)); 191 va_end(ap); 192 TESTCANCEL(self); 193 194 return retval; 195 } 196 197 int 198 fdatasync(int d) 199 { 200 int retval; 201 pthread_t self; 202 203 self = pthread__self(); 204 TESTCANCEL(self); 205 retval = _sys_fdatasync(d); 206 TESTCANCEL(self); 207 208 return retval; 209 } 210 211 int 212 fsync(int d) 213 { 214 int retval; 215 pthread_t self; 216 217 self = pthread__self(); 218 TESTCANCEL(self); 219 retval = _sys_fsync(d); 220 TESTCANCEL(self); 221 222 return retval; 223 } 224 225 int 226 fsync_range(int d, int f, off_t s, off_t e) 227 { 228 int retval; 229 pthread_t self; 230 231 self = pthread__self(); 232 TESTCANCEL(self); 233 retval = _sys_fsync_range(d, f, s, e); 234 TESTCANCEL(self); 235 236 return retval; 237 } 238 239 int 240 mq_send(mqd_t mqdes, const char *msg_ptr, size_t msg_len, unsigned msg_prio) 241 { 242 int retval; 243 pthread_t self; 244 245 self = pthread__self(); 246 TESTCANCEL(self); 247 retval = _sys_mq_send(mqdes, msg_ptr, msg_len, msg_prio); 248 TESTCANCEL(self); 249 250 return retval; 251 } 252 253 ssize_t 254 mq_receive(mqd_t mqdes, char *msg_ptr, size_t msg_len, unsigned *msg_prio) 255 { 256 ssize_t retval; 257 pthread_t self; 258 259 self = pthread__self(); 260 TESTCANCEL(self); 261 retval = _sys_mq_receive(mqdes, msg_ptr, msg_len, msg_prio); 262 TESTCANCEL(self); 263 264 return retval; 265 } 266 267 int 268 mq_timedsend(mqd_t mqdes, const char *msg_ptr, size_t msg_len, 269 unsigned msg_prio, const struct timespec *abst) 270 { 271 int retval; 272 pthread_t self; 273 274 self = pthread__self(); 275 TESTCANCEL(self); 276 retval = _sys_mq_timedsend(mqdes, msg_ptr, msg_len, msg_prio, abst); 277 TESTCANCEL(self); 278 279 return retval; 280 } 281 282 ssize_t 283 mq_timedreceive(mqd_t mqdes, char *msg_ptr, size_t msg_len, unsigned *msg_prio, 284 const struct timespec *abst) 285 { 286 ssize_t retval; 287 pthread_t self; 288 289 self = pthread__self(); 290 TESTCANCEL(self); 291 retval = _sys_mq_timedreceive(mqdes, msg_ptr, msg_len, msg_prio, abst); 292 TESTCANCEL(self); 293 294 return retval; 295 } 296 297 ssize_t 298 msgrcv(int msgid, void *msgp, size_t msgsz, long msgtyp, int msgflg) 299 { 300 ssize_t retval; 301 pthread_t self; 302 303 self = pthread__self(); 304 TESTCANCEL(self); 305 retval = _sys_msgrcv(msgid, msgp, msgsz, msgtyp, msgflg); 306 TESTCANCEL(self); 307 308 return retval; 309 } 310 311 int 312 msgsnd(int msgid, const void *msgp, size_t msgsz, int msgflg) 313 { 314 int retval; 315 pthread_t self; 316 317 self = pthread__self(); 318 TESTCANCEL(self); 319 retval = _sys_msgsnd(msgid, msgp, msgsz, msgflg); 320 TESTCANCEL(self); 321 322 return retval; 323 } 324 325 int 326 __msync13(void *addr, size_t len, int flags) 327 { 328 int retval; 329 pthread_t self; 330 331 self = pthread__self(); 332 TESTCANCEL(self); 333 retval = _sys___msync13(addr, len, flags); 334 TESTCANCEL(self); 335 336 return retval; 337 } 338 339 int 340 open(const char *path, int flags, ...) 341 { 342 int retval; 343 pthread_t self; 344 va_list ap; 345 346 self = pthread__self(); 347 TESTCANCEL(self); 348 va_start(ap, flags); 349 retval = _sys_open(path, flags, va_arg(ap, mode_t)); 350 va_end(ap); 351 TESTCANCEL(self); 352 353 return retval; 354 } 355 356 int 357 poll(struct pollfd *fds, nfds_t nfds, int timeout) 358 { 359 int retval; 360 pthread_t self; 361 362 self = pthread__self(); 363 TESTCANCEL(self); 364 retval = _sys_poll(fds, nfds, timeout); 365 TESTCANCEL(self); 366 367 return retval; 368 } 369 370 int 371 pollts(struct pollfd *fds, nfds_t nfds, const struct timespec *ts, 372 const sigset_t *sigmask) 373 { 374 int retval; 375 pthread_t self; 376 377 self = pthread__self(); 378 TESTCANCEL(self); 379 retval = _sys_pollts(fds, nfds, ts, sigmask); 380 TESTCANCEL(self); 381 382 return retval; 383 } 384 385 ssize_t 386 pread(int d, void *buf, size_t nbytes, off_t offset) 387 { 388 ssize_t retval; 389 pthread_t self; 390 391 self = pthread__self(); 392 TESTCANCEL(self); 393 retval = _sys_pread(d, buf, nbytes, offset); 394 TESTCANCEL(self); 395 396 return retval; 397 } 398 399 int 400 pselect(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, 401 const struct timespec *timeout, const sigset_t *sigmask) 402 { 403 int retval; 404 pthread_t self; 405 406 self = pthread__self(); 407 TESTCANCEL(self); 408 retval = _sys_pselect(nfds, readfds, writefds, exceptfds, timeout, 409 sigmask); 410 TESTCANCEL(self); 411 412 return retval; 413 } 414 415 ssize_t 416 pwrite(int d, const void *buf, size_t nbytes, off_t offset) 417 { 418 ssize_t retval; 419 pthread_t self; 420 421 self = pthread__self(); 422 TESTCANCEL(self); 423 retval = _sys_pwrite(d, buf, nbytes, offset); 424 TESTCANCEL(self); 425 426 return retval; 427 } 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