pthread_cancelstub.c revision 1.40 1 /* $NetBSD: pthread_cancelstub.c,v 1.40 2021/10/01 20:13:38 christos 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.40 2021/10/01 20:13:38 christos 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_clock_nanosleep(clockid_t clock_id, int flags,
94 const struct timespec *rqtp, struct timespec *rmtp);
95 int _sys_close(int);
96 int _sys_connect(int, const struct sockaddr *, socklen_t);
97 int _sys_fcntl(int, int, ...);
98 int _sys_fdatasync(int);
99 int _sys_fsync(int);
100 int _sys_fsync_range(int, int, off_t, off_t);
101 int _sys___kevent50(int, const struct kevent *, size_t, struct kevent *,
102 size_t, const struct timespec *);
103 int _sys_mq_send(mqd_t, const char *, size_t, unsigned);
104 ssize_t _sys_mq_receive(mqd_t, char *, size_t, unsigned *);
105 int _sys___mq_timedsend50(mqd_t, const char *, size_t, unsigned,
106 const struct timespec *);
107 ssize_t _sys___mq_timedreceive50(mqd_t, char *, size_t, unsigned *,
108 const struct timespec *);
109 ssize_t _sys_msgrcv(int, void *, size_t, long, int);
110 int _sys_msgsnd(int, const void *, size_t, int);
111 int _sys___msync13(void *, size_t, int);
112 int _sys___nanosleep50(const struct timespec *, struct timespec *);
113 int __nanosleep50(const struct timespec *, struct timespec *);
114 int _sys_open(const char *, int, ...);
115 int _sys_openat(int, const char *, int, ...);
116 int _sys_poll(struct pollfd *, nfds_t, int);
117 int _sys___pollts50(struct pollfd *, nfds_t, const struct timespec *,
118 const sigset_t *);
119 ssize_t _sys_pread(int, void *, size_t, off_t);
120 int _sys___pselect50(int, fd_set *, fd_set *, fd_set *,
121 const struct timespec *, const sigset_t *);
122 ssize_t _sys_pwrite(int, const void *, size_t, off_t);
123 ssize_t _sys_read(int, void *, size_t);
124 ssize_t _sys_readv(int, const struct iovec *, int);
125 ssize_t _sys_recvfrom(int, void * restrict, size_t, int,
126 struct sockaddr * restrict, socklen_t * restrict);
127 ssize_t _sys_recvmsg(int, struct msghdr *, int);
128 int _sys_recvmmsg(int, struct mmsghdr *, unsigned int, unsigned int,
129 struct timespec *);
130 ssize_t _sys_sendto(int, const void *, size_t, int, const struct sockaddr *,
131 socklen_t);
132 ssize_t _sys_sendmsg(int, const struct msghdr *, int);
133 int _sys_sendmmsg(int, struct mmsghdr *, unsigned int, unsigned int);
134 int _sys___select50(int, fd_set *, fd_set *, fd_set *, struct timeval *);
135 int _sys___wait450(pid_t, int *, int, struct rusage *);
136 ssize_t _sys_write(int, const void *, size_t);
137 ssize_t _sys_writev(int, const struct iovec *, int);
138 int _sys___sigsuspend14(const sigset_t *);
139 int ____sigtimedwait50(const sigset_t * __restrict, siginfo_t * __restrict,
140 struct timespec * __restrict);
141 int __sigsuspend14(const sigset_t *);
142
143 #define TESTCANCEL(id) do { \
144 if (__predict_true(!__uselibcstub) && \
145 __predict_false((id)->pt_cancel)) \
146 pthread__cancelled(); \
147 } while (/*CONSTCOND*/0)
148
149
150 int
151 accept(int s, struct sockaddr *addr, socklen_t *addrlen)
152 {
153 int retval;
154 pthread_t self;
155
156 self = pthread__self();
157 TESTCANCEL(self);
158 retval = _sys_accept(s, addr, addrlen);
159 TESTCANCEL(self);
160
161 return retval;
162 }
163
164 int
165 __aio_suspend50(const struct aiocb * const list[], int nent,
166 const struct timespec *timeout)
167 {
168 int retval;
169 pthread_t self;
170
171 self = pthread__self();
172 TESTCANCEL(self);
173 retval = _sys___aio_suspend50(list, nent, timeout);
174 TESTCANCEL(self);
175
176 return retval;
177 }
178
179 int
180 __kevent50(int fd, const struct kevent *ev, size_t nev, struct kevent *rev,
181 size_t nrev, const struct timespec *ts)
182 {
183 int retval;
184 pthread_t self;
185
186 self = pthread__self();
187 TESTCANCEL(self);
188 retval = _sys___kevent50(fd, ev, nev, rev, nrev, ts);
189 TESTCANCEL(self);
190
191 return retval;
192 }
193
194 int
195 clock_nanosleep(clockid_t clock_id, int flags,
196 const struct timespec *rqtp, struct timespec *rmtp)
197 {
198 int retval;
199 pthread_t self;
200
201 self = pthread__self();
202 TESTCANCEL(self);
203 retval = _sys_clock_nanosleep(clock_id, flags, rqtp, rmtp);
204 TESTCANCEL(self);
205
206 return retval;
207 }
208
209 int
210 close(int d)
211 {
212 int retval;
213 pthread_t self;
214
215 self = pthread__self();
216 TESTCANCEL(self);
217 retval = _sys_close(d);
218 TESTCANCEL(self);
219
220 return retval;
221 }
222
223 int
224 connect(int s, const struct sockaddr *addr, socklen_t namelen)
225 {
226 int retval;
227 pthread_t self;
228
229 self = pthread__self();
230 TESTCANCEL(self);
231 retval = _sys_connect(s, addr, namelen);
232 TESTCANCEL(self);
233
234 return retval;
235 }
236
237 int
238 fcntl(int fd, int cmd, ...)
239 {
240 int retval;
241 pthread_t self;
242 va_list ap;
243
244 self = pthread__self();
245 TESTCANCEL(self);
246 va_start(ap, cmd);
247 retval = _sys_fcntl(fd, cmd, va_arg(ap, void *));
248 va_end(ap);
249 TESTCANCEL(self);
250
251 return retval;
252 }
253
254 int
255 fdatasync(int d)
256 {
257 int retval;
258 pthread_t self;
259
260 self = pthread__self();
261 TESTCANCEL(self);
262 retval = _sys_fdatasync(d);
263 TESTCANCEL(self);
264
265 return retval;
266 }
267
268 int
269 fsync(int d)
270 {
271 int retval;
272 pthread_t self;
273
274 self = pthread__self();
275 TESTCANCEL(self);
276 retval = _sys_fsync(d);
277 TESTCANCEL(self);
278
279 return retval;
280 }
281
282 int
283 fsync_range(int d, int f, off_t s, off_t e)
284 {
285 int retval;
286 pthread_t self;
287
288 self = pthread__self();
289 TESTCANCEL(self);
290 retval = _sys_fsync_range(d, f, s, e);
291 TESTCANCEL(self);
292
293 return retval;
294 }
295
296 int
297 mq_send(mqd_t mqdes, const char *msg_ptr, size_t msg_len, unsigned msg_prio)
298 {
299 int retval;
300 pthread_t self;
301
302 self = pthread__self();
303 TESTCANCEL(self);
304 retval = _sys_mq_send(mqdes, msg_ptr, msg_len, msg_prio);
305 TESTCANCEL(self);
306
307 return retval;
308 }
309
310 ssize_t
311 mq_receive(mqd_t mqdes, char *msg_ptr, size_t msg_len, unsigned *msg_prio)
312 {
313 ssize_t retval;
314 pthread_t self;
315
316 self = pthread__self();
317 TESTCANCEL(self);
318 retval = _sys_mq_receive(mqdes, msg_ptr, msg_len, msg_prio);
319 TESTCANCEL(self);
320
321 return retval;
322 }
323
324 int
325 __mq_timedsend50(mqd_t mqdes, const char *msg_ptr, size_t msg_len,
326 unsigned msg_prio, const struct timespec *abst)
327 {
328 int retval;
329 pthread_t self;
330
331 self = pthread__self();
332 TESTCANCEL(self);
333 retval = _sys___mq_timedsend50(mqdes, msg_ptr, msg_len, msg_prio, abst);
334 TESTCANCEL(self);
335
336 return retval;
337 }
338
339 ssize_t
340 __mq_timedreceive50(mqd_t mqdes, char *msg_ptr, size_t msg_len, unsigned *msg_prio,
341 const struct timespec *abst)
342 {
343 ssize_t retval;
344 pthread_t self;
345
346 self = pthread__self();
347 TESTCANCEL(self);
348 retval = _sys___mq_timedreceive50(mqdes, msg_ptr, msg_len, msg_prio, abst);
349 TESTCANCEL(self);
350
351 return retval;
352 }
353
354 ssize_t
355 msgrcv(int msgid, void *msgp, size_t msgsz, long msgtyp, int msgflg)
356 {
357 ssize_t retval;
358 pthread_t self;
359
360 self = pthread__self();
361 TESTCANCEL(self);
362 retval = _sys_msgrcv(msgid, msgp, msgsz, msgtyp, msgflg);
363 TESTCANCEL(self);
364
365 return retval;
366 }
367
368 int
369 msgsnd(int msgid, const void *msgp, size_t msgsz, int msgflg)
370 {
371 int retval;
372 pthread_t self;
373
374 self = pthread__self();
375 TESTCANCEL(self);
376 retval = _sys_msgsnd(msgid, msgp, msgsz, msgflg);
377 TESTCANCEL(self);
378
379 return retval;
380 }
381
382 int
383 __msync13(void *addr, size_t len, int flags)
384 {
385 int retval;
386 pthread_t self;
387
388 self = pthread__self();
389 TESTCANCEL(self);
390 retval = _sys___msync13(addr, len, flags);
391 TESTCANCEL(self);
392
393 return retval;
394 }
395
396 int
397 open(const char *path, int flags, ...)
398 {
399 int retval;
400 pthread_t self;
401 va_list ap;
402
403 self = pthread__self();
404 TESTCANCEL(self);
405 va_start(ap, flags);
406 retval = _sys_open(path, flags, va_arg(ap, mode_t));
407 va_end(ap);
408 TESTCANCEL(self);
409
410 return retval;
411 }
412
413 int
414 openat(int fd, const char *path, int flags, ...)
415 {
416 int retval;
417 pthread_t self;
418 va_list ap;
419
420 self = pthread__self();
421 TESTCANCEL(self);
422 va_start(ap, flags);
423 retval = _sys_openat(fd, path, flags, va_arg(ap, mode_t));
424 va_end(ap);
425 TESTCANCEL(self);
426
427 return retval;
428 }
429
430 int
431 __nanosleep50(const struct timespec *rqtp, struct timespec *rmtp)
432 {
433 int retval;
434 pthread_t self;
435
436 self = pthread__self();
437 TESTCANCEL(self);
438 /*
439 * For now, just nanosleep. In the future, maybe pass a ucontext_t
440 * to _lwp_nanosleep() and allow it to recycle our kernel stack.
441 */
442 retval = _sys___nanosleep50(rqtp, rmtp);
443 TESTCANCEL(self);
444
445 return retval;
446 }
447
448 int
449 poll(struct pollfd *fds, nfds_t nfds, int timeout)
450 {
451 int retval;
452 pthread_t self;
453
454 self = pthread__self();
455 TESTCANCEL(self);
456 retval = _sys_poll(fds, nfds, timeout);
457 TESTCANCEL(self);
458
459 return retval;
460 }
461
462 int
463 __pollts50(struct pollfd *fds, nfds_t nfds, const struct timespec *ts,
464 const sigset_t *sigmask)
465 {
466 int retval;
467 pthread_t self;
468
469 self = pthread__self();
470 TESTCANCEL(self);
471 retval = _sys___pollts50(fds, nfds, ts, sigmask);
472 TESTCANCEL(self);
473
474 return retval;
475 }
476
477 ssize_t
478 pread(int d, void *buf, size_t nbytes, off_t offset)
479 {
480 ssize_t retval;
481 pthread_t self;
482
483 self = pthread__self();
484 TESTCANCEL(self);
485 retval = _sys_pread(d, buf, nbytes, offset);
486 TESTCANCEL(self);
487
488 return retval;
489 }
490
491 int
492 __pselect50(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
493 const struct timespec *timeout, const sigset_t *sigmask)
494 {
495 int retval;
496 pthread_t self;
497
498 self = pthread__self();
499 TESTCANCEL(self);
500 retval = _sys___pselect50(nfds, readfds, writefds, exceptfds, timeout,
501 sigmask);
502 TESTCANCEL(self);
503
504 return retval;
505 }
506
507 ssize_t
508 pwrite(int d, const void *buf, size_t nbytes, off_t offset)
509 {
510 ssize_t retval;
511 pthread_t self;
512
513 self = pthread__self();
514 TESTCANCEL(self);
515 retval = _sys_pwrite(d, buf, nbytes, offset);
516 TESTCANCEL(self);
517
518 return retval;
519 }
520
521 ssize_t
522 read(int d, void *buf, size_t nbytes)
523 {
524 ssize_t retval;
525 pthread_t self;
526
527 self = pthread__self();
528 TESTCANCEL(self);
529 retval = _sys_read(d, buf, nbytes);
530 TESTCANCEL(self);
531
532 return retval;
533 }
534
535 ssize_t
536 readv(int d, const struct iovec *iov, int iovcnt)
537 {
538 ssize_t retval;
539 pthread_t self;
540
541 self = pthread__self();
542 TESTCANCEL(self);
543 retval = _sys_readv(d, iov, iovcnt);
544 TESTCANCEL(self);
545
546 return retval;
547 }
548
549 ssize_t
550 recvfrom(int s, void * restrict buf, size_t len, int flags,
551 struct sockaddr * restrict from, socklen_t * restrict fromlen)
552 {
553 ssize_t retval;
554 pthread_t self;
555
556 self = pthread__self();
557 TESTCANCEL(self);
558 retval = _sys_recvfrom(s, buf, len, flags, from, fromlen);
559 TESTCANCEL(self);
560
561 return retval;
562 }
563
564 ssize_t
565 recvmsg(int s, struct msghdr *msg, int flags)
566 {
567 ssize_t retval;
568 pthread_t self;
569
570 self = pthread__self();
571 TESTCANCEL(self);
572 retval = _sys_recvmsg(s, msg, flags);
573 TESTCANCEL(self);
574
575 return retval;
576 }
577
578 int
579 recvmmsg(int s, struct mmsghdr *mmsg, unsigned int vlen,
580 unsigned int flags, struct timespec *timeout)
581 {
582 ssize_t retval;
583 pthread_t self;
584
585 self = pthread__self();
586 TESTCANCEL(self);
587 retval = _sys_recvmmsg(s, mmsg, vlen, flags, timeout);
588 TESTCANCEL(self);
589
590 return retval;
591 }
592
593 int
594 __select50(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
595 struct timeval *timeout)
596 {
597 int retval;
598 pthread_t self;
599
600 self = pthread__self();
601 TESTCANCEL(self);
602 retval = _sys___select50(nfds, readfds, writefds, exceptfds, timeout);
603 TESTCANCEL(self);
604
605 return retval;
606 }
607
608 ssize_t
609 sendto(int s, const void *msg, size_t len, int flags,
610 const struct sockaddr *to, socklen_t tolen)
611 {
612 int retval;
613 pthread_t self;
614
615 self = pthread__self();
616 TESTCANCEL(self);
617 retval = _sys_sendto(s, msg, len, flags, to, tolen);
618 TESTCANCEL(self);
619
620 return retval;
621 }
622
623 ssize_t
624 sendmsg(int s, const struct msghdr *msg, int flags)
625 {
626 int retval;
627 pthread_t self;
628
629 self = pthread__self();
630 TESTCANCEL(self);
631 retval = _sys_sendmsg(s, msg, flags);
632 TESTCANCEL(self);
633
634 return retval;
635 }
636
637 int
638 sendmmsg(int s, struct mmsghdr *mmsg, unsigned int vlen,
639 unsigned int flags)
640 {
641 int retval;
642 pthread_t self;
643
644 self = pthread__self();
645 TESTCANCEL(self);
646 retval = _sys_sendmmsg(s, mmsg, vlen, flags);
647 TESTCANCEL(self);
648
649 return retval;
650 }
651
652
653 pid_t
654 __wait450(pid_t wpid, int *status, int options, struct rusage *rusage)
655 {
656 pid_t retval;
657 pthread_t self;
658
659 self = pthread__self();
660 TESTCANCEL(self);
661 retval = _sys___wait450(wpid, status, options, rusage);
662 TESTCANCEL(self);
663
664 return retval;
665 }
666
667 ssize_t
668 write(int d, const void *buf, size_t nbytes)
669 {
670 ssize_t retval;
671 pthread_t self;
672
673 self = pthread__self();
674 TESTCANCEL(self);
675 retval = _sys_write(d, buf, nbytes);
676 TESTCANCEL(self);
677
678 return retval;
679 }
680
681 ssize_t
682 writev(int d, const struct iovec *iov, int iovcnt)
683 {
684 ssize_t retval;
685 pthread_t self;
686
687 self = pthread__self();
688 TESTCANCEL(self);
689 retval = _sys_writev(d, iov, iovcnt);
690 TESTCANCEL(self);
691
692 return retval;
693 }
694
695 int
696 __sigsuspend14(const sigset_t *sigmask)
697 {
698 pthread_t self;
699 int retval;
700
701 self = pthread__self();
702 TESTCANCEL(self);
703 retval = _sys___sigsuspend14(sigmask);
704 TESTCANCEL(self);
705
706 return retval;
707 }
708
709 int
710 __sigtimedwait50(const sigset_t * __restrict set, siginfo_t * __restrict info,
711 const struct timespec * __restrict timeout)
712 {
713 pthread_t self;
714 int retval;
715 struct timespec tout, *tp;
716
717 if (timeout) {
718 tout = *timeout;
719 tp = &tout;
720 } else
721 tp = NULL;
722
723 self = pthread__self();
724 TESTCANCEL(self);
725 retval = ____sigtimedwait50(set, info, tp);
726 TESTCANCEL(self);
727
728 return retval;
729 }
730
731 int
732 sigwait(const sigset_t * __restrict set, int * __restrict sig)
733 {
734 pthread_t self;
735 int saved_errno;
736 int new_errno;
737 int retval;
738
739 self = pthread__self();
740 saved_errno = errno;
741 TESTCANCEL(self);
742 retval = ____sigtimedwait50(set, NULL, NULL);
743 TESTCANCEL(self);
744 new_errno = errno;
745 errno = saved_errno;
746 if (retval < 0) {
747 return new_errno;
748 }
749 *sig = retval;
750 return 0;
751 }
752
753 __strong_alias(_close, close)
754 __strong_alias(_clock_nanosleep, clock_nanosleep)
755 __strong_alias(_fcntl, fcntl)
756 __strong_alias(_fdatasync, fdatasync)
757 __strong_alias(_fsync, fsync)
758 __weak_alias(fsync_range, _fsync_range)
759 __strong_alias(_mq_send, mq_send)
760 __strong_alias(_mq_receive, mq_receive)
761 __strong_alias(_msgrcv, msgrcv)
762 __strong_alias(_msgsnd, msgsnd)
763 __strong_alias(___msync13, __msync13)
764 __strong_alias(___nanosleep50, __nanosleep50)
765 __strong_alias(_open, open)
766 __strong_alias(_openat, openat)
767 __strong_alias(_poll, poll)
768 __strong_alias(_pread, pread)
769 __strong_alias(_pwrite, pwrite)
770 __strong_alias(_read, read)
771 __strong_alias(_readv, readv)
772 __strong_alias(_recvfrom, recvfrom)
773 __strong_alias(_recvmsg, recvmsg)
774 __strong_alias(_recvmmsg, recvmmsg)
775 __strong_alias(_sendmsg, sendmsg)
776 __strong_alias(_sendmmsg, sendmmsg)
777 __strong_alias(_sendto, sendto)
778 __strong_alias(_sigwait, sigwait)
779 __strong_alias(_write, write)
780 __strong_alias(_writev, writev)
781
782 #endif /* !lint */
783