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