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