]> CyberLeo.Net >> Repos - FreeBSD/releng/10.2.git/blob - lib/libthr/thread/thr_syscalls.c
- Copy stable/10@285827 to releng/10.2 in preparation for 10.2-RC1
[FreeBSD/releng/10.2.git] / lib / libthr / thread / thr_syscalls.c
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$");
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
98 #ifdef SYSCALL_COMPAT
99 extern int __fcntl_compat(int, int, ...);
100 #endif
101
102 static int
103 __thr_accept(int s, struct sockaddr *addr, socklen_t *addrlen)
104 {
105         struct pthread *curthread;
106         int ret;
107
108         curthread = _get_curthread();
109         _thr_cancel_enter(curthread);
110         ret = __sys_accept(s, addr, addrlen);
111         _thr_cancel_leave(curthread, ret == -1);
112
113         return (ret);
114 }
115
116 /*
117  * Cancellation behavior:
118  *   If thread is canceled, no socket is created.
119  */
120 static int
121 __thr_accept4(int s, struct sockaddr *addr, socklen_t *addrlen, int flags)
122 {
123         struct pthread *curthread;
124         int ret;
125
126         curthread = _get_curthread();
127         _thr_cancel_enter(curthread);
128         ret = __sys_accept4(s, addr, addrlen, flags);
129         _thr_cancel_leave(curthread, ret == -1);
130
131         return (ret);
132 }
133
134 static int
135 __thr_aio_suspend(const struct aiocb * const iocbs[], int niocb, const struct
136     timespec *timeout)
137 {
138         struct pthread *curthread;
139         int ret;
140
141         curthread = _get_curthread();
142         _thr_cancel_enter(curthread);
143         ret = __sys_aio_suspend(iocbs, niocb, timeout);
144         _thr_cancel_leave(curthread, 1);
145
146         return (ret);
147 }
148
149 /*
150  * Cancellation behavior:
151  *   According to manual of close(), the file descriptor is always deleted.
152  *   Here, thread is only canceled after the system call, so the file
153  *   descriptor is always deleted despite whether the thread is canceled
154  *   or not.
155  */
156 static int
157 __thr_close(int fd)
158 {
159         struct pthread *curthread;
160         int ret;
161
162         curthread = _get_curthread();
163         _thr_cancel_enter2(curthread, 0);
164         ret = __sys_close(fd);
165         _thr_cancel_leave(curthread, 1);
166         
167         return (ret);
168 }
169
170 /*
171  * Cancellation behavior:
172  *   If the thread is canceled, connection is not made.
173  */
174 static int
175 __thr_connect(int fd, const struct sockaddr *name, socklen_t namelen)
176 {
177         struct pthread *curthread;
178         int ret;
179
180         curthread = _get_curthread();
181         _thr_cancel_enter(curthread);
182         ret = __sys_connect(fd, name, namelen);
183         _thr_cancel_leave(curthread, ret == -1);
184
185         return (ret);
186 }
187
188 /*
189  * Cancellation behavior:
190  *   According to specification, only F_SETLKW is a cancellation point.
191  *   Thread is only canceled at start, or canceled if the system call
192  *   is failure, this means the function does not generate side effect
193  *   if it is canceled.
194  */
195 static int
196 __thr_fcntl(int fd, int cmd, ...)
197 {
198         struct pthread *curthread;
199         int ret;
200         va_list ap;
201
202         curthread = _get_curthread();
203         va_start(ap, cmd);
204         if (cmd == F_OSETLKW || cmd == F_SETLKW) {
205                 _thr_cancel_enter(curthread);
206 #ifdef SYSCALL_COMPAT
207                 ret = __fcntl_compat(fd, cmd, va_arg(ap, void *));
208 #else
209                 ret = __sys_fcntl(fd, cmd, va_arg(ap, void *));
210 #endif
211                 _thr_cancel_leave(curthread, ret == -1);
212         } else {
213 #ifdef SYSCALL_COMPAT
214                 ret = __fcntl_compat(fd, cmd, va_arg(ap, void *));
215 #else
216                 ret = __sys_fcntl(fd, cmd, va_arg(ap, void *));
217 #endif
218         }
219         va_end(ap);
220
221         return (ret);
222 }
223
224 /*
225  * Cancellation behavior:
226  *   Thread may be canceled after system call.
227  */
228 static int
229 __thr_fsync(int fd)
230 {
231         struct pthread *curthread;
232         int ret;
233
234         curthread = _get_curthread();
235         _thr_cancel_enter2(curthread, 0);
236         ret = __sys_fsync(fd);
237         _thr_cancel_leave(curthread, 1);
238
239         return (ret);
240 }
241
242 /*
243  * Cancellation behavior:
244  *   Thread may be canceled after system call.
245  */
246 static int
247 __thr_msync(void *addr, size_t len, int flags)
248 {
249         struct pthread *curthread;
250         int ret;
251
252         curthread = _get_curthread();
253         _thr_cancel_enter2(curthread, 0);
254         ret = __sys_msync(addr, len, flags);
255         _thr_cancel_leave(curthread, 1);
256
257         return (ret);
258 }
259
260 static int
261 __thr_nanosleep(const struct timespec *time_to_sleep,
262     struct timespec *time_remaining)
263 {
264         struct pthread *curthread;
265         int ret;
266
267         curthread = _get_curthread();
268         _thr_cancel_enter(curthread);
269         ret = __sys_nanosleep(time_to_sleep, time_remaining);
270         _thr_cancel_leave(curthread, 1);
271
272         return (ret);
273 }
274
275 /*
276  * Cancellation behavior:
277  *   If the thread is canceled, file is not opened.
278  */
279 static int
280 __thr_openat(int fd, const char *path, int flags, ...)
281 {
282         struct pthread *curthread;
283         int mode, ret;
284         va_list ap;
285
286         
287         /* Check if the file is being created: */
288         if ((flags & O_CREAT) != 0) {
289                 /* Get the creation mode: */
290                 va_start(ap, flags);
291                 mode = va_arg(ap, int);
292                 va_end(ap);
293         } else {
294                 mode = 0;
295         }
296         
297         curthread = _get_curthread();
298         _thr_cancel_enter(curthread);
299         ret = __sys_openat(fd, path, flags, mode);
300         _thr_cancel_leave(curthread, ret == -1);
301
302         return (ret);
303 }
304
305 /*
306  * Cancellation behavior:
307  *   Thread may be canceled at start, but if the system call returns something,
308  *   the thread is not canceled.
309  */
310 static int
311 __thr_poll(struct pollfd *fds, unsigned int nfds, int timeout)
312 {
313         struct pthread *curthread;
314         int ret;
315
316         curthread = _get_curthread();
317         _thr_cancel_enter(curthread);
318         ret = __sys_poll(fds, nfds, timeout);
319         _thr_cancel_leave(curthread, ret == -1);
320
321         return (ret);
322 }
323
324 /*
325  * Cancellation behavior:
326  *   Thread may be canceled at start, but if the system call returns something,
327  *   the thread is not canceled.
328  */
329 static int
330 __thr_ppoll(struct pollfd pfd[], nfds_t nfds, const struct timespec *
331     timeout, const sigset_t *newsigmask)
332 {
333         struct pthread *curthread;
334         int ret;
335
336         curthread = _get_curthread();
337         _thr_cancel_enter(curthread);
338         ret = __sys_ppoll(pfd, nfds, timeout, newsigmask);
339         _thr_cancel_leave(curthread, ret == -1);
340
341         return (ret);
342 }
343
344 /*
345  * Cancellation behavior:
346  *   Thread may be canceled at start, but if the system call returns something,
347  *   the thread is not canceled.
348  */
349 static int
350 __thr_pselect(int count, fd_set *rfds, fd_set *wfds, fd_set *efds, 
351         const struct timespec *timo, const sigset_t *mask)
352 {
353         struct pthread *curthread;
354         int ret;
355
356         curthread = _get_curthread();
357         _thr_cancel_enter(curthread);
358         ret = __sys_pselect(count, rfds, wfds, efds, timo, mask);
359         _thr_cancel_leave(curthread, ret == -1);
360
361         return (ret);
362 }
363
364 static int
365 __thr_kevent(int kq, const struct kevent *changelist, int nchanges,
366     struct kevent *eventlist, int nevents, const struct timespec *timeout)
367 {
368         struct pthread *curthread;
369         int ret;
370
371         if (nevents == 0) {
372                 /*
373                  * No blocking, do not make the call cancellable.
374                  */
375                 return (__sys_kevent(kq, changelist, nchanges, eventlist,
376                     nevents, timeout));
377         }
378         curthread = _get_curthread();
379         _thr_cancel_enter(curthread);
380         ret = __sys_kevent(kq, changelist, nchanges, eventlist, nevents,
381             timeout);
382         _thr_cancel_leave(curthread, ret == -1 && nchanges == 0);
383
384         return (ret);
385 }
386
387 /*
388  * Cancellation behavior:
389  *   Thread may be canceled at start, but if the system call got some data, 
390  *   the thread is not canceled.
391  */
392 static ssize_t
393 __thr_read(int fd, void *buf, size_t nbytes)
394 {
395         struct pthread *curthread;
396         ssize_t ret;
397
398         curthread = _get_curthread();
399         _thr_cancel_enter(curthread);
400         ret = __sys_read(fd, buf, nbytes);
401         _thr_cancel_leave(curthread, ret == -1);
402
403         return (ret);
404 }
405
406 /*
407  * Cancellation behavior:
408  *   Thread may be canceled at start, but if the system call got some data, 
409  *   the thread is not canceled.
410  */
411 static ssize_t
412 __thr_readv(int fd, const struct iovec *iov, int iovcnt)
413 {
414         struct pthread *curthread;
415         ssize_t ret;
416
417         curthread = _get_curthread();
418         _thr_cancel_enter(curthread);
419         ret = __sys_readv(fd, iov, iovcnt);
420         _thr_cancel_leave(curthread, ret == -1);
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  */
429 static ssize_t
430 __thr_recvfrom(int s, void *b, size_t l, int f, struct sockaddr *from,
431     socklen_t *fl)
432 {
433         struct pthread *curthread;
434         ssize_t ret;
435
436         curthread = _get_curthread();
437         _thr_cancel_enter(curthread);
438         ret = __sys_recvfrom(s, b, l, f, from, fl);
439         _thr_cancel_leave(curthread, ret == -1);
440         return (ret);
441 }
442
443 /*
444  * Cancellation behavior:
445  *   Thread may be canceled at start, but if the system call got some data, 
446  *   the thread is not canceled.
447  */
448 static ssize_t
449 __thr_recvmsg(int s, struct msghdr *m, int f)
450 {
451         struct pthread *curthread;
452         ssize_t ret;
453
454         curthread = _get_curthread();
455         _thr_cancel_enter(curthread);
456         ret = __sys_recvmsg(s, m, f);
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 returns something,
464  *   the thread is not canceled.
465  */
466 static int 
467 __thr_select(int numfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
468         struct timeval *timeout)
469 {
470         struct pthread *curthread;
471         int ret;
472
473         curthread = _get_curthread();
474         _thr_cancel_enter(curthread);
475         ret = __sys_select(numfds, readfds, writefds, exceptfds, timeout);
476         _thr_cancel_leave(curthread, ret == -1);
477         return (ret);
478 }
479
480 /*
481  * Cancellation behavior:
482  *   Thread may be canceled at start, but if the system call sent
483  *   data, the thread is not canceled.
484  */
485 static ssize_t
486 __thr_sendmsg(int s, const struct msghdr *m, int f)
487 {
488         struct pthread *curthread;
489         ssize_t ret;
490
491         curthread = _get_curthread();
492         _thr_cancel_enter(curthread);
493         ret = __sys_sendmsg(s, m, f);
494         _thr_cancel_leave(curthread, ret <= 0);
495         return (ret);
496 }
497
498 /*
499  * Cancellation behavior:
500  *   Thread may be canceled at start, but if the system call sent some
501  *   data, the thread is not canceled.
502  */
503 static ssize_t
504 __thr_sendto(int s, const void *m, size_t l, int f, const struct sockaddr *t,
505     socklen_t tl)
506 {
507         struct pthread *curthread;
508         ssize_t ret;
509
510         curthread = _get_curthread();
511         _thr_cancel_enter(curthread);
512         ret = __sys_sendto(s, m, l, f, t, tl);
513         _thr_cancel_leave(curthread, ret <= 0);
514         return (ret);
515 }
516
517 static int
518 __thr_system(const char *string)
519 {
520         struct pthread *curthread;
521         int ret;
522
523         curthread = _get_curthread();
524         _thr_cancel_enter(curthread);
525         ret = __libc_system(string);
526         _thr_cancel_leave(curthread, 1);
527         return (ret);
528 }
529
530 /*
531  * Cancellation behavior:
532  *   If thread is canceled, the system call is not completed,
533  *   this means not all bytes were drained.
534  */
535 static int
536 __thr_tcdrain(int fd)
537 {
538         struct pthread *curthread;
539         int ret;
540         
541         curthread = _get_curthread();
542         _thr_cancel_enter(curthread);
543         ret = __libc_tcdrain(fd);
544         _thr_cancel_leave(curthread, ret == -1);
545         return (ret);
546 }
547
548 /*
549  * Cancellation behavior:
550  *   Thread may be canceled at start, but if the system call returns
551  *   a child pid, the thread is not canceled.
552  */
553 static pid_t
554 __thr_wait4(pid_t pid, int *status, int options, struct rusage *rusage)
555 {
556         struct pthread *curthread;
557         pid_t ret;
558
559         curthread = _get_curthread();
560         _thr_cancel_enter(curthread);
561         ret = __sys_wait4(pid, status, options, rusage);
562         _thr_cancel_leave(curthread, ret <= 0);
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  */
571 static pid_t
572 __thr_wait6(idtype_t idtype, id_t id, int *status, int options,
573     struct __wrusage *ru, siginfo_t *infop)
574 {
575         struct pthread *curthread;
576         pid_t ret;
577
578         curthread = _get_curthread();
579         _thr_cancel_enter(curthread);
580         ret = __sys_wait6(idtype, id, status, options, ru, infop);
581         _thr_cancel_leave(curthread, ret <= 0);
582         return (ret);
583 }
584
585 /*
586  * Cancellation behavior:
587  *   Thread may be canceled at start, but if the thread wrote some data,
588  *   it is not canceled.
589  */
590 static ssize_t
591 __thr_write(int fd, const void *buf, size_t nbytes)
592 {
593         struct pthread *curthread;
594         ssize_t ret;
595
596         curthread = _get_curthread();
597         _thr_cancel_enter(curthread);
598         ret = __sys_write(fd, buf, nbytes);
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  */
608 static ssize_t
609 __thr_writev(int fd, const struct iovec *iov, int iovcnt)
610 {
611         struct pthread *curthread;
612         ssize_t ret;
613
614         curthread = _get_curthread();
615         _thr_cancel_enter(curthread);
616         ret = __sys_writev(fd, iov, iovcnt);
617         _thr_cancel_leave(curthread, (ret <= 0));
618         return (ret);
619 }
620
621 void
622 __thr_interpose_libc(void)
623 {
624
625         __set_error_selector(__error_threaded);
626 #define SLOT(name)                                      \
627         *(__libc_interposing_slot(INTERPOS_##name)) =   \
628             (interpos_func_t)__thr_##name;
629         SLOT(accept);
630         SLOT(accept4);
631         SLOT(aio_suspend);
632         SLOT(close);
633         SLOT(connect);
634         SLOT(fcntl);
635         SLOT(fsync);
636         SLOT(fork);
637         SLOT(msync);
638         SLOT(nanosleep);
639         SLOT(openat);
640         SLOT(poll);
641         SLOT(pselect);
642         SLOT(read);
643         SLOT(readv);
644         SLOT(recvfrom);
645         SLOT(recvmsg);
646         SLOT(select);
647         SLOT(sendmsg);
648         SLOT(sendto);
649         SLOT(setcontext);
650         SLOT(sigaction);
651         SLOT(sigprocmask);
652         SLOT(sigsuspend);
653         SLOT(sigwait);
654         SLOT(sigtimedwait);
655         SLOT(sigwaitinfo);
656         SLOT(swapcontext);
657         SLOT(system);
658         SLOT(tcdrain);
659         SLOT(wait4);
660         SLOT(write);
661         SLOT(writev);
662         SLOT(spinlock);
663         SLOT(spinunlock);
664         SLOT(kevent);
665         SLOT(wait6);
666         SLOT(ppoll);
667 #undef SLOT
668         *(__libc_interposing_slot(
669             INTERPOS__pthread_mutex_init_calloc_cb)) =
670             (interpos_func_t)_pthread_mutex_init_calloc_cb;
671 }