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