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