xref: /netbsd-src/lib/libpthread/pthread_cancelstub.c (revision 5bbd2a12505d72a8177929a37b5cee489d0a1cfd)
1 /*	$NetBSD: pthread_cancelstub.c,v 1.37 2012/04/04 17:47:03 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.37 2012/04/04 17:47:03 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 
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