1 /* $NetBSD: pthread_cancelstub.c,v 1.37 2012/04/04 17:47:03 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 /* 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.37 2012/04/04 17:47:03 christos Exp $"); 37 38 #ifndef lint 39 40 41 /* 42 * This is necessary because the names are always weak (they are not 43 * POSIX functions). 44 */ 45 #define fsync_range _fsync_range 46 #define pollts _pollts 47 48 /* 49 * XXX this is necessary to get the prototypes for the __sigsuspend14 50 * XXX and __msync13 internal names, instead of the application-visible 51 * XXX sigsuspend and msync names. It's kind of gross, but we're pretty 52 * XXX intimate with libc already. 53 */ 54 #define __LIBC12_SOURCE__ 55 56 #include <sys/msg.h> 57 #include <sys/types.h> 58 #include <sys/uio.h> 59 #include <sys/wait.h> 60 #include <aio.h> 61 #include <errno.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 #include <sys/event.h> 73 74 #include <compat/sys/mman.h> 75 #include <compat/sys/poll.h> 76 #include <compat/sys/select.h> 77 #include <compat/sys/event.h> 78 #include <compat/sys/wait.h> 79 #include <compat/include/mqueue.h> 80 #include <compat/include/signal.h> 81 82 #include "pthread.h" 83 #include "pthread_int.h" 84 85 int pthread__cancel_stub_binder; 86 87 int _sys_accept(int, struct sockaddr *, socklen_t *); 88 int _sys___aio_suspend50(const struct aiocb * const [], int, 89 const struct timespec *); 90 int __aio_suspend50(const struct aiocb * const [], int, 91 const struct timespec *); 92 int _sys_close(int); 93 int _sys_connect(int, const struct sockaddr *, socklen_t); 94 int _sys_fcntl(int, int, ...); 95 int _sys_fdatasync(int); 96 int _sys_fsync(int); 97 int _sys_fsync_range(int, int, off_t, off_t); 98 int _sys___kevent50(int, const struct kevent *, size_t, struct kevent *, 99 size_t, const struct timespec *); 100 int _sys_mq_send(mqd_t, const char *, size_t, unsigned); 101 ssize_t _sys_mq_receive(mqd_t, char *, size_t, unsigned *); 102 int _sys___mq_timedsend50(mqd_t, const char *, size_t, unsigned, 103 const struct timespec *); 104 ssize_t _sys___mq_timedreceive50(mqd_t, char *, size_t, unsigned *, 105 const struct timespec *); 106 ssize_t _sys_msgrcv(int, void *, size_t, long, int); 107 int _sys_msgsnd(int, const void *, size_t, int); 108 int _sys___msync13(void *, size_t, int); 109 int _sys___nanosleep50(const struct timespec *, struct timespec *); 110 int __nanosleep50(const struct timespec *, struct timespec *); 111 int _sys_open(const char *, int, ...); 112 int _sys_poll(struct pollfd *, nfds_t, int); 113 int _sys___pollts50(struct pollfd *, nfds_t, const struct timespec *, 114 const sigset_t *); 115 ssize_t _sys_pread(int, void *, size_t, off_t); 116 int _sys___pselect50(int, fd_set *, fd_set *, fd_set *, 117 const struct timespec *, const sigset_t *); 118 ssize_t _sys_pwrite(int, const void *, size_t, off_t); 119 ssize_t _sys_read(int, void *, size_t); 120 ssize_t _sys_readv(int, const struct iovec *, int); 121 int _sys___select50(int, fd_set *, fd_set *, fd_set *, struct timeval *); 122 int _sys___wait450(pid_t, int *, int, struct rusage *); 123 ssize_t _sys_write(int, const void *, size_t); 124 ssize_t _sys_writev(int, const struct iovec *, int); 125 int _sys___sigsuspend14(const sigset_t *); 126 int ____sigtimedwait50(const sigset_t * __restrict, siginfo_t * __restrict, 127 struct timespec * __restrict); 128 int __sigsuspend14(const sigset_t *); 129 130 #define TESTCANCEL(id) do { \ 131 if (__predict_false((id)->pt_cancel)) \ 132 pthread__cancelled(); \ 133 } while (/*CONSTCOND*/0) 134 135 136 int 137 accept(int s, struct sockaddr *addr, socklen_t *addrlen) 138 { 139 int retval; 140 pthread_t self; 141 142 self = pthread__self(); 143 TESTCANCEL(self); 144 retval = _sys_accept(s, addr, addrlen); 145 TESTCANCEL(self); 146 147 return retval; 148 } 149 150 int 151 __aio_suspend50(const struct aiocb * const list[], int nent, 152 const struct timespec *timeout) 153 { 154 int retval; 155 pthread_t self; 156 157 self = pthread__self(); 158 TESTCANCEL(self); 159 retval = _sys___aio_suspend50(list, nent, timeout); 160 TESTCANCEL(self); 161 162 return retval; 163 } 164 165 int 166 __kevent50(int fd, const struct kevent *ev, size_t nev, struct kevent *rev, 167 size_t nrev, const struct timespec *ts) 168 { 169 int retval; 170 pthread_t self; 171 172 self = pthread__self(); 173 TESTCANCEL(self); 174 retval = _sys___kevent50(fd, ev, nev, rev, nrev, ts); 175 TESTCANCEL(self); 176 177 return retval; 178 } 179 180 int 181 close(int d) 182 { 183 int retval; 184 pthread_t self; 185 186 self = pthread__self(); 187 TESTCANCEL(self); 188 retval = _sys_close(d); 189 TESTCANCEL(self); 190 191 return retval; 192 } 193 194 int 195 connect(int s, const struct sockaddr *addr, socklen_t namelen) 196 { 197 int retval; 198 pthread_t self; 199 200 self = pthread__self(); 201 TESTCANCEL(self); 202 retval = _sys_connect(s, addr, namelen); 203 TESTCANCEL(self); 204 205 return retval; 206 } 207 208 int 209 fcntl(int fd, int cmd, ...) 210 { 211 int retval; 212 pthread_t self; 213 va_list ap; 214 215 self = pthread__self(); 216 TESTCANCEL(self); 217 va_start(ap, cmd); 218 retval = _sys_fcntl(fd, cmd, va_arg(ap, void *)); 219 va_end(ap); 220 TESTCANCEL(self); 221 222 return retval; 223 } 224 225 int 226 fdatasync(int d) 227 { 228 int retval; 229 pthread_t self; 230 231 self = pthread__self(); 232 TESTCANCEL(self); 233 retval = _sys_fdatasync(d); 234 TESTCANCEL(self); 235 236 return retval; 237 } 238 239 int 240 fsync(int d) 241 { 242 int retval; 243 pthread_t self; 244 245 self = pthread__self(); 246 TESTCANCEL(self); 247 retval = _sys_fsync(d); 248 TESTCANCEL(self); 249 250 return retval; 251 } 252 253 int 254 fsync_range(int d, int f, off_t s, off_t e) 255 { 256 int retval; 257 pthread_t self; 258 259 self = pthread__self(); 260 TESTCANCEL(self); 261 retval = _sys_fsync_range(d, f, s, e); 262 TESTCANCEL(self); 263 264 return retval; 265 } 266 267 int 268 mq_send(mqd_t mqdes, const char *msg_ptr, size_t msg_len, unsigned msg_prio) 269 { 270 int retval; 271 pthread_t self; 272 273 self = pthread__self(); 274 TESTCANCEL(self); 275 retval = _sys_mq_send(mqdes, msg_ptr, msg_len, msg_prio); 276 TESTCANCEL(self); 277 278 return retval; 279 } 280 281 ssize_t 282 mq_receive(mqd_t mqdes, char *msg_ptr, size_t msg_len, unsigned *msg_prio) 283 { 284 ssize_t retval; 285 pthread_t self; 286 287 self = pthread__self(); 288 TESTCANCEL(self); 289 retval = _sys_mq_receive(mqdes, msg_ptr, msg_len, msg_prio); 290 TESTCANCEL(self); 291 292 return retval; 293 } 294 295 int 296 __mq_timedsend50(mqd_t mqdes, const char *msg_ptr, size_t msg_len, 297 unsigned msg_prio, const struct timespec *abst) 298 { 299 int retval; 300 pthread_t self; 301 302 self = pthread__self(); 303 TESTCANCEL(self); 304 retval = _sys___mq_timedsend50(mqdes, msg_ptr, msg_len, msg_prio, abst); 305 TESTCANCEL(self); 306 307 return retval; 308 } 309 310 ssize_t 311 __mq_timedreceive50(mqd_t mqdes, char *msg_ptr, size_t msg_len, unsigned *msg_prio, 312 const struct timespec *abst) 313 { 314 ssize_t retval; 315 pthread_t self; 316 317 self = pthread__self(); 318 TESTCANCEL(self); 319 retval = _sys___mq_timedreceive50(mqdes, msg_ptr, msg_len, msg_prio, abst); 320 TESTCANCEL(self); 321 322 return retval; 323 } 324 325 ssize_t 326 msgrcv(int msgid, void *msgp, size_t msgsz, long msgtyp, int msgflg) 327 { 328 ssize_t retval; 329 pthread_t self; 330 331 self = pthread__self(); 332 TESTCANCEL(self); 333 retval = _sys_msgrcv(msgid, msgp, msgsz, msgtyp, msgflg); 334 TESTCANCEL(self); 335 336 return retval; 337 } 338 339 int 340 msgsnd(int msgid, const void *msgp, size_t msgsz, int msgflg) 341 { 342 int retval; 343 pthread_t self; 344 345 self = pthread__self(); 346 TESTCANCEL(self); 347 retval = _sys_msgsnd(msgid, msgp, msgsz, msgflg); 348 TESTCANCEL(self); 349 350 return retval; 351 } 352 353 int 354 __msync13(void *addr, size_t len, int flags) 355 { 356 int retval; 357 pthread_t self; 358 359 self = pthread__self(); 360 TESTCANCEL(self); 361 retval = _sys___msync13(addr, len, flags); 362 TESTCANCEL(self); 363 364 return retval; 365 } 366 367 int 368 open(const char *path, int flags, ...) 369 { 370 int retval; 371 pthread_t self; 372 va_list ap; 373 374 self = pthread__self(); 375 TESTCANCEL(self); 376 va_start(ap, flags); 377 retval = _sys_open(path, flags, va_arg(ap, mode_t)); 378 va_end(ap); 379 TESTCANCEL(self); 380 381 return retval; 382 } 383 384 int 385 __nanosleep50(const struct timespec *rqtp, struct timespec *rmtp) 386 { 387 int retval; 388 pthread_t self; 389 390 self = pthread__self(); 391 TESTCANCEL(self); 392 /* 393 * For now, just nanosleep. In the future, maybe pass a ucontext_t 394 * to _lwp_nanosleep() and allow it to recycle our kernel stack. 395 */ 396 retval = _sys___nanosleep50(rqtp, rmtp); 397 TESTCANCEL(self); 398 399 return retval; 400 } 401 402 int 403 poll(struct pollfd *fds, nfds_t nfds, int timeout) 404 { 405 int retval; 406 pthread_t self; 407 408 self = pthread__self(); 409 TESTCANCEL(self); 410 retval = _sys_poll(fds, nfds, timeout); 411 TESTCANCEL(self); 412 413 return retval; 414 } 415 416 int 417 __pollts50(struct pollfd *fds, nfds_t nfds, const struct timespec *ts, 418 const sigset_t *sigmask) 419 { 420 int retval; 421 pthread_t self; 422 423 self = pthread__self(); 424 TESTCANCEL(self); 425 retval = _sys___pollts50(fds, nfds, ts, sigmask); 426 TESTCANCEL(self); 427 428 return retval; 429 } 430 431 ssize_t 432 pread(int d, void *buf, size_t nbytes, off_t offset) 433 { 434 ssize_t retval; 435 pthread_t self; 436 437 self = pthread__self(); 438 TESTCANCEL(self); 439 retval = _sys_pread(d, buf, nbytes, offset); 440 TESTCANCEL(self); 441 442 return retval; 443 } 444 445 int 446 __pselect50(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, 447 const struct timespec *timeout, const sigset_t *sigmask) 448 { 449 int retval; 450 pthread_t self; 451 452 self = pthread__self(); 453 TESTCANCEL(self); 454 retval = _sys___pselect50(nfds, readfds, writefds, exceptfds, timeout, 455 sigmask); 456 TESTCANCEL(self); 457 458 return retval; 459 } 460 461 ssize_t 462 pwrite(int d, const void *buf, size_t nbytes, off_t offset) 463 { 464 ssize_t retval; 465 pthread_t self; 466 467 self = pthread__self(); 468 TESTCANCEL(self); 469 retval = _sys_pwrite(d, buf, nbytes, offset); 470 TESTCANCEL(self); 471 472 return retval; 473 } 474 475 ssize_t 476 read(int d, void *buf, size_t nbytes) 477 { 478 ssize_t retval; 479 pthread_t self; 480 481 self = pthread__self(); 482 TESTCANCEL(self); 483 retval = _sys_read(d, buf, nbytes); 484 TESTCANCEL(self); 485 486 return retval; 487 } 488 489 ssize_t 490 readv(int d, const struct iovec *iov, int iovcnt) 491 { 492 ssize_t retval; 493 pthread_t self; 494 495 self = pthread__self(); 496 TESTCANCEL(self); 497 retval = _sys_readv(d, iov, iovcnt); 498 TESTCANCEL(self); 499 500 return retval; 501 } 502 503 int 504 __select50(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, 505 struct timeval *timeout) 506 { 507 int retval; 508 pthread_t self; 509 510 self = pthread__self(); 511 TESTCANCEL(self); 512 retval = _sys___select50(nfds, readfds, writefds, exceptfds, timeout); 513 TESTCANCEL(self); 514 515 return retval; 516 } 517 518 pid_t 519 __wait450(pid_t wpid, int *status, int options, struct rusage *rusage) 520 { 521 pid_t retval; 522 pthread_t self; 523 524 self = pthread__self(); 525 TESTCANCEL(self); 526 retval = _sys___wait450(wpid, status, options, rusage); 527 TESTCANCEL(self); 528 529 return retval; 530 } 531 532 ssize_t 533 write(int d, const void *buf, size_t nbytes) 534 { 535 ssize_t retval; 536 pthread_t self; 537 538 self = pthread__self(); 539 TESTCANCEL(self); 540 retval = _sys_write(d, buf, nbytes); 541 TESTCANCEL(self); 542 543 return retval; 544 } 545 546 ssize_t 547 writev(int d, const struct iovec *iov, int iovcnt) 548 { 549 ssize_t retval; 550 pthread_t self; 551 552 self = pthread__self(); 553 TESTCANCEL(self); 554 retval = _sys_writev(d, iov, iovcnt); 555 TESTCANCEL(self); 556 557 return retval; 558 } 559 560 int 561 __sigsuspend14(const sigset_t *sigmask) 562 { 563 pthread_t self; 564 int retval; 565 566 self = pthread__self(); 567 TESTCANCEL(self); 568 retval = _sys___sigsuspend14(sigmask); 569 TESTCANCEL(self); 570 571 return retval; 572 } 573 574 int 575 __sigtimedwait50(const sigset_t * __restrict set, siginfo_t * __restrict info, 576 const struct timespec * __restrict timeout) 577 { 578 pthread_t self; 579 int retval; 580 struct timespec tout, *tp; 581 582 if (timeout) { 583 tout = *timeout; 584 tp = &tout; 585 } else 586 tp = NULL; 587 588 self = pthread__self(); 589 TESTCANCEL(self); 590 retval = ____sigtimedwait50(set, info, tp); 591 TESTCANCEL(self); 592 593 return retval; 594 } 595 596 int 597 sigwait(const sigset_t * __restrict set, int * __restrict sig) 598 { 599 pthread_t self; 600 int saved_errno; 601 int new_errno; 602 int retval; 603 604 self = pthread__self(); 605 saved_errno = errno; 606 TESTCANCEL(self); 607 retval = ____sigtimedwait50(set, NULL, NULL); 608 TESTCANCEL(self); 609 new_errno = errno; 610 errno = saved_errno; 611 if (retval < 0) { 612 return new_errno; 613 } 614 *sig = retval; 615 return 0; 616 } 617 618 __strong_alias(_close, close) 619 __strong_alias(_fcntl, fcntl) 620 __strong_alias(_fdatasync, fdatasync) 621 __strong_alias(_fsync, fsync) 622 __weak_alias(fsync_range, _fsync_range) 623 __strong_alias(_mq_send, mq_send) 624 __strong_alias(_mq_receive, mq_receive) 625 __strong_alias(_msgrcv, msgrcv) 626 __strong_alias(_msgsnd, msgsnd) 627 __strong_alias(___msync13, __msync13) 628 __strong_alias(___nanosleep50, __nanosleep50) 629 __strong_alias(_open, open) 630 __strong_alias(_poll, poll) 631 __strong_alias(_pread, pread) 632 __strong_alias(_pwrite, pwrite) 633 __strong_alias(_read, read) 634 __strong_alias(_readv, readv) 635 __strong_alias(_sigwait, sigwait) 636 __strong_alias(_write, write) 637 __strong_alias(_writev, writev) 638 639 #endif /* !lint */ 640