1 /* $NetBSD: pthread_cancelstub.c,v 1.14 2007/03/04 20:07:13 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 * 3. All advertising materials mentioning features or use of this software 19 * must display the following acknowledgement: 20 * This product includes software developed by the NetBSD 21 * Foundation, Inc. and its contributors. 22 * 4. Neither the name of The NetBSD Foundation nor the names of its 23 * contributors may be used to endorse or promote products derived 24 * from this software without specific prior written permission. 25 * 26 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 27 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 28 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 29 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 30 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 31 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 32 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 33 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 34 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 35 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 36 * POSSIBILITY OF SUCH DAMAGE. 37 */ 38 39 #include <sys/cdefs.h> 40 __RCSID("$NetBSD: pthread_cancelstub.c,v 1.14 2007/03/04 20:07:13 ad Exp $"); 41 42 /* 43 * This is necessary because the names are always weak (they are not 44 * POSIX functions). 45 */ 46 #define fsync_range _fsync_range 47 #define pollts _pollts 48 49 /* 50 * XXX this is necessary to get the prototypes for the __sigsuspend14 51 * XXX and __msync13 internal names, instead of the application-visible 52 * XXX sigsuspend and msync names. It's kind of gross, but we're pretty 53 * XXX intimate with libc already. 54 */ 55 #define __LIBC12_SOURCE__ 56 57 #include <sys/msg.h> 58 #include <sys/types.h> 59 #include <sys/uio.h> 60 #include <sys/wait.h> 61 #include <fcntl.h> 62 #include <poll.h> 63 #include <stdarg.h> 64 #include <unistd.h> 65 66 #include <signal.h> 67 #include <sys/mman.h> 68 #include <sys/select.h> 69 #include <sys/socket.h> 70 71 #include <compat/sys/mman.h> 72 73 #include "pthread.h" 74 #include "pthread_int.h" 75 76 int pthread__cancel_stub_binder; 77 78 int _sys_accept(int, struct sockaddr *, socklen_t *); 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 ssize_t _sys_msgrcv(int, void *, size_t, long, int); 86 int _sys_msgsnd(int, const void *, size_t, int); 87 int _sys___msync13(void *, size_t, int); 88 int _sys_open(const char *, int, ...); 89 int _sys_poll(struct pollfd *, nfds_t, int); 90 int _sys_pollts(struct pollfd *, nfds_t, const struct timespec *, 91 const sigset_t *); 92 ssize_t _sys_pread(int, void *, size_t, off_t); 93 int _sys_pselect(int, fd_set *, fd_set *, fd_set *, 94 const struct timespec *, const sigset_t *); 95 ssize_t _sys_pwrite(int, const void *, size_t, off_t); 96 ssize_t _sys_read(int, void *, size_t); 97 ssize_t _sys_readv(int, const struct iovec *, int); 98 int _sys_select(int, fd_set *, fd_set *, fd_set *, struct timeval *); 99 int _sys_wait4(pid_t, int *, int, struct rusage *); 100 ssize_t _sys_write(int, const void *, size_t); 101 ssize_t _sys_writev(int, const struct iovec *, int); 102 int _sys___sigsuspend14(const sigset_t *); 103 int _sigtimedwait(const sigset_t * __restrict, siginfo_t * __restrict, 104 const struct timespec * __restrict); 105 int __sigsuspend14(const sigset_t *); 106 107 #define TESTCANCEL(id) do { \ 108 if (__predict_false((id)->pt_cancel)) \ 109 pthread_exit(PTHREAD_CANCELED); \ 110 } while (/*CONSTCOND*/0) 111 112 113 int 114 accept(int s, struct sockaddr *addr, socklen_t *addrlen) 115 { 116 int retval; 117 pthread_t self; 118 119 self = pthread__self(); 120 TESTCANCEL(self); 121 retval = _sys_accept(s, addr, addrlen); 122 TESTCANCEL(self); 123 124 return retval; 125 } 126 127 int 128 close(int d) 129 { 130 int retval; 131 pthread_t self; 132 133 self = pthread__self(); 134 TESTCANCEL(self); 135 retval = _sys_close(d); 136 TESTCANCEL(self); 137 138 return retval; 139 } 140 141 int 142 connect(int s, const struct sockaddr *addr, socklen_t namelen) 143 { 144 int retval; 145 pthread_t self; 146 147 self = pthread__self(); 148 TESTCANCEL(self); 149 retval = _sys_connect(s, addr, namelen); 150 TESTCANCEL(self); 151 152 return retval; 153 } 154 155 int 156 fcntl(int fd, int cmd, ...) 157 { 158 int retval; 159 pthread_t self; 160 va_list ap; 161 162 self = pthread__self(); 163 TESTCANCEL(self); 164 va_start(ap, cmd); 165 retval = _sys_fcntl(fd, cmd, va_arg(ap, void *)); 166 va_end(ap); 167 TESTCANCEL(self); 168 169 return retval; 170 } 171 172 int 173 fdatasync(int d) 174 { 175 int retval; 176 pthread_t self; 177 178 self = pthread__self(); 179 TESTCANCEL(self); 180 retval = _sys_fdatasync(d); 181 TESTCANCEL(self); 182 183 return retval; 184 } 185 186 int 187 fsync(int d) 188 { 189 int retval; 190 pthread_t self; 191 192 self = pthread__self(); 193 TESTCANCEL(self); 194 retval = _sys_fsync(d); 195 TESTCANCEL(self); 196 197 return retval; 198 } 199 200 int 201 fsync_range(int d, int f, off_t s, off_t e) 202 { 203 int retval; 204 pthread_t self; 205 206 self = pthread__self(); 207 TESTCANCEL(self); 208 retval = _sys_fsync_range(d, f, s, e); 209 TESTCANCEL(self); 210 211 return retval; 212 } 213 214 ssize_t 215 msgrcv(int msgid, void *msgp, size_t msgsz, long msgtyp, int msgflg) 216 { 217 ssize_t retval; 218 pthread_t self; 219 220 self = pthread__self(); 221 TESTCANCEL(self); 222 retval = _sys_msgrcv(msgid, msgp, msgsz, msgtyp, msgflg); 223 TESTCANCEL(self); 224 225 return retval; 226 } 227 228 int 229 msgsnd(int msgid, const void *msgp, size_t msgsz, int msgflg) 230 { 231 int retval; 232 pthread_t self; 233 234 self = pthread__self(); 235 TESTCANCEL(self); 236 retval = _sys_msgsnd(msgid, msgp, msgsz, msgflg); 237 TESTCANCEL(self); 238 239 return retval; 240 } 241 242 int 243 __msync13(void *addr, size_t len, int flags) 244 { 245 int retval; 246 pthread_t self; 247 248 self = pthread__self(); 249 TESTCANCEL(self); 250 retval = _sys___msync13(addr, len, flags); 251 TESTCANCEL(self); 252 253 return retval; 254 } 255 256 int 257 open(const char *path, int flags, ...) 258 { 259 int retval; 260 pthread_t self; 261 va_list ap; 262 263 self = pthread__self(); 264 TESTCANCEL(self); 265 va_start(ap, flags); 266 retval = _sys_open(path, flags, va_arg(ap, mode_t)); 267 va_end(ap); 268 TESTCANCEL(self); 269 270 return retval; 271 } 272 273 int 274 poll(struct pollfd *fds, nfds_t nfds, int timeout) 275 { 276 int retval; 277 pthread_t self; 278 279 self = pthread__self(); 280 TESTCANCEL(self); 281 retval = _sys_poll(fds, nfds, timeout); 282 TESTCANCEL(self); 283 284 return retval; 285 } 286 287 int 288 pollts(struct pollfd *fds, nfds_t nfds, const struct timespec *ts, 289 const sigset_t *sigmask) 290 { 291 int retval; 292 pthread_t self; 293 294 self = pthread__self(); 295 TESTCANCEL(self); 296 retval = _sys_pollts(fds, nfds, ts, sigmask); 297 TESTCANCEL(self); 298 299 return retval; 300 } 301 302 ssize_t 303 pread(int d, void *buf, size_t nbytes, off_t offset) 304 { 305 ssize_t retval; 306 pthread_t self; 307 308 self = pthread__self(); 309 TESTCANCEL(self); 310 retval = _sys_pread(d, buf, nbytes, offset); 311 TESTCANCEL(self); 312 313 return retval; 314 } 315 316 int 317 pselect(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, 318 const struct timespec *timeout, const sigset_t *sigmask) 319 { 320 int retval; 321 pthread_t self; 322 323 self = pthread__self(); 324 TESTCANCEL(self); 325 retval = _sys_pselect(nfds, readfds, writefds, exceptfds, timeout, 326 sigmask); 327 TESTCANCEL(self); 328 329 return retval; 330 } 331 332 ssize_t 333 pwrite(int d, const void *buf, size_t nbytes, off_t offset) 334 { 335 ssize_t retval; 336 pthread_t self; 337 338 self = pthread__self(); 339 TESTCANCEL(self); 340 retval = _sys_pwrite(d, buf, nbytes, offset); 341 TESTCANCEL(self); 342 343 return retval; 344 } 345 346 ssize_t 347 read(int d, void *buf, size_t nbytes) 348 { 349 ssize_t retval; 350 pthread_t self; 351 352 self = pthread__self(); 353 TESTCANCEL(self); 354 retval = _sys_read(d, buf, nbytes); 355 TESTCANCEL(self); 356 357 return retval; 358 } 359 360 ssize_t 361 readv(int d, const struct iovec *iov, int iovcnt) 362 { 363 ssize_t retval; 364 pthread_t self; 365 366 self = pthread__self(); 367 TESTCANCEL(self); 368 retval = _sys_readv(d, iov, iovcnt); 369 TESTCANCEL(self); 370 371 return retval; 372 } 373 374 int 375 select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, 376 struct timeval *timeout) 377 { 378 int retval; 379 pthread_t self; 380 381 self = pthread__self(); 382 TESTCANCEL(self); 383 retval = _sys_select(nfds, readfds, writefds, exceptfds, timeout); 384 TESTCANCEL(self); 385 386 return retval; 387 } 388 389 pid_t 390 wait4(pid_t wpid, int *status, int options, struct rusage *rusage) 391 { 392 pid_t retval; 393 pthread_t self; 394 395 self = pthread__self(); 396 TESTCANCEL(self); 397 retval = _sys_wait4(wpid, status, options, rusage); 398 TESTCANCEL(self); 399 400 return retval; 401 } 402 403 ssize_t 404 write(int d, const void *buf, size_t nbytes) 405 { 406 ssize_t retval; 407 pthread_t self; 408 409 self = pthread__self(); 410 TESTCANCEL(self); 411 retval = _sys_write(d, buf, nbytes); 412 TESTCANCEL(self); 413 414 return retval; 415 } 416 417 ssize_t 418 writev(int d, const struct iovec *iov, int iovcnt) 419 { 420 ssize_t retval; 421 pthread_t self; 422 423 self = pthread__self(); 424 TESTCANCEL(self); 425 retval = _sys_writev(d, iov, iovcnt); 426 TESTCANCEL(self); 427 428 return retval; 429 } 430 431 int 432 __sigsuspend14(const sigset_t *sigmask) 433 { 434 pthread_t self; 435 int retval; 436 437 self = pthread__self(); 438 TESTCANCEL(self); 439 retval = _sys___sigsuspend14(sigmask); 440 TESTCANCEL(self); 441 442 return retval; 443 } 444 445 int 446 sigtimedwait(const sigset_t * __restrict set, siginfo_t * __restrict info, 447 const struct timespec * __restrict timeout) 448 { 449 pthread_t self; 450 int retval; 451 452 self = pthread__self(); 453 TESTCANCEL(self); 454 retval = _sigtimedwait(set, info, timeout); 455 TESTCANCEL(self); 456 457 return retval; 458 } 459 460 __strong_alias(_close, close) 461 __strong_alias(_fcntl, fcntl) 462 __strong_alias(_fdatasync, fdatasync) 463 __strong_alias(_fsync, fsync) 464 __weak_alias(fsync_range, _fsync_range) 465 __strong_alias(_msgrcv, msgrcv) 466 __strong_alias(_msgsnd, msgsnd) 467 __strong_alias(___msync13, __msync13) 468 __strong_alias(_open, open) 469 __strong_alias(_poll, poll) 470 __weak_alias(pollts, _pollts) 471 __strong_alias(_pread, pread) 472 __strong_alias(_pselect, pselect) 473 __strong_alias(_pwrite, pwrite) 474 __strong_alias(_read, read) 475 __strong_alias(_readv, readv) 476 __strong_alias(_select, select) 477 __strong_alias(_wait4, wait4) 478 __strong_alias(_write, write) 479 __strong_alias(_writev, writev) 480