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