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