pthread_cancelstub.c revision 1.35 1 /* $NetBSD: pthread_cancelstub.c,v 1.35 2011/04/22 14:18:34 joerg 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 /* Disable namespace mangling, Fortification is useless here anyway. */
33 #undef _FORTIFY_SOURCE
34
35 #include <sys/cdefs.h>
36 __RCSID("$NetBSD: pthread_cancelstub.c,v 1.35 2011/04/22 14:18:34 joerg Exp $");
37
38 #ifndef lint
39
40
41 /*
42 * This is necessary because the names are always weak (they are not
43 * POSIX functions).
44 */
45 #define fsync_range _fsync_range
46 #define pollts _pollts
47
48 /*
49 * XXX this is necessary to get the prototypes for the __sigsuspend14
50 * XXX and __msync13 internal names, instead of the application-visible
51 * XXX sigsuspend and msync names. It's kind of gross, but we're pretty
52 * XXX intimate with libc already.
53 */
54 #define __LIBC12_SOURCE__
55
56 #include <sys/msg.h>
57 #include <sys/types.h>
58 #include <sys/uio.h>
59 #include <sys/wait.h>
60 #include <aio.h>
61 #include <fcntl.h>
62 #include <mqueue.h>
63 #include <poll.h>
64 #include <stdarg.h>
65 #include <unistd.h>
66
67 #include <signal.h>
68 #include <sys/mman.h>
69 #include <sys/select.h>
70 #include <sys/socket.h>
71 #include <sys/event.h>
72
73 #include <compat/sys/mman.h>
74 #include <compat/sys/poll.h>
75 #include <compat/sys/select.h>
76 #include <compat/sys/event.h>
77 #include <compat/sys/wait.h>
78 #include <compat/include/mqueue.h>
79 #include <compat/include/signal.h>
80
81 #include "pthread.h"
82 #include "pthread_int.h"
83
84 int pthread__cancel_stub_binder;
85
86 int _sys_accept(int, struct sockaddr *, socklen_t *);
87 int _sys___aio_suspend50(const struct aiocb * const [], int,
88 const struct timespec *);
89 int __aio_suspend50(const struct aiocb * const [], int,
90 const struct timespec *);
91 int _sys_close(int);
92 int _sys_connect(int, const struct sockaddr *, socklen_t);
93 int _sys_fcntl(int, int, ...);
94 int _sys_fdatasync(int);
95 int _sys_fsync(int);
96 int _sys_fsync_range(int, int, off_t, off_t);
97 int _sys___kevent50(int, const struct kevent *, size_t, struct kevent *,
98 size_t, const struct timespec *);
99 int _sys_mq_send(mqd_t, const char *, size_t, unsigned);
100 ssize_t _sys_mq_receive(mqd_t, char *, size_t, unsigned *);
101 int _sys___mq_timedsend50(mqd_t, const char *, size_t, unsigned,
102 const struct timespec *);
103 ssize_t _sys___mq_timedreceive50(mqd_t, char *, size_t, unsigned *,
104 const struct timespec *);
105 ssize_t _sys_msgrcv(int, void *, size_t, long, int);
106 int _sys_msgsnd(int, const void *, size_t, int);
107 int _sys___msync13(void *, size_t, int);
108 int _sys___nanosleep50(const struct timespec *, struct timespec *);
109 int __nanosleep50(const struct timespec *, struct timespec *);
110 int _sys_open(const char *, int, ...);
111 int _sys_poll(struct pollfd *, nfds_t, int);
112 int _sys___pollts50(struct pollfd *, nfds_t, const struct timespec *,
113 const sigset_t *);
114 ssize_t _sys_pread(int, void *, size_t, off_t);
115 int _sys___pselect50(int, fd_set *, fd_set *, fd_set *,
116 const struct timespec *, const sigset_t *);
117 ssize_t _sys_pwrite(int, const void *, size_t, off_t);
118 ssize_t _sys_read(int, void *, size_t);
119 ssize_t _sys_readv(int, const struct iovec *, int);
120 int _sys___select50(int, fd_set *, fd_set *, fd_set *, struct timeval *);
121 int _sys___wait450(pid_t, int *, int, struct rusage *);
122 ssize_t _sys_write(int, const void *, size_t);
123 ssize_t _sys_writev(int, const struct iovec *, int);
124 int _sys___sigsuspend14(const sigset_t *);
125 int ____sigtimedwait50(const sigset_t * __restrict, siginfo_t * __restrict,
126 struct timespec * __restrict);
127 int __sigsuspend14(const sigset_t *);
128
129 #define TESTCANCEL(id) do { \
130 if (__predict_false((id)->pt_cancel)) \
131 pthread__cancelled(); \
132 } while (/*CONSTCOND*/0)
133
134
135 int
136 accept(int s, struct sockaddr *addr, socklen_t *addrlen)
137 {
138 int retval;
139 pthread_t self;
140
141 self = pthread__self();
142 TESTCANCEL(self);
143 retval = _sys_accept(s, addr, addrlen);
144 TESTCANCEL(self);
145
146 return retval;
147 }
148
149 int
150 __aio_suspend50(const struct aiocb * const list[], int nent,
151 const struct timespec *timeout)
152 {
153 int retval;
154 pthread_t self;
155
156 self = pthread__self();
157 TESTCANCEL(self);
158 retval = _sys___aio_suspend50(list, nent, timeout);
159 TESTCANCEL(self);
160
161 return retval;
162 }
163
164 int
165 __kevent50(int fd, const struct kevent *ev, size_t nev, struct kevent *rev,
166 size_t nrev, const struct timespec *ts)
167 {
168 int retval;
169 pthread_t self;
170
171 self = pthread__self();
172 TESTCANCEL(self);
173 retval = _sys___kevent50(fd, ev, nev, rev, nrev, ts);
174 TESTCANCEL(self);
175
176 return retval;
177 }
178
179 int
180 close(int d)
181 {
182 int retval;
183 pthread_t self;
184
185 self = pthread__self();
186 TESTCANCEL(self);
187 retval = _sys_close(d);
188 TESTCANCEL(self);
189
190 return retval;
191 }
192
193 int
194 connect(int s, const struct sockaddr *addr, socklen_t namelen)
195 {
196 int retval;
197 pthread_t self;
198
199 self = pthread__self();
200 TESTCANCEL(self);
201 retval = _sys_connect(s, addr, namelen);
202 TESTCANCEL(self);
203
204 return retval;
205 }
206
207 int
208 fcntl(int fd, int cmd, ...)
209 {
210 int retval;
211 pthread_t self;
212 va_list ap;
213
214 self = pthread__self();
215 TESTCANCEL(self);
216 va_start(ap, cmd);
217 retval = _sys_fcntl(fd, cmd, va_arg(ap, void *));
218 va_end(ap);
219 TESTCANCEL(self);
220
221 return retval;
222 }
223
224 int
225 fdatasync(int d)
226 {
227 int retval;
228 pthread_t self;
229
230 self = pthread__self();
231 TESTCANCEL(self);
232 retval = _sys_fdatasync(d);
233 TESTCANCEL(self);
234
235 return retval;
236 }
237
238 int
239 fsync(int d)
240 {
241 int retval;
242 pthread_t self;
243
244 self = pthread__self();
245 TESTCANCEL(self);
246 retval = _sys_fsync(d);
247 TESTCANCEL(self);
248
249 return retval;
250 }
251
252 int
253 fsync_range(int d, int f, off_t s, off_t e)
254 {
255 int retval;
256 pthread_t self;
257
258 self = pthread__self();
259 TESTCANCEL(self);
260 retval = _sys_fsync_range(d, f, s, e);
261 TESTCANCEL(self);
262
263 return retval;
264 }
265
266 int
267 mq_send(mqd_t mqdes, const char *msg_ptr, size_t msg_len, unsigned msg_prio)
268 {
269 int retval;
270 pthread_t self;
271
272 self = pthread__self();
273 TESTCANCEL(self);
274 retval = _sys_mq_send(mqdes, msg_ptr, msg_len, msg_prio);
275 TESTCANCEL(self);
276
277 return retval;
278 }
279
280 ssize_t
281 mq_receive(mqd_t mqdes, char *msg_ptr, size_t msg_len, unsigned *msg_prio)
282 {
283 ssize_t retval;
284 pthread_t self;
285
286 self = pthread__self();
287 TESTCANCEL(self);
288 retval = _sys_mq_receive(mqdes, msg_ptr, msg_len, msg_prio);
289 TESTCANCEL(self);
290
291 return retval;
292 }
293
294 int
295 __mq_timedsend50(mqd_t mqdes, const char *msg_ptr, size_t msg_len,
296 unsigned msg_prio, const struct timespec *abst)
297 {
298 int retval;
299 pthread_t self;
300
301 self = pthread__self();
302 TESTCANCEL(self);
303 retval = _sys___mq_timedsend50(mqdes, msg_ptr, msg_len, msg_prio, abst);
304 TESTCANCEL(self);
305
306 return retval;
307 }
308
309 ssize_t
310 __mq_timedreceive50(mqd_t mqdes, char *msg_ptr, size_t msg_len, unsigned *msg_prio,
311 const struct timespec *abst)
312 {
313 ssize_t retval;
314 pthread_t self;
315
316 self = pthread__self();
317 TESTCANCEL(self);
318 retval = _sys___mq_timedreceive50(mqdes, msg_ptr, msg_len, msg_prio, abst);
319 TESTCANCEL(self);
320
321 return retval;
322 }
323
324 ssize_t
325 msgrcv(int msgid, void *msgp, size_t msgsz, long msgtyp, int msgflg)
326 {
327 ssize_t retval;
328 pthread_t self;
329
330 self = pthread__self();
331 TESTCANCEL(self);
332 retval = _sys_msgrcv(msgid, msgp, msgsz, msgtyp, msgflg);
333 TESTCANCEL(self);
334
335 return retval;
336 }
337
338 int
339 msgsnd(int msgid, const void *msgp, size_t msgsz, int msgflg)
340 {
341 int retval;
342 pthread_t self;
343
344 self = pthread__self();
345 TESTCANCEL(self);
346 retval = _sys_msgsnd(msgid, msgp, msgsz, msgflg);
347 TESTCANCEL(self);
348
349 return retval;
350 }
351
352 int
353 __msync13(void *addr, size_t len, int flags)
354 {
355 int retval;
356 pthread_t self;
357
358 self = pthread__self();
359 TESTCANCEL(self);
360 retval = _sys___msync13(addr, len, flags);
361 TESTCANCEL(self);
362
363 return retval;
364 }
365
366 int
367 open(const char *path, int flags, ...)
368 {
369 int retval;
370 pthread_t self;
371 va_list ap;
372
373 self = pthread__self();
374 TESTCANCEL(self);
375 va_start(ap, flags);
376 retval = _sys_open(path, flags, va_arg(ap, mode_t));
377 va_end(ap);
378 TESTCANCEL(self);
379
380 return retval;
381 }
382
383 int
384 __nanosleep50(const struct timespec *rqtp, struct timespec *rmtp)
385 {
386 int retval;
387 pthread_t self;
388
389 self = pthread__self();
390 TESTCANCEL(self);
391 /*
392 * For now, just nanosleep. In the future, maybe pass a ucontext_t
393 * to _lwp_nanosleep() and allow it to recycle our kernel stack.
394 */
395 retval = _sys___nanosleep50(rqtp, rmtp);
396 TESTCANCEL(self);
397
398 return retval;
399 }
400
401 int
402 poll(struct pollfd *fds, nfds_t nfds, int timeout)
403 {
404 int retval;
405 pthread_t self;
406
407 self = pthread__self();
408 TESTCANCEL(self);
409 retval = _sys_poll(fds, nfds, timeout);
410 TESTCANCEL(self);
411
412 return retval;
413 }
414
415 int
416 __pollts50(struct pollfd *fds, nfds_t nfds, const struct timespec *ts,
417 const sigset_t *sigmask)
418 {
419 int retval;
420 pthread_t self;
421
422 self = pthread__self();
423 TESTCANCEL(self);
424 retval = _sys___pollts50(fds, nfds, ts, sigmask);
425 TESTCANCEL(self);
426
427 return retval;
428 }
429
430 ssize_t
431 pread(int d, 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_pread(d, buf, nbytes, offset);
439 TESTCANCEL(self);
440
441 return retval;
442 }
443
444 int
445 __pselect50(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
446 const struct timespec *timeout, const sigset_t *sigmask)
447 {
448 int retval;
449 pthread_t self;
450
451 self = pthread__self();
452 TESTCANCEL(self);
453 retval = _sys___pselect50(nfds, readfds, writefds, exceptfds, timeout,
454 sigmask);
455 TESTCANCEL(self);
456
457 return retval;
458 }
459
460 ssize_t
461 pwrite(int d, const void *buf, size_t nbytes, off_t offset)
462 {
463 ssize_t retval;
464 pthread_t self;
465
466 self = pthread__self();
467 TESTCANCEL(self);
468 retval = _sys_pwrite(d, buf, nbytes, offset);
469 TESTCANCEL(self);
470
471 return retval;
472 }
473
474 ssize_t
475 read(int d, void *buf, size_t nbytes)
476 {
477 ssize_t retval;
478 pthread_t self;
479
480 self = pthread__self();
481 TESTCANCEL(self);
482 retval = _sys_read(d, buf, nbytes);
483 TESTCANCEL(self);
484
485 return retval;
486 }
487
488 ssize_t
489 readv(int d, const struct iovec *iov, int iovcnt)
490 {
491 ssize_t retval;
492 pthread_t self;
493
494 self = pthread__self();
495 TESTCANCEL(self);
496 retval = _sys_readv(d, iov, iovcnt);
497 TESTCANCEL(self);
498
499 return retval;
500 }
501
502 int
503 __select50(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
504 struct timeval *timeout)
505 {
506 int retval;
507 pthread_t self;
508
509 self = pthread__self();
510 TESTCANCEL(self);
511 retval = _sys___select50(nfds, readfds, writefds, exceptfds, timeout);
512 TESTCANCEL(self);
513
514 return retval;
515 }
516
517 pid_t
518 __wait450(pid_t wpid, int *status, int options, struct rusage *rusage)
519 {
520 pid_t retval;
521 pthread_t self;
522
523 self = pthread__self();
524 TESTCANCEL(self);
525 retval = _sys___wait450(wpid, status, options, rusage);
526 TESTCANCEL(self);
527
528 return retval;
529 }
530
531 ssize_t
532 write(int d, const void *buf, size_t nbytes)
533 {
534 ssize_t retval;
535 pthread_t self;
536
537 self = pthread__self();
538 TESTCANCEL(self);
539 retval = _sys_write(d, buf, nbytes);
540 TESTCANCEL(self);
541
542 return retval;
543 }
544
545 ssize_t
546 writev(int d, const struct iovec *iov, int iovcnt)
547 {
548 ssize_t retval;
549 pthread_t self;
550
551 self = pthread__self();
552 TESTCANCEL(self);
553 retval = _sys_writev(d, iov, iovcnt);
554 TESTCANCEL(self);
555
556 return retval;
557 }
558
559 int
560 __sigsuspend14(const sigset_t *sigmask)
561 {
562 pthread_t self;
563 int retval;
564
565 self = pthread__self();
566 TESTCANCEL(self);
567 retval = _sys___sigsuspend14(sigmask);
568 TESTCANCEL(self);
569
570 return retval;
571 }
572
573 int
574 __sigtimedwait50(const sigset_t * __restrict set, siginfo_t * __restrict info,
575 const struct timespec * __restrict timeout)
576 {
577 pthread_t self;
578 int retval;
579 struct timespec tout, *tp;
580 if (timeout) {
581 tout = *timeout;
582 tp = &tout;
583 } else
584 tp = NULL;
585
586 self = pthread__self();
587 TESTCANCEL(self);
588 retval = ____sigtimedwait50(set, info, tp);
589 TESTCANCEL(self);
590
591 return retval;
592 }
593
594 __strong_alias(_close, close)
595 __strong_alias(_fcntl, fcntl)
596 __strong_alias(_fdatasync, fdatasync)
597 __strong_alias(_fsync, fsync)
598 __weak_alias(fsync_range, _fsync_range)
599 __strong_alias(_mq_send, mq_send)
600 __strong_alias(_mq_receive, mq_receive)
601 __strong_alias(_msgrcv, msgrcv)
602 __strong_alias(_msgsnd, msgsnd)
603 __strong_alias(___msync13, __msync13)
604 __strong_alias(___nanosleep50, __nanosleep50)
605 __strong_alias(_open, open)
606 __strong_alias(_poll, poll)
607 __strong_alias(_pread, pread)
608 __strong_alias(_pwrite, pwrite)
609 __strong_alias(_read, read)
610 __strong_alias(_readv, readv)
611 __strong_alias(_write, write)
612 __strong_alias(_writev, writev)
613
614 #endif /* !lint */
615