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