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