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