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