1 /* $NetBSD: pthread_cancelstub.c,v 1.13 2005/09/13 02:45:38 christos Exp $ */ 2 3 /*- 4 * Copyright (c) 2002 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. 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.13 2005/09/13 02:45:38 christos 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 103 #define TESTCANCEL(id) do { \ 104 if (__predict_false((id)->pt_cancel)) \ 105 pthread_exit(PTHREAD_CANCELED); \ 106 } while (/*CONSTCOND*/0) 107 108 109 int 110 accept(int s, struct sockaddr *addr, socklen_t *addrlen) 111 { 112 int retval; 113 pthread_t self; 114 115 self = pthread__self(); 116 TESTCANCEL(self); 117 retval = _sys_accept(s, addr, addrlen); 118 TESTCANCEL(self); 119 120 return retval; 121 } 122 123 int 124 close(int d) 125 { 126 int retval; 127 pthread_t self; 128 129 self = pthread__self(); 130 TESTCANCEL(self); 131 retval = _sys_close(d); 132 TESTCANCEL(self); 133 134 return retval; 135 } 136 137 int 138 connect(int s, const struct sockaddr *addr, socklen_t namelen) 139 { 140 int retval; 141 pthread_t self; 142 143 self = pthread__self(); 144 TESTCANCEL(self); 145 retval = _sys_connect(s, addr, namelen); 146 TESTCANCEL(self); 147 148 return retval; 149 } 150 151 int 152 fcntl(int fd, int cmd, ...) 153 { 154 int retval; 155 pthread_t self; 156 va_list ap; 157 158 self = pthread__self(); 159 TESTCANCEL(self); 160 va_start(ap, cmd); 161 retval = _sys_fcntl(fd, cmd, va_arg(ap, void *)); 162 va_end(ap); 163 TESTCANCEL(self); 164 165 return retval; 166 } 167 168 int 169 fdatasync(int d) 170 { 171 int retval; 172 pthread_t self; 173 174 self = pthread__self(); 175 TESTCANCEL(self); 176 retval = _sys_fdatasync(d); 177 TESTCANCEL(self); 178 179 return retval; 180 } 181 182 int 183 fsync(int d) 184 { 185 int retval; 186 pthread_t self; 187 188 self = pthread__self(); 189 TESTCANCEL(self); 190 retval = _sys_fsync(d); 191 TESTCANCEL(self); 192 193 return retval; 194 } 195 196 int 197 fsync_range(int d, int f, off_t s, off_t e) 198 { 199 int retval; 200 pthread_t self; 201 202 self = pthread__self(); 203 TESTCANCEL(self); 204 retval = _sys_fsync_range(d, f, s, e); 205 TESTCANCEL(self); 206 207 return retval; 208 } 209 210 ssize_t 211 msgrcv(int msgid, void *msgp, size_t msgsz, long msgtyp, int msgflg) 212 { 213 ssize_t retval; 214 pthread_t self; 215 216 self = pthread__self(); 217 TESTCANCEL(self); 218 retval = _sys_msgrcv(msgid, msgp, msgsz, msgtyp, msgflg); 219 TESTCANCEL(self); 220 221 return retval; 222 } 223 224 int 225 msgsnd(int msgid, const void *msgp, size_t msgsz, int msgflg) 226 { 227 int retval; 228 pthread_t self; 229 230 self = pthread__self(); 231 TESTCANCEL(self); 232 retval = _sys_msgsnd(msgid, msgp, msgsz, msgflg); 233 TESTCANCEL(self); 234 235 return retval; 236 } 237 238 int 239 __msync13(void *addr, size_t len, int flags) 240 { 241 int retval; 242 pthread_t self; 243 244 self = pthread__self(); 245 TESTCANCEL(self); 246 retval = _sys___msync13(addr, len, flags); 247 TESTCANCEL(self); 248 249 return retval; 250 } 251 252 int 253 open(const char *path, int flags, ...) 254 { 255 int retval; 256 pthread_t self; 257 va_list ap; 258 259 self = pthread__self(); 260 TESTCANCEL(self); 261 va_start(ap, flags); 262 retval = _sys_open(path, flags, va_arg(ap, mode_t)); 263 va_end(ap); 264 TESTCANCEL(self); 265 266 return retval; 267 } 268 269 int 270 poll(struct pollfd *fds, nfds_t nfds, int timeout) 271 { 272 int retval; 273 pthread_t self; 274 275 self = pthread__self(); 276 TESTCANCEL(self); 277 retval = _sys_poll(fds, nfds, timeout); 278 TESTCANCEL(self); 279 280 return retval; 281 } 282 283 int 284 pollts(struct pollfd *fds, nfds_t nfds, const struct timespec *ts, 285 const sigset_t *sigmask) 286 { 287 int retval; 288 pthread_t self; 289 290 self = pthread__self(); 291 TESTCANCEL(self); 292 retval = _sys_pollts(fds, nfds, ts, sigmask); 293 TESTCANCEL(self); 294 295 return retval; 296 } 297 298 ssize_t 299 pread(int d, void *buf, size_t nbytes, off_t offset) 300 { 301 ssize_t retval; 302 pthread_t self; 303 304 self = pthread__self(); 305 TESTCANCEL(self); 306 retval = _sys_pread(d, buf, nbytes, offset); 307 TESTCANCEL(self); 308 309 return retval; 310 } 311 312 int 313 pselect(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, 314 const struct timespec *timeout, const sigset_t *sigmask) 315 { 316 int retval; 317 pthread_t self; 318 319 self = pthread__self(); 320 TESTCANCEL(self); 321 retval = _sys_pselect(nfds, readfds, writefds, exceptfds, timeout, 322 sigmask); 323 TESTCANCEL(self); 324 325 return retval; 326 } 327 328 ssize_t 329 pwrite(int d, const void *buf, size_t nbytes, off_t offset) 330 { 331 ssize_t retval; 332 pthread_t self; 333 334 self = pthread__self(); 335 TESTCANCEL(self); 336 retval = _sys_pwrite(d, buf, nbytes, offset); 337 TESTCANCEL(self); 338 339 return retval; 340 } 341 342 ssize_t 343 read(int d, void *buf, size_t nbytes) 344 { 345 ssize_t retval; 346 pthread_t self; 347 348 self = pthread__self(); 349 TESTCANCEL(self); 350 retval = _sys_read(d, buf, nbytes); 351 TESTCANCEL(self); 352 353 return retval; 354 } 355 356 ssize_t 357 readv(int d, const struct iovec *iov, int iovcnt) 358 { 359 ssize_t retval; 360 pthread_t self; 361 362 self = pthread__self(); 363 TESTCANCEL(self); 364 retval = _sys_readv(d, iov, iovcnt); 365 TESTCANCEL(self); 366 367 return retval; 368 } 369 370 int 371 select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, 372 struct timeval *timeout) 373 { 374 int retval; 375 pthread_t self; 376 377 self = pthread__self(); 378 TESTCANCEL(self); 379 retval = _sys_select(nfds, readfds, writefds, exceptfds, timeout); 380 TESTCANCEL(self); 381 382 return retval; 383 } 384 385 pid_t 386 wait4(pid_t wpid, int *status, int options, struct rusage *rusage) 387 { 388 pid_t retval; 389 pthread_t self; 390 391 self = pthread__self(); 392 TESTCANCEL(self); 393 retval = _sys_wait4(wpid, status, options, rusage); 394 TESTCANCEL(self); 395 396 return retval; 397 } 398 399 ssize_t 400 write(int d, const void *buf, size_t nbytes) 401 { 402 ssize_t retval; 403 pthread_t self; 404 405 self = pthread__self(); 406 TESTCANCEL(self); 407 retval = _sys_write(d, buf, nbytes); 408 TESTCANCEL(self); 409 410 return retval; 411 } 412 413 ssize_t 414 writev(int d, const struct iovec *iov, int iovcnt) 415 { 416 ssize_t retval; 417 pthread_t self; 418 419 self = pthread__self(); 420 TESTCANCEL(self); 421 retval = _sys_writev(d, iov, iovcnt); 422 TESTCANCEL(self); 423 424 return retval; 425 } 426 427 428 __strong_alias(_close, close) 429 __strong_alias(_fcntl, fcntl) 430 __strong_alias(_fdatasync, fdatasync) 431 __strong_alias(_fsync, fsync) 432 __weak_alias(fsync_range, _fsync_range) 433 __strong_alias(_msgrcv, msgrcv) 434 __strong_alias(_msgsnd, msgsnd) 435 __strong_alias(___msync13, __msync13) 436 __strong_alias(_open, open) 437 __strong_alias(_poll, poll) 438 __weak_alias(pollts, _pollts) 439 __strong_alias(_pread, pread) 440 __strong_alias(_pselect, pselect) 441 __strong_alias(_pwrite, pwrite) 442 __strong_alias(_read, read) 443 __strong_alias(_readv, readv) 444 __strong_alias(_select, select) 445 __strong_alias(_wait4, wait4) 446 __strong_alias(_write, write) 447 __strong_alias(_writev, writev) 448