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