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