thr_syscalls.c revision 317618
1/*
2 * Copyright (c) 2014 The FreeBSD Foundation.
3 * Copyright (C) 2005 David Xu <davidxu@freebsd.org>.
4 * Copyright (c) 2003 Daniel Eischen <deischen@freebsd.org>.
5 * Copyright (C) 2000 Jason Evans <jasone@freebsd.org>.
6 * All rights reserved.
7 *
8 * Portions of this software were developed by Konstantin Belousov
9 * under sponsorship from the FreeBSD Foundation.
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
14 * 1. Redistributions of source code must retain the above copyright
15 *    notice(s), this list of conditions and the following disclaimer as
16 *    the first lines of this file unmodified other than the possible
17 *    addition of one or more copyright notices.
18 * 2. Redistributions in binary form must reproduce the above copyright
19 *    notice(s), this list of conditions and the following disclaimer in
20 *    the documentation and/or other materials provided with the
21 *    distribution.
22 *
23 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) ``AS IS'' AND ANY
24 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
26 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) BE
27 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
28 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
29 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
30 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
31 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
32 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
33 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34 */
35
36/*
37 * Copyright (c) 1995-1998 John Birrell <jb@cimlogic.com.au>
38 * All rights reserved.
39 *
40 * Redistribution and use in source and binary forms, with or without
41 * modification, are permitted provided that the following conditions
42 * are met:
43 * 1. Redistributions of source code must retain the above copyright
44 *    notice, this list of conditions and the following disclaimer.
45 * 2. Redistributions in binary form must reproduce the above copyright
46 *    notice, this list of conditions and the following disclaimer in the
47 *    documentation and/or other materials provided with the distribution.
48 * 3. Neither the name of the author nor the names of any co-contributors
49 *    may be used to endorse or promote products derived from this software
50 *    without specific prior written permission.
51 *
52 * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
53 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
54 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
55 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
56 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
57 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
58 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
59 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
60 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
61 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
62 * SUCH DAMAGE.
63 *
64 */
65
66#include <sys/cdefs.h>
67__FBSDID("$FreeBSD: stable/11/lib/libthr/thread/thr_syscalls.c 317618 2017-05-01 01:36:54Z vangyzen $");
68
69#include "namespace.h"
70#include <sys/types.h>
71#include <sys/mman.h>
72#include <sys/param.h>
73#include <sys/select.h>
74#include <sys/signalvar.h>
75#include <sys/socket.h>
76#include <sys/stat.h>
77#include <sys/time.h>
78#include <sys/uio.h>
79#include <sys/wait.h>
80#include <aio.h>
81#include <dirent.h>
82#include <errno.h>
83#include <fcntl.h>
84#include <poll.h>
85#include <signal.h>
86#include <stdarg.h>
87#include <stdio.h>
88#include <stdlib.h>
89#include <string.h>
90#include <termios.h>
91#include <unistd.h>
92#include <pthread.h>
93#include "un-namespace.h"
94
95#include "libc_private.h"
96#include "thr_private.h"
97
98static int
99__thr_accept(int s, struct sockaddr *addr, socklen_t *addrlen)
100{
101	struct pthread *curthread;
102	int ret;
103
104	curthread = _get_curthread();
105	_thr_cancel_enter(curthread);
106	ret = __sys_accept(s, addr, addrlen);
107	_thr_cancel_leave(curthread, ret == -1);
108
109 	return (ret);
110}
111
112/*
113 * Cancellation behavior:
114 *   If thread is canceled, no socket is created.
115 */
116static int
117__thr_accept4(int s, struct sockaddr *addr, socklen_t *addrlen, int flags)
118{
119	struct pthread *curthread;
120	int ret;
121
122	curthread = _get_curthread();
123	_thr_cancel_enter(curthread);
124	ret = __sys_accept4(s, addr, addrlen, flags);
125	_thr_cancel_leave(curthread, ret == -1);
126
127 	return (ret);
128}
129
130static int
131__thr_aio_suspend(const struct aiocb * const iocbs[], int niocb, const struct
132    timespec *timeout)
133{
134	struct pthread *curthread;
135	int ret;
136
137	curthread = _get_curthread();
138	_thr_cancel_enter(curthread);
139	ret = __sys_aio_suspend(iocbs, niocb, timeout);
140	_thr_cancel_leave(curthread, 1);
141
142	return (ret);
143}
144
145/*
146 * Cancellation behavior:
147 *   According to manual of close(), the file descriptor is always deleted.
148 *   Here, thread is only canceled after the system call, so the file
149 *   descriptor is always deleted despite whether the thread is canceled
150 *   or not.
151 */
152static int
153__thr_close(int fd)
154{
155	struct pthread *curthread;
156	int ret;
157
158	curthread = _get_curthread();
159	_thr_cancel_enter2(curthread, 0);
160	ret = __sys_close(fd);
161	_thr_cancel_leave(curthread, 1);
162
163	return (ret);
164}
165
166/*
167 * Cancellation behavior:
168 *   If the thread is canceled, connection is not made.
169 */
170static int
171__thr_connect(int fd, const struct sockaddr *name, socklen_t namelen)
172{
173	struct pthread *curthread;
174	int ret;
175
176	curthread = _get_curthread();
177	_thr_cancel_enter(curthread);
178	ret = __sys_connect(fd, name, namelen);
179	_thr_cancel_leave(curthread, ret == -1);
180
181 	return (ret);
182}
183
184/*
185 * Cancellation behavior:
186 *   According to specification, only F_SETLKW is a cancellation point.
187 *   Thread is only canceled at start, or canceled if the system call
188 *   is failure, this means the function does not generate side effect
189 *   if it is canceled.
190 */
191static int
192__thr_fcntl(int fd, int cmd, ...)
193{
194	struct pthread *curthread;
195	int ret;
196	va_list	ap;
197
198	curthread = _get_curthread();
199	va_start(ap, cmd);
200	if (cmd == F_OSETLKW || cmd == F_SETLKW) {
201		_thr_cancel_enter(curthread);
202		ret = __sys_fcntl(fd, cmd, va_arg(ap, void *));
203		_thr_cancel_leave(curthread, ret == -1);
204	} else {
205		ret = __sys_fcntl(fd, cmd, va_arg(ap, void *));
206	}
207	va_end(ap);
208
209	return (ret);
210}
211
212/*
213 * Cancellation behavior:
214 *   Thread may be canceled after system call.
215 */
216static int
217__thr_fsync(int fd)
218{
219	struct pthread *curthread;
220	int ret;
221
222	curthread = _get_curthread();
223	_thr_cancel_enter2(curthread, 0);
224	ret = __sys_fsync(fd);
225	_thr_cancel_leave(curthread, 1);
226
227	return (ret);
228}
229
230static int
231__thr_fdatasync(int fd)
232{
233	struct pthread *curthread;
234	int ret;
235
236	curthread = _get_curthread();
237	_thr_cancel_enter2(curthread, 0);
238	ret = __sys_fdatasync(fd);
239	_thr_cancel_leave(curthread, 1);
240
241	return (ret);
242}
243
244/*
245 * Cancellation behavior:
246 *   Thread may be canceled after system call.
247 */
248static int
249__thr_msync(void *addr, size_t len, int flags)
250{
251	struct pthread *curthread;
252	int ret;
253
254	curthread = _get_curthread();
255	_thr_cancel_enter2(curthread, 0);
256	ret = __sys_msync(addr, len, flags);
257	_thr_cancel_leave(curthread, 1);
258
259	return (ret);
260}
261
262static int
263__thr_clock_nanosleep(clockid_t clock_id, int flags,
264    const struct timespec *time_to_sleep, struct timespec *time_remaining)
265{
266	struct pthread *curthread;
267	int ret;
268
269	curthread = _get_curthread();
270	_thr_cancel_enter(curthread);
271	ret = __sys_clock_nanosleep(clock_id, flags, time_to_sleep,
272	    time_remaining);
273	_thr_cancel_leave(curthread, 1);
274
275	return (ret);
276}
277
278static int
279__thr_nanosleep(const struct timespec *time_to_sleep,
280    struct timespec *time_remaining)
281{
282	struct pthread *curthread;
283	int ret;
284
285	curthread = _get_curthread();
286	_thr_cancel_enter(curthread);
287	ret = __sys_nanosleep(time_to_sleep, time_remaining);
288	_thr_cancel_leave(curthread, 1);
289
290	return (ret);
291}
292
293/*
294 * Cancellation behavior:
295 *   If the thread is canceled, file is not opened.
296 */
297static int
298__thr_openat(int fd, const char *path, int flags, ...)
299{
300	struct pthread *curthread;
301	int mode, ret;
302	va_list	ap;
303
304
305	/* Check if the file is being created: */
306	if ((flags & O_CREAT) != 0) {
307		/* Get the creation mode: */
308		va_start(ap, flags);
309		mode = va_arg(ap, int);
310		va_end(ap);
311	} else {
312		mode = 0;
313	}
314
315	curthread = _get_curthread();
316	_thr_cancel_enter(curthread);
317	ret = __sys_openat(fd, path, flags, mode);
318	_thr_cancel_leave(curthread, ret == -1);
319
320	return (ret);
321}
322
323/*
324 * Cancellation behavior:
325 *   Thread may be canceled at start, but if the system call returns something,
326 *   the thread is not canceled.
327 */
328static int
329__thr_poll(struct pollfd *fds, unsigned int nfds, int timeout)
330{
331	struct pthread *curthread;
332	int ret;
333
334	curthread = _get_curthread();
335	_thr_cancel_enter(curthread);
336	ret = __sys_poll(fds, nfds, timeout);
337	_thr_cancel_leave(curthread, ret == -1);
338
339	return (ret);
340}
341
342/*
343 * Cancellation behavior:
344 *   Thread may be canceled at start, but if the system call returns something,
345 *   the thread is not canceled.
346 */
347static int
348__thr_ppoll(struct pollfd pfd[], nfds_t nfds, const struct timespec *
349    timeout, const sigset_t *newsigmask)
350{
351	struct pthread *curthread;
352	int ret;
353
354	curthread = _get_curthread();
355	_thr_cancel_enter(curthread);
356	ret = __sys_ppoll(pfd, nfds, timeout, newsigmask);
357	_thr_cancel_leave(curthread, ret == -1);
358
359	return (ret);
360}
361
362/*
363 * Cancellation behavior:
364 *   Thread may be canceled at start, but if the system call returns something,
365 *   the thread is not canceled.
366 */
367static int
368__thr_pselect(int count, fd_set *rfds, fd_set *wfds, fd_set *efds,
369	const struct timespec *timo, const sigset_t *mask)
370{
371	struct pthread *curthread;
372	int ret;
373
374	curthread = _get_curthread();
375	_thr_cancel_enter(curthread);
376	ret = __sys_pselect(count, rfds, wfds, efds, timo, mask);
377	_thr_cancel_leave(curthread, ret == -1);
378
379	return (ret);
380}
381
382static int
383__thr_kevent(int kq, const struct kevent *changelist, int nchanges,
384    struct kevent *eventlist, int nevents, const struct timespec *timeout)
385{
386	struct pthread *curthread;
387	int ret;
388
389	if (nevents == 0) {
390		/*
391		 * No blocking, do not make the call cancellable.
392		 */
393		return (__sys_kevent(kq, changelist, nchanges, eventlist,
394		    nevents, timeout));
395	}
396	curthread = _get_curthread();
397	_thr_cancel_enter(curthread);
398	ret = __sys_kevent(kq, changelist, nchanges, eventlist, nevents,
399	    timeout);
400	_thr_cancel_leave(curthread, ret == -1 && nchanges == 0);
401
402	return (ret);
403}
404
405/*
406 * Cancellation behavior:
407 *   Thread may be canceled at start, but if the system call got some data,
408 *   the thread is not canceled.
409 */
410static ssize_t
411__thr_read(int fd, void *buf, size_t nbytes)
412{
413	struct pthread *curthread;
414	ssize_t	ret;
415
416	curthread = _get_curthread();
417	_thr_cancel_enter(curthread);
418	ret = __sys_read(fd, buf, nbytes);
419	_thr_cancel_leave(curthread, ret == -1);
420
421	return (ret);
422}
423
424/*
425 * Cancellation behavior:
426 *   Thread may be canceled at start, but if the system call got some data,
427 *   the thread is not canceled.
428 */
429static ssize_t
430__thr_readv(int fd, const struct iovec *iov, int iovcnt)
431{
432	struct pthread *curthread;
433	ssize_t ret;
434
435	curthread = _get_curthread();
436	_thr_cancel_enter(curthread);
437	ret = __sys_readv(fd, iov, iovcnt);
438	_thr_cancel_leave(curthread, ret == -1);
439	return (ret);
440}
441
442/*
443 * Cancellation behavior:
444 *   Thread may be canceled at start, but if the system call got some data,
445 *   the thread is not canceled.
446 */
447static ssize_t
448__thr_recvfrom(int s, void *b, size_t l, int f, struct sockaddr *from,
449    socklen_t *fl)
450{
451	struct pthread *curthread;
452	ssize_t ret;
453
454	curthread = _get_curthread();
455	_thr_cancel_enter(curthread);
456	ret = __sys_recvfrom(s, b, l, f, from, fl);
457	_thr_cancel_leave(curthread, ret == -1);
458	return (ret);
459}
460
461/*
462 * Cancellation behavior:
463 *   Thread may be canceled at start, but if the system call got some data,
464 *   the thread is not canceled.
465 */
466static ssize_t
467__thr_recvmsg(int s, struct msghdr *m, int f)
468{
469	struct pthread *curthread;
470	ssize_t ret;
471
472	curthread = _get_curthread();
473	_thr_cancel_enter(curthread);
474	ret = __sys_recvmsg(s, m, f);
475	_thr_cancel_leave(curthread, ret == -1);
476	return (ret);
477}
478
479/*
480 * Cancellation behavior:
481 *   Thread may be canceled at start, but if the system call returns something,
482 *   the thread is not canceled.
483 */
484static int
485__thr_select(int numfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
486	struct timeval *timeout)
487{
488	struct pthread *curthread;
489	int ret;
490
491	curthread = _get_curthread();
492	_thr_cancel_enter(curthread);
493	ret = __sys_select(numfds, readfds, writefds, exceptfds, timeout);
494	_thr_cancel_leave(curthread, ret == -1);
495	return (ret);
496}
497
498/*
499 * Cancellation behavior:
500 *   Thread may be canceled at start, but if the system call sent
501 *   data, the thread is not canceled.
502 */
503static ssize_t
504__thr_sendmsg(int s, const struct msghdr *m, int f)
505{
506	struct pthread *curthread;
507	ssize_t ret;
508
509	curthread = _get_curthread();
510	_thr_cancel_enter(curthread);
511	ret = __sys_sendmsg(s, m, f);
512	_thr_cancel_leave(curthread, ret <= 0);
513	return (ret);
514}
515
516/*
517 * Cancellation behavior:
518 *   Thread may be canceled at start, but if the system call sent some
519 *   data, the thread is not canceled.
520 */
521static ssize_t
522__thr_sendto(int s, const void *m, size_t l, int f, const struct sockaddr *t,
523    socklen_t tl)
524{
525	struct pthread *curthread;
526	ssize_t ret;
527
528	curthread = _get_curthread();
529	_thr_cancel_enter(curthread);
530	ret = __sys_sendto(s, m, l, f, t, tl);
531	_thr_cancel_leave(curthread, ret <= 0);
532	return (ret);
533}
534
535static int
536__thr_system(const char *string)
537{
538	struct pthread *curthread;
539	int ret;
540
541	curthread = _get_curthread();
542	_thr_cancel_enter(curthread);
543	ret = __libc_system(string);
544	_thr_cancel_leave(curthread, 1);
545	return (ret);
546}
547
548/*
549 * Cancellation behavior:
550 *   If thread is canceled, the system call is not completed,
551 *   this means not all bytes were drained.
552 */
553static int
554__thr_tcdrain(int fd)
555{
556	struct pthread *curthread;
557	int ret;
558
559	curthread = _get_curthread();
560	_thr_cancel_enter(curthread);
561	ret = __libc_tcdrain(fd);
562	_thr_cancel_leave(curthread, ret == -1);
563	return (ret);
564}
565
566/*
567 * Cancellation behavior:
568 *   Thread may be canceled at start, but if the system call returns
569 *   a child pid, the thread is not canceled.
570 */
571static pid_t
572__thr_wait4(pid_t pid, int *status, int options, struct rusage *rusage)
573{
574	struct pthread *curthread;
575	pid_t ret;
576
577	curthread = _get_curthread();
578	_thr_cancel_enter(curthread);
579	ret = __sys_wait4(pid, status, options, rusage);
580	_thr_cancel_leave(curthread, ret <= 0);
581	return (ret);
582}
583
584/*
585 * Cancellation behavior:
586 *   Thread may be canceled at start, but if the system call returns
587 *   a child pid, the thread is not canceled.
588 */
589static pid_t
590__thr_wait6(idtype_t idtype, id_t id, int *status, int options,
591    struct __wrusage *ru, siginfo_t *infop)
592{
593	struct pthread *curthread;
594	pid_t ret;
595
596	curthread = _get_curthread();
597	_thr_cancel_enter(curthread);
598	ret = __sys_wait6(idtype, id, status, options, ru, infop);
599	_thr_cancel_leave(curthread, ret <= 0);
600	return (ret);
601}
602
603/*
604 * Cancellation behavior:
605 *   Thread may be canceled at start, but if the thread wrote some data,
606 *   it is not canceled.
607 */
608static ssize_t
609__thr_write(int fd, const void *buf, size_t nbytes)
610{
611	struct pthread *curthread;
612	ssize_t	ret;
613
614	curthread = _get_curthread();
615	_thr_cancel_enter(curthread);
616	ret = __sys_write(fd, buf, nbytes);
617	_thr_cancel_leave(curthread, (ret <= 0));
618	return (ret);
619}
620
621/*
622 * Cancellation behavior:
623 *   Thread may be canceled at start, but if the thread wrote some data,
624 *   it is not canceled.
625 */
626static ssize_t
627__thr_writev(int fd, const struct iovec *iov, int iovcnt)
628{
629	struct pthread *curthread;
630	ssize_t ret;
631
632	curthread = _get_curthread();
633	_thr_cancel_enter(curthread);
634	ret = __sys_writev(fd, iov, iovcnt);
635	_thr_cancel_leave(curthread, (ret <= 0));
636	return (ret);
637}
638
639void
640__thr_interpose_libc(void)
641{
642
643	__set_error_selector(__error_threaded);
644#define	SLOT(name)					\
645	*(__libc_interposing_slot(INTERPOS_##name)) =	\
646	    (interpos_func_t)__thr_##name;
647	SLOT(accept);
648	SLOT(accept4);
649	SLOT(aio_suspend);
650	SLOT(close);
651	SLOT(connect);
652	SLOT(fcntl);
653	SLOT(fsync);
654	SLOT(fork);
655	SLOT(msync);
656	SLOT(nanosleep);
657	SLOT(openat);
658	SLOT(poll);
659	SLOT(pselect);
660	SLOT(read);
661	SLOT(readv);
662	SLOT(recvfrom);
663	SLOT(recvmsg);
664	SLOT(select);
665	SLOT(sendmsg);
666	SLOT(sendto);
667	SLOT(setcontext);
668	SLOT(sigaction);
669	SLOT(sigprocmask);
670	SLOT(sigsuspend);
671	SLOT(sigwait);
672	SLOT(sigtimedwait);
673	SLOT(sigwaitinfo);
674	SLOT(swapcontext);
675	SLOT(system);
676	SLOT(tcdrain);
677	SLOT(wait4);
678	SLOT(write);
679	SLOT(writev);
680	SLOT(spinlock);
681	SLOT(spinunlock);
682	SLOT(kevent);
683	SLOT(wait6);
684	SLOT(ppoll);
685	SLOT(map_stacks_exec);
686	SLOT(fdatasync);
687	SLOT(clock_nanosleep);
688#undef SLOT
689	*(__libc_interposing_slot(
690	    INTERPOS__pthread_mutex_init_calloc_cb)) =
691	    (interpos_func_t)_pthread_mutex_init_calloc_cb;
692}
693