ViewVC Help
View File | Revision Log | Show Annotations | Download File | View Changeset | Root Listing
root/src/trunk/lib/libthr/thread/thr_syscalls.c
Revision: 10633
Committed: Sat Jun 9 16:42:31 2018 UTC (5 years, 10 months ago) by laffer1
Content type: text/plain
File size: 16730 byte(s)
Log Message:
sync with freebsd

File Contents

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

Properties

Name Value
svn:keywords MidnightBSD=%H