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