1 /* $NetBSD: pthread_cancelstub.c,v 1.9 2004/05/21 17:15:42 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.9 2004/05/21 17:15:42 kleink Exp $"); 41 42 /* 43 * This is necessary because the fsync_range() name is always weak (it is 44 * not a POSIX function). 45 */ 46 #define fsync_range _fsync_range 47 48 #include <sys/msg.h> 49 #include <sys/types.h> 50 #include <sys/uio.h> 51 #include <sys/wait.h> 52 #include <fcntl.h> 53 #include <poll.h> 54 #include <stdarg.h> 55 #include <unistd.h> 56 57 int pthread__cancel_stub_binder; 58 59 /* 60 * XXX this is necessary to get the prototypes for the __sigsuspend14 61 * XXX and __msync13 internal names, instead of the application-visible 62 * XXX sigsuspend and msync names. It's kind of gross, but we're pretty 63 * XXX intimate with libc already. 64 */ 65 #define __LIBC12_SOURCE__ 66 #include <signal.h> 67 #include <sys/mman.h> 68 #include <sys/socket.h> 69 70 #include "pthread.h" 71 #include "pthread_int.h" 72 73 int _sys_accept(int, struct sockaddr *, socklen_t *); 74 int _sys_close(int); 75 int _sys_connect(int, const struct sockaddr *, socklen_t); 76 int _sys_fcntl(int, int, ...); 77 int _sys_fdatasync(int); 78 int _sys_fsync(int); 79 int _sys_fsync_range(int, int, off_t, off_t); 80 ssize_t _sys_msgrcv(int, void *, size_t, long, int); 81 int _sys_msgsnd(int, const void *, size_t, int); 82 int _sys___msync13(void *, size_t, int); 83 int _sys_open(const char *, int, ...); 84 int _sys_poll(struct pollfd *, nfds_t, int); 85 ssize_t _sys_pread(int, void *, size_t, off_t); 86 ssize_t _sys_pwrite(int, const void *, size_t, off_t); 87 ssize_t _sys_read(int, void *, size_t); 88 ssize_t _sys_readv(int, const struct iovec *, int); 89 int _sys_select(int, fd_set *, fd_set *, fd_set *, struct timeval *); 90 int _sys_wait4(pid_t, int *, int, struct rusage *); 91 ssize_t _sys_write(int, const void *, size_t); 92 ssize_t _sys_writev(int, const struct iovec *, int); 93 94 #define TESTCANCEL(id) do { \ 95 if (__predict_false((id)->pt_cancel)) \ 96 pthread_exit(PTHREAD_CANCELED); \ 97 } while (/*CONSTCOND*/0) 98 99 100 int 101 accept(int s, struct sockaddr *addr, socklen_t *addrlen) 102 { 103 int retval; 104 pthread_t self; 105 106 self = pthread__self(); 107 TESTCANCEL(self); 108 retval = _sys_accept(s, addr, addrlen); 109 TESTCANCEL(self); 110 111 return retval; 112 } 113 114 int 115 close(int d) 116 { 117 int retval; 118 pthread_t self; 119 120 self = pthread__self(); 121 TESTCANCEL(self); 122 retval = _sys_close(d); 123 TESTCANCEL(self); 124 125 return retval; 126 } 127 128 int 129 connect(int s, const struct sockaddr *addr, socklen_t namelen) 130 { 131 int retval; 132 pthread_t self; 133 134 self = pthread__self(); 135 TESTCANCEL(self); 136 retval = _sys_connect(s, addr, namelen); 137 TESTCANCEL(self); 138 139 return retval; 140 } 141 142 int 143 fcntl(int fd, int cmd, ...) 144 { 145 int retval; 146 pthread_t self; 147 va_list ap; 148 149 self = pthread__self(); 150 TESTCANCEL(self); 151 va_start(ap, cmd); 152 retval = _sys_fcntl(fd, cmd, va_arg(ap, void *)); 153 va_end(ap); 154 TESTCANCEL(self); 155 156 return retval; 157 } 158 159 int 160 fdatasync(int d) 161 { 162 int retval; 163 pthread_t self; 164 165 self = pthread__self(); 166 TESTCANCEL(self); 167 retval = _sys_fdatasync(d); 168 TESTCANCEL(self); 169 170 return retval; 171 } 172 173 int 174 fsync(int d) 175 { 176 int retval; 177 pthread_t self; 178 179 self = pthread__self(); 180 TESTCANCEL(self); 181 retval = _sys_fsync(d); 182 TESTCANCEL(self); 183 184 return retval; 185 } 186 187 int 188 fsync_range(int d, int f, off_t s, off_t e) 189 { 190 int retval; 191 pthread_t self; 192 193 self = pthread__self(); 194 TESTCANCEL(self); 195 retval = _sys_fsync_range(d, f, s, e); 196 TESTCANCEL(self); 197 198 return retval; 199 } 200 201 ssize_t 202 msgrcv(int msgid, void *msgp, size_t msgsz, long msgtyp, int msgflg) 203 { 204 ssize_t retval; 205 pthread_t self; 206 207 self = pthread__self(); 208 TESTCANCEL(self); 209 retval = _sys_msgrcv(msgid, msgp, msgsz, msgtyp, msgflg); 210 TESTCANCEL(self); 211 212 return retval; 213 } 214 215 int 216 msgsnd(int msgid, const void *msgp, size_t msgsz, int msgflg) 217 { 218 int retval; 219 pthread_t self; 220 221 self = pthread__self(); 222 TESTCANCEL(self); 223 retval = _sys_msgsnd(msgid, msgp, msgsz, msgflg); 224 TESTCANCEL(self); 225 226 return retval; 227 } 228 229 int 230 __msync13(void *addr, size_t len, int flags) 231 { 232 int retval; 233 pthread_t self; 234 235 self = pthread__self(); 236 TESTCANCEL(self); 237 retval = _sys___msync13(addr, len, flags); 238 TESTCANCEL(self); 239 240 return retval; 241 } 242 243 int 244 open(const char *path, int flags, ...) 245 { 246 int retval; 247 pthread_t self; 248 va_list ap; 249 250 self = pthread__self(); 251 TESTCANCEL(self); 252 va_start(ap, flags); 253 retval = _sys_open(path, flags, va_arg(ap, mode_t)); 254 va_end(ap); 255 TESTCANCEL(self); 256 257 return retval; 258 } 259 260 int 261 poll(struct pollfd *fds, nfds_t nfds, int timeout) 262 { 263 int retval; 264 pthread_t self; 265 266 self = pthread__self(); 267 TESTCANCEL(self); 268 retval = _sys_poll(fds, nfds, timeout); 269 TESTCANCEL(self); 270 271 return retval; 272 } 273 274 ssize_t 275 pread(int d, void *buf, size_t nbytes, off_t offset) 276 { 277 ssize_t retval; 278 pthread_t self; 279 280 self = pthread__self(); 281 TESTCANCEL(self); 282 retval = _sys_pread(d, buf, nbytes, offset); 283 TESTCANCEL(self); 284 285 return retval; 286 } 287 288 ssize_t 289 pwrite(int d, const void *buf, size_t nbytes, off_t offset) 290 { 291 ssize_t retval; 292 pthread_t self; 293 294 self = pthread__self(); 295 TESTCANCEL(self); 296 retval = _sys_pwrite(d, buf, nbytes, offset); 297 TESTCANCEL(self); 298 299 return retval; 300 } 301 302 ssize_t 303 read(int d, void *buf, size_t nbytes) 304 { 305 ssize_t retval; 306 pthread_t self; 307 308 self = pthread__self(); 309 TESTCANCEL(self); 310 retval = _sys_read(d, buf, nbytes); 311 TESTCANCEL(self); 312 313 return retval; 314 } 315 316 ssize_t 317 readv(int d, const struct iovec *iov, int iovcnt) 318 { 319 ssize_t retval; 320 pthread_t self; 321 322 self = pthread__self(); 323 TESTCANCEL(self); 324 retval = _sys_readv(d, iov, iovcnt); 325 TESTCANCEL(self); 326 327 return retval; 328 } 329 330 int 331 select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, 332 struct timeval *timeout) 333 { 334 int retval; 335 pthread_t self; 336 337 self = pthread__self(); 338 TESTCANCEL(self); 339 retval = _sys_select(nfds, readfds, writefds, exceptfds, timeout); 340 TESTCANCEL(self); 341 342 return retval; 343 } 344 345 pid_t 346 wait4(pid_t wpid, int *status, int options, struct rusage *rusage) 347 { 348 pid_t retval; 349 pthread_t self; 350 351 self = pthread__self(); 352 TESTCANCEL(self); 353 retval = _sys_wait4(wpid, status, options, rusage); 354 TESTCANCEL(self); 355 356 return retval; 357 } 358 359 ssize_t 360 write(int d, const void *buf, size_t nbytes) 361 { 362 ssize_t retval; 363 pthread_t self; 364 365 self = pthread__self(); 366 TESTCANCEL(self); 367 retval = _sys_write(d, buf, nbytes); 368 TESTCANCEL(self); 369 370 return retval; 371 } 372 373 ssize_t 374 writev(int d, const struct iovec *iov, int iovcnt) 375 { 376 ssize_t retval; 377 pthread_t self; 378 379 self = pthread__self(); 380 TESTCANCEL(self); 381 retval = _sys_writev(d, iov, iovcnt); 382 TESTCANCEL(self); 383 384 return retval; 385 } 386 387 388 __strong_alias(_close, close) 389 __strong_alias(_fcntl, fcntl) 390 __strong_alias(_fdatasync, fdatasync) 391 __strong_alias(_fsync, fsync) 392 __weak_alias(fsync_range, _fsync_range) 393 __strong_alias(_msgrcv, msgrcv) 394 __strong_alias(_msgsnd, msgsnd) 395 __strong_alias(___msync13, __msync13) 396 __strong_alias(_open, open) 397 __strong_alias(_poll, poll) 398 __strong_alias(_pread, pread) 399 __strong_alias(_pwrite, pwrite) 400 __strong_alias(_read, read) 401 __strong_alias(_readv, readv) 402 __strong_alias(_select, select) 403 __strong_alias(_wait4, wait4) 404 __strong_alias(_write, write) 405 __strong_alias(_writev, writev) 406