xref: /netbsd-src/lib/libpthread/pthread_cancelstub.c (revision ed75d7a867996c84cfa88e3b8906816277e957f7)
1 /*	$NetBSD: pthread_cancelstub.c,v 1.38 2013/03/21 16:49:12 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.38 2013/03/21 16:49:12 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_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