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