pthread_cancelstub.c revision 1.22.6.1 1 /* $NetBSD: pthread_cancelstub.c,v 1.22.6.1 2010/04/21 05:28:11 matt 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 *
19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE.
30 */
31
32 #include <sys/cdefs.h>
33 __RCSID("$NetBSD: pthread_cancelstub.c,v 1.22.6.1 2010/04/21 05:28:11 matt Exp $");
34
35 #ifndef lint
36
37
38 /*
39 * This is necessary because the names are always weak (they are not
40 * POSIX functions).
41 */
42 #define fsync_range _fsync_range
43 #define pollts _pollts
44
45 /*
46 * XXX this is necessary to get the prototypes for the __sigsuspend14
47 * XXX and __msync13 internal names, instead of the application-visible
48 * XXX sigsuspend and msync names. It's kind of gross, but we're pretty
49 * XXX intimate with libc already.
50 */
51 #define __LIBC12_SOURCE__
52
53 #include <sys/msg.h>
54 #include <sys/types.h>
55 #include <sys/uio.h>
56 #include <sys/wait.h>
57 #include <aio.h>
58 #include <fcntl.h>
59 #include <mqueue.h>
60 #include <poll.h>
61 #include <stdarg.h>
62 #include <unistd.h>
63
64 #include <signal.h>
65 #include <sys/mman.h>
66 #include <sys/select.h>
67 #include <sys/socket.h>
68
69 #include <compat/sys/mman.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_aio_suspend(const struct aiocb * const [], int,
78 const struct timespec *);
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 int _sys_mq_send(mqd_t, const char *, size_t, unsigned);
86 ssize_t _sys_mq_receive(mqd_t, char *, size_t, unsigned *);
87 int _sys_mq_timedsend(mqd_t, const char *, size_t, unsigned,
88 const struct timespec *);
89 ssize_t _sys_mq_timedreceive(mqd_t, char *, size_t, unsigned *,
90 const struct timespec *);
91 ssize_t _sys_msgrcv(int, void *, size_t, long, int);
92 int _sys_msgsnd(int, const void *, size_t, int);
93 int _sys___msync13(void *, size_t, int);
94 int _sys_nanosleep(const struct timespec *, struct timespec *);
95 int _sys_open(const char *, int, ...);
96 int _sys_poll(struct pollfd *, nfds_t, int);
97 int _sys_pollts(struct pollfd *, nfds_t, const struct timespec *,
98 const sigset_t *);
99 ssize_t _sys_pread(int, void *, size_t, off_t);
100 int _sys_pselect(int, fd_set *, fd_set *, fd_set *,
101 const struct timespec *, const sigset_t *);
102 ssize_t _sys_pwrite(int, const void *, size_t, off_t);
103 ssize_t _sys_read(int, void *, size_t);
104 ssize_t _sys_readv(int, const struct iovec *, int);
105 int _sys_select(int, fd_set *, fd_set *, fd_set *, struct timeval *);
106 int _sys_wait4(pid_t, int *, int, struct rusage *);
107 ssize_t _sys_write(int, const void *, size_t);
108 ssize_t _sys_writev(int, const struct iovec *, int);
109 int _sys___sigsuspend14(const sigset_t *);
110 int _sigtimedwait(const sigset_t * __restrict, siginfo_t * __restrict,
111 const struct timespec * __restrict);
112 int __sigsuspend14(const sigset_t *);
113
114 #define TESTCANCEL(id) do { \
115 if (__predict_false((id)->pt_cancel)) \
116 pthread__cancelled(); \
117 } while (/*CONSTCOND*/0)
118
119
120 int
121 accept(int s, struct sockaddr *addr, socklen_t *addrlen)
122 {
123 int retval;
124 pthread_t self;
125
126 self = pthread__self();
127 TESTCANCEL(self);
128 retval = _sys_accept(s, addr, addrlen);
129 TESTCANCEL(self);
130
131 return retval;
132 }
133
134 int
135 aio_suspend(const struct aiocb * const list[], int nent,
136 const struct timespec *timeout)
137 {
138 int retval;
139 pthread_t self;
140
141 self = pthread__self();
142 TESTCANCEL(self);
143 retval = _sys_aio_suspend(list, nent, timeout);
144 TESTCANCEL(self);
145
146 return retval;
147 }
148
149 int
150 close(int d)
151 {
152 int retval;
153 pthread_t self;
154
155 self = pthread__self();
156 TESTCANCEL(self);
157 retval = _sys_close(d);
158 TESTCANCEL(self);
159
160 return retval;
161 }
162
163 int
164 connect(int s, const struct sockaddr *addr, socklen_t namelen)
165 {
166 int retval;
167 pthread_t self;
168
169 self = pthread__self();
170 TESTCANCEL(self);
171 retval = _sys_connect(s, addr, namelen);
172 TESTCANCEL(self);
173
174 return retval;
175 }
176
177 int
178 fcntl(int fd, int cmd, ...)
179 {
180 int retval;
181 pthread_t self;
182 va_list ap;
183
184 self = pthread__self();
185 TESTCANCEL(self);
186 va_start(ap, cmd);
187 retval = _sys_fcntl(fd, cmd, va_arg(ap, void *));
188 va_end(ap);
189 TESTCANCEL(self);
190
191 return retval;
192 }
193
194 int
195 fdatasync(int d)
196 {
197 int retval;
198 pthread_t self;
199
200 self = pthread__self();
201 TESTCANCEL(self);
202 retval = _sys_fdatasync(d);
203 TESTCANCEL(self);
204
205 return retval;
206 }
207
208 int
209 fsync(int d)
210 {
211 int retval;
212 pthread_t self;
213
214 self = pthread__self();
215 TESTCANCEL(self);
216 retval = _sys_fsync(d);
217 TESTCANCEL(self);
218
219 return retval;
220 }
221
222 int
223 fsync_range(int d, int f, off_t s, off_t e)
224 {
225 int retval;
226 pthread_t self;
227
228 self = pthread__self();
229 TESTCANCEL(self);
230 retval = _sys_fsync_range(d, f, s, e);
231 TESTCANCEL(self);
232
233 return retval;
234 }
235
236 int
237 mq_send(mqd_t mqdes, const char *msg_ptr, size_t msg_len, unsigned msg_prio)
238 {
239 int retval;
240 pthread_t self;
241
242 self = pthread__self();
243 TESTCANCEL(self);
244 retval = _sys_mq_send(mqdes, msg_ptr, msg_len, msg_prio);
245 TESTCANCEL(self);
246
247 return retval;
248 }
249
250 ssize_t
251 mq_receive(mqd_t mqdes, char *msg_ptr, size_t msg_len, unsigned *msg_prio)
252 {
253 ssize_t retval;
254 pthread_t self;
255
256 self = pthread__self();
257 TESTCANCEL(self);
258 retval = _sys_mq_receive(mqdes, msg_ptr, msg_len, msg_prio);
259 TESTCANCEL(self);
260
261 return retval;
262 }
263
264 int
265 mq_timedsend(mqd_t mqdes, const char *msg_ptr, size_t msg_len,
266 unsigned msg_prio, const struct timespec *abst)
267 {
268 int retval;
269 pthread_t self;
270
271 self = pthread__self();
272 TESTCANCEL(self);
273 retval = _sys_mq_timedsend(mqdes, msg_ptr, msg_len, msg_prio, abst);
274 TESTCANCEL(self);
275
276 return retval;
277 }
278
279 ssize_t
280 mq_timedreceive(mqd_t mqdes, char *msg_ptr, size_t msg_len, unsigned *msg_prio,
281 const struct timespec *abst)
282 {
283 ssize_t retval;
284 pthread_t self;
285
286 self = pthread__self();
287 TESTCANCEL(self);
288 retval = _sys_mq_timedreceive(mqdes, msg_ptr, msg_len, msg_prio, abst);
289 TESTCANCEL(self);
290
291 return retval;
292 }
293
294 ssize_t
295 msgrcv(int msgid, void *msgp, size_t msgsz, long msgtyp, int msgflg)
296 {
297 ssize_t retval;
298 pthread_t self;
299
300 self = pthread__self();
301 TESTCANCEL(self);
302 retval = _sys_msgrcv(msgid, msgp, msgsz, msgtyp, msgflg);
303 TESTCANCEL(self);
304
305 return retval;
306 }
307
308 int
309 msgsnd(int msgid, const void *msgp, size_t msgsz, int msgflg)
310 {
311 int retval;
312 pthread_t self;
313
314 self = pthread__self();
315 TESTCANCEL(self);
316 retval = _sys_msgsnd(msgid, msgp, msgsz, msgflg);
317 TESTCANCEL(self);
318
319 return retval;
320 }
321
322 int
323 __msync13(void *addr, size_t len, int flags)
324 {
325 int retval;
326 pthread_t self;
327
328 self = pthread__self();
329 TESTCANCEL(self);
330 retval = _sys___msync13(addr, len, flags);
331 TESTCANCEL(self);
332
333 return retval;
334 }
335
336 int
337 nanosleep(const struct timespec *rqtp, struct timespec *rmtp)
338 {
339 int retval;
340 pthread_t self;
341
342 self = pthread__self();
343 TESTCANCEL(self);
344 /*
345 * For now, just nanosleep. In the future, maybe pass a ucontext_t
346 * to _lwp_nanosleep() and allow it to recycle our kernel stack.
347 */
348 retval = _sys_nanosleep(rqtp, rmtp);
349 TESTCANCEL(self);
350
351 return retval;
352 }
353
354 int
355 open(const char *path, int flags, ...)
356 {
357 int retval;
358 pthread_t self;
359 va_list ap;
360
361 self = pthread__self();
362 TESTCANCEL(self);
363 va_start(ap, flags);
364 retval = _sys_open(path, flags, va_arg(ap, mode_t));
365 va_end(ap);
366 TESTCANCEL(self);
367
368 return retval;
369 }
370
371 int
372 poll(struct pollfd *fds, nfds_t nfds, int timeout)
373 {
374 int retval;
375 pthread_t self;
376
377 self = pthread__self();
378 TESTCANCEL(self);
379 retval = _sys_poll(fds, nfds, timeout);
380 TESTCANCEL(self);
381
382 return retval;
383 }
384
385 int
386 pollts(struct pollfd *fds, nfds_t nfds, const struct timespec *ts,
387 const sigset_t *sigmask)
388 {
389 int retval;
390 pthread_t self;
391
392 self = pthread__self();
393 TESTCANCEL(self);
394 retval = _sys_pollts(fds, nfds, ts, sigmask);
395 TESTCANCEL(self);
396
397 return retval;
398 }
399
400 ssize_t
401 pread(int d, void *buf, size_t nbytes, off_t offset)
402 {
403 ssize_t retval;
404 pthread_t self;
405
406 self = pthread__self();
407 TESTCANCEL(self);
408 retval = _sys_pread(d, buf, nbytes, offset);
409 TESTCANCEL(self);
410
411 return retval;
412 }
413
414 int
415 pselect(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
416 const struct timespec *timeout, const sigset_t *sigmask)
417 {
418 int retval;
419 pthread_t self;
420
421 self = pthread__self();
422 TESTCANCEL(self);
423 retval = _sys_pselect(nfds, readfds, writefds, exceptfds, timeout,
424 sigmask);
425 TESTCANCEL(self);
426
427 return retval;
428 }
429
430 ssize_t
431 pwrite(int d, const void *buf, size_t nbytes, off_t offset)
432 {
433 ssize_t retval;
434 pthread_t self;
435
436 self = pthread__self();
437 TESTCANCEL(self);
438 retval = _sys_pwrite(d, buf, nbytes, offset);
439 TESTCANCEL(self);
440
441 return retval;
442 }
443
444 #ifdef _FORTIFY_SOURCE
445 #undef read
446 #endif
447
448 ssize_t
449 read(int d, void *buf, size_t nbytes)
450 {
451 ssize_t retval;
452 pthread_t self;
453
454 self = pthread__self();
455 TESTCANCEL(self);
456 retval = _sys_read(d, buf, nbytes);
457 TESTCANCEL(self);
458
459 return retval;
460 }
461
462 ssize_t
463 readv(int d, const struct iovec *iov, int iovcnt)
464 {
465 ssize_t retval;
466 pthread_t self;
467
468 self = pthread__self();
469 TESTCANCEL(self);
470 retval = _sys_readv(d, iov, iovcnt);
471 TESTCANCEL(self);
472
473 return retval;
474 }
475
476 int
477 select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
478 struct timeval *timeout)
479 {
480 int retval;
481 pthread_t self;
482
483 self = pthread__self();
484 TESTCANCEL(self);
485 retval = _sys_select(nfds, readfds, writefds, exceptfds, timeout);
486 TESTCANCEL(self);
487
488 return retval;
489 }
490
491 pid_t
492 wait4(pid_t wpid, int *status, int options, struct rusage *rusage)
493 {
494 pid_t retval;
495 pthread_t self;
496
497 self = pthread__self();
498 TESTCANCEL(self);
499 retval = _sys_wait4(wpid, status, options, rusage);
500 TESTCANCEL(self);
501
502 return retval;
503 }
504
505 ssize_t
506 write(int d, const void *buf, size_t nbytes)
507 {
508 ssize_t retval;
509 pthread_t self;
510
511 self = pthread__self();
512 TESTCANCEL(self);
513 retval = _sys_write(d, buf, nbytes);
514 TESTCANCEL(self);
515
516 return retval;
517 }
518
519 ssize_t
520 writev(int d, const struct iovec *iov, int iovcnt)
521 {
522 ssize_t retval;
523 pthread_t self;
524
525 self = pthread__self();
526 TESTCANCEL(self);
527 retval = _sys_writev(d, iov, iovcnt);
528 TESTCANCEL(self);
529
530 return retval;
531 }
532
533 int
534 __sigsuspend14(const sigset_t *sigmask)
535 {
536 pthread_t self;
537 int retval;
538
539 self = pthread__self();
540 TESTCANCEL(self);
541 retval = _sys___sigsuspend14(sigmask);
542 TESTCANCEL(self);
543
544 return retval;
545 }
546
547 int
548 sigtimedwait(const sigset_t * __restrict set, siginfo_t * __restrict info,
549 const struct timespec * __restrict timeout)
550 {
551 pthread_t self;
552 int retval;
553
554 self = pthread__self();
555 TESTCANCEL(self);
556 retval = _sigtimedwait(set, info, timeout);
557 TESTCANCEL(self);
558
559 return retval;
560 }
561
562 __strong_alias(_aio_suspend, aio_suspend)
563 __strong_alias(_close, close)
564 __strong_alias(_fcntl, fcntl)
565 __strong_alias(_fdatasync, fdatasync)
566 __strong_alias(_fsync, fsync)
567 __weak_alias(fsync_range, _fsync_range)
568 __strong_alias(_mq_send, mq_send)
569 __strong_alias(_mq_receive, mq_receive)
570 __strong_alias(_mq_timedsend, mq_timedsend)
571 __strong_alias(_mq_timedreceive, mq_timedreceive)
572 __strong_alias(_msgrcv, msgrcv)
573 __strong_alias(_msgsnd, msgsnd)
574 __strong_alias(___msync13, __msync13)
575 __strong_alias(_nanosleep, nanosleep)
576 __strong_alias(_open, open)
577 __strong_alias(_poll, poll)
578 __weak_alias(pollts, _pollts)
579 __strong_alias(_pread, pread)
580 __strong_alias(_pselect, pselect)
581 __strong_alias(_pwrite, pwrite)
582 __strong_alias(_read, read)
583 __strong_alias(_readv, readv)
584 __strong_alias(_select, select)
585 __strong_alias(_wait4, wait4)
586 __strong_alias(_write, write)
587 __strong_alias(_writev, writev)
588
589 #endif /* !lint */
590