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