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