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.35.6.1 2012/04/09 18:15:27 riz 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
86int	pthread__cancel_stub_binder;
87
88int	_sys_accept(int, struct sockaddr *, socklen_t *);
89int	_sys___aio_suspend50(const struct aiocb * const [], int,
90	    const struct timespec *);
91int	__aio_suspend50(const struct aiocb * const [], int,
92	    const struct timespec *);
93int	_sys_close(int);
94int	_sys_connect(int, const struct sockaddr *, socklen_t);
95int	_sys_fcntl(int, int, ...);
96int	_sys_fdatasync(int);
97int	_sys_fsync(int);
98int	_sys_fsync_range(int, int, off_t, off_t);
99int	_sys___kevent50(int, const struct kevent *, size_t, struct kevent *,
100	    size_t, const struct timespec *);
101int	_sys_mq_send(mqd_t, const char *, size_t, unsigned);
102ssize_t	_sys_mq_receive(mqd_t, char *, size_t, unsigned *);
103int	_sys___mq_timedsend50(mqd_t, const char *, size_t, unsigned,
104	    const struct timespec *);
105ssize_t	_sys___mq_timedreceive50(mqd_t, char *, size_t, unsigned *,
106	    const struct timespec *);
107ssize_t	_sys_msgrcv(int, void *, size_t, long, int);
108int	_sys_msgsnd(int, const void *, size_t, int);
109int	_sys___msync13(void *, size_t, int);
110int	_sys___nanosleep50(const struct timespec *, struct timespec *);
111int	__nanosleep50(const struct timespec *, struct timespec *);
112int	_sys_open(const char *, int, ...);
113int	_sys_poll(struct pollfd *, nfds_t, int);
114int	_sys___pollts50(struct pollfd *, nfds_t, const struct timespec *,
115	    const sigset_t *);
116ssize_t	_sys_pread(int, void *, size_t, off_t);
117int	_sys___pselect50(int, fd_set *, fd_set *, fd_set *,
118	    const struct timespec *, const sigset_t *);
119ssize_t	_sys_pwrite(int, const void *, size_t, off_t);
120ssize_t	_sys_read(int, void *, size_t);
121ssize_t	_sys_readv(int, const struct iovec *, int);
122int	_sys___select50(int, fd_set *, fd_set *, fd_set *, struct timeval *);
123int	_sys___wait450(pid_t, int *, int, struct rusage *);
124ssize_t	_sys_write(int, const void *, size_t);
125ssize_t	_sys_writev(int, const struct iovec *, int);
126int	_sys___sigsuspend14(const sigset_t *);
127int	____sigtimedwait50(const sigset_t * __restrict, siginfo_t * __restrict,
128	    struct timespec * __restrict);
129int	__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
138int
139accept(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
152int
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
167int
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
182int
183close(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
196int
197connect(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
210int
211fcntl(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
227int
228fdatasync(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
241int
242fsync(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
255int
256fsync_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
269int
270mq_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
283ssize_t
284mq_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
297int
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
312ssize_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
327ssize_t
328msgrcv(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
341int
342msgsnd(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
355int
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
369int
370open(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
386int
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
404int
405poll(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
418int
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
433ssize_t
434pread(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
447int
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
463ssize_t
464pwrite(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
477ssize_t
478read(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
491ssize_t
492readv(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
505int
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
520pid_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
534ssize_t
535write(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
548ssize_t
549writev(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
562int
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
576int
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
598int
599sigwait(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