1 /*
2 * Copyright (C) 2005 David Xu <davidxu@freebsd.org>.
3 * Copyright (c) 2003 Daniel Eischen <deischen@freebsd.org>.
4 * Copyright (C) 2000 Jason Evans <jasone@freebsd.org>.
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice(s), this list of conditions and the following disclaimer as
12 * the first lines of this file unmodified other than the possible
13 * addition of one or more copyright notices.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice(s), this list of conditions and the following disclaimer in
16 * the documentation and/or other materials provided with the
17 * distribution.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) ``AS IS'' AND ANY
20 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) BE
23 * 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
26 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
27 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
28 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
29 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 */
31
32 /*
33 * Copyright (c) 1995-1998 John Birrell <jb@cimlogic.com.au>
34 * All rights reserved.
35 *
36 * Redistribution and use in source and binary forms, with or without
37 * modification, are permitted provided that the following conditions
38 * are met:
39 * 1. Redistributions of source code must retain the above copyright
40 * notice, this list of conditions and the following disclaimer.
41 * 2. Redistributions in binary form must reproduce the above copyright
42 * notice, this list of conditions and the following disclaimer in the
43 * documentation and/or other materials provided with the distribution.
44 * 3. Neither the name of the author nor the names of any co-contributors
45 * may be used to endorse or promote products derived from this software
46 * without specific prior written permission.
47 *
48 * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
49 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
50 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
51 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
52 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
53 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
54 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
55 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
56 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
57 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
58 * SUCH DAMAGE.
59 *
60 */
61
62
63 #include "namespace.h"
64 #include <sys/types.h>
65 #include <sys/mman.h>
66 #include <sys/param.h>
67 #include <sys/select.h>
68 #include <sys/signalvar.h>
69 #include <sys/socket.h>
70 #include <sys/stat.h>
71 #include <sys/time.h>
72 #include <sys/uio.h>
73 #include <sys/wait.h>
74 #include <machine/tls.h>
75 #include <aio.h>
76 #include <dirent.h>
77 #include <errno.h>
78 #include <fcntl.h>
79 #include <poll.h>
80 #include <signal.h>
81 #include <stdarg.h>
82 #include <stdio.h>
83 #include <stdlib.h>
84 #include <string.h>
85 #include <termios.h>
86 #include <unistd.h>
87 #include <pthread.h>
88 #include "un-namespace.h"
89
90 #include "thr_private.h"
91
92 extern int __creat(const char *, mode_t);
93 extern int __pause(void);
94 extern int __sys_pselect(int, fd_set *, fd_set *, fd_set *,
95 const struct timespec *, const sigset_t *);
96 extern unsigned __sleep(unsigned int);
97 extern int __system(const char *);
98 extern int __tcdrain(int);
99 extern int __usleep(useconds_t);
100 extern pid_t __wait(int *);
101 extern pid_t __waitpid(pid_t, int *, int);
102 extern int __sys_aio_suspend(const struct aiocb * const[], int,
103 const struct timespec *);
104 extern int __sys_accept(int, struct sockaddr *, socklen_t *);
105 extern int __sys_connect(int, const struct sockaddr *, socklen_t);
106 extern int __sys_fsync(int);
107 extern int __sys_fdatasync(int);
108 extern int __sys_msync(void *, size_t, int);
109 extern int __sys_poll(struct pollfd *, unsigned, int);
110 extern int __sys_ppoll(struct pollfd *, unsigned, const struct timespec *,
111 const sigset_t *);
112 extern ssize_t __sys_recv(int, void *, size_t, int);
113 extern ssize_t __sys_recvfrom(int, void *, size_t, int, struct sockaddr *, socklen_t *);
114 extern ssize_t __sys_recvmsg(int, struct msghdr *, int);
115 extern int __sys_select(int, fd_set *, fd_set *, fd_set *, struct timeval *);
116 extern int __sys_sendfile(int, int, off_t, size_t, struct sf_hdtr *,
117 off_t *, int);
118 extern ssize_t __sys_sendmsg(int, const struct msghdr *, int);
119 extern ssize_t __sys_sendto(int, const void *,size_t, int, const struct sockaddr *, socklen_t);
120 extern ssize_t __sys_readv(int, const struct iovec *, int);
121 extern pid_t __sys_wait4(pid_t, int *, int, struct rusage *);
122 extern ssize_t __sys_writev(int, const struct iovec *, int);
123
124 int ___creat(const char *, mode_t);
125 int ___usleep(useconds_t);
126 int __accept(int, struct sockaddr *, socklen_t *);
127 int __close(int);
128 int __connect(int, const struct sockaddr *, socklen_t);
129 int __fcntl(int, int,...);
130 int __fsync(int);
131 int __fdatasync(int);
132 int __msync(void *, size_t, int);
133 int __nanosleep(const struct timespec *, struct timespec *);
134 int __clock_nanosleep(clock_t, int, const struct timespec *,
135 struct timespec *);
136 int __open(const char *, int,...);
137 int __openat(int fd, const char *, int,...);
138 int __poll(struct pollfd *, unsigned int, int);
139 int __ppoll(struct pollfd *, unsigned int, const struct timespec *,
140 const sigset_t *);
141 ssize_t __read(int, void *buf, size_t);
142 ssize_t __readv(int, const struct iovec *, int);
143 ssize_t __recvfrom(int, void *, size_t, int f, struct sockaddr *, socklen_t *);
144 ssize_t __recvmsg(int, struct msghdr *, int);
145 int __select(int, fd_set *, fd_set *, fd_set *, struct timeval *);
146 ssize_t __sendmsg(int, const struct msghdr *, int);
147 ssize_t __sendto(int, const void *, size_t, int,
148 const struct sockaddr *, socklen_t);
149 pid_t __wait4(pid_t, int *, int, struct rusage *);
150 ssize_t __write(int, const void *, size_t);
151 ssize_t __writev(int, const struct iovec *, int);
152 int _aio_suspend(const struct aiocb * const iocbs[], int,
153 const struct timespec *);
154 int _pause(void);
155 int __pselect(int, fd_set *, fd_set *, fd_set *,
156 const struct timespec *, const sigset_t *);
157 int _raise(int);
158 unsigned _sleep(unsigned);
159 int _system(const char *);
160 int _tcdrain(int);
161 #if 0
162 int _vfork(void);
163 #endif
164 pid_t _wait(int *);
165
166 int
__accept(int s,struct sockaddr * addr,socklen_t * addrlen)167 __accept(int s, struct sockaddr *addr, socklen_t *addrlen)
168 {
169 pthread_t curthread;
170 int oldcancel;
171 int ret;
172
173 curthread = tls_get_curthread();
174 oldcancel = _thr_cancel_enter(curthread);
175 ret = __sys_accept(s, addr, addrlen);
176 _thr_cancel_leave(curthread, oldcancel);
177
178 return (ret);
179 }
180
181 __strong_reference(__accept, accept);
182
183 int
_aio_suspend(const struct aiocb * const iocbs[],int niocb,const struct timespec * timeout)184 _aio_suspend(const struct aiocb * const iocbs[], int niocb, const struct
185 timespec *timeout)
186 {
187 pthread_t curthread = tls_get_curthread();
188 int oldcancel;
189 int ret;
190
191 oldcancel = _thr_cancel_enter(curthread);
192 ret = __sys_aio_suspend(iocbs, niocb, timeout);
193 _thr_cancel_leave(curthread, oldcancel);
194
195 return (ret);
196 }
197
198 __strong_reference(_aio_suspend, aio_suspend);
199
200 int
__close(int fd)201 __close(int fd)
202 {
203 pthread_t curthread = tls_get_curthread();
204 int oldcancel;
205 int ret;
206
207 oldcancel = _thr_cancel_enter(curthread);
208 ret = __sys_close(fd);
209 _thr_cancel_leave(curthread, oldcancel);
210
211 return (ret);
212 }
213
214 __strong_reference(__close, close);
215
216 int
__connect(int fd,const struct sockaddr * name,socklen_t namelen)217 __connect(int fd, const struct sockaddr *name, socklen_t namelen)
218 {
219 pthread_t curthread = tls_get_curthread();
220 int oldcancel;
221 int ret;
222
223 oldcancel = _thr_cancel_enter(curthread);
224 ret = __sys_connect(fd, name, namelen);
225 _thr_cancel_leave(curthread, oldcancel);
226
227 return (ret);
228 }
229
230 __strong_reference(__connect, connect);
231
232 int
___creat(const char * path,mode_t mode)233 ___creat(const char *path, mode_t mode)
234 {
235 pthread_t curthread = tls_get_curthread();
236 int oldcancel;
237 int ret;
238
239 oldcancel = _thr_cancel_enter(curthread);
240 ret = __creat(path, mode);
241 _thr_cancel_leave(curthread, oldcancel);
242
243 return ret;
244 }
245
246 __strong_reference(___creat, creat);
247
248 int
__fcntl(int fd,int cmd,...)249 __fcntl(int fd, int cmd,...)
250 {
251 pthread_t curthread = tls_get_curthread();
252 int oldcancel;
253 int ret;
254 va_list ap;
255
256 oldcancel = _thr_cancel_enter(curthread);
257
258 va_start(ap, cmd);
259 switch (cmd) {
260 case F_DUPFD:
261 ret = __sys_fcntl(fd, cmd, va_arg(ap, int));
262 break;
263 case F_SETFD:
264 case F_SETFL:
265 ret = __sys_fcntl(fd, cmd, va_arg(ap, int));
266 break;
267 case F_GETFD:
268 case F_GETFL:
269 ret = __sys_fcntl(fd, cmd);
270 break;
271 default:
272 ret = __sys_fcntl(fd, cmd, va_arg(ap, void *));
273 }
274 va_end(ap);
275
276 _thr_cancel_leave(curthread, oldcancel);
277
278 return (ret);
279 }
280
281 __strong_reference(__fcntl, fcntl);
282
283 int
__fsync(int fd)284 __fsync(int fd)
285 {
286 pthread_t curthread = tls_get_curthread();
287 int oldcancel;
288 int ret;
289
290 oldcancel = _thr_cancel_enter(curthread);
291 ret = __sys_fsync(fd);
292 _thr_cancel_leave(curthread, oldcancel);
293
294 return (ret);
295 }
296
297 __strong_reference(__fsync, fsync);
298
299 int
__fdatasync(int fd)300 __fdatasync(int fd)
301 {
302 pthread_t curthread = tls_get_curthread();
303 int oldcancel;
304 int ret;
305
306 oldcancel = _thr_cancel_enter(curthread);
307 ret = __sys_fdatasync(fd);
308 _thr_cancel_leave(curthread, oldcancel);
309
310 return (ret);
311 }
312
313 __strong_reference(__fdatasync, fdatasync);
314
315 int
__msync(void * addr,size_t len,int flags)316 __msync(void *addr, size_t len, int flags)
317 {
318 pthread_t curthread = tls_get_curthread();
319 int oldcancel;
320 int ret;
321
322 oldcancel = _thr_cancel_enter(curthread);
323 ret = __sys_msync(addr, len, flags);
324 _thr_cancel_leave(curthread, oldcancel);
325
326 return ret;
327 }
328
329 __strong_reference(__msync, msync);
330
331 int
__nanosleep(const struct timespec * time_to_sleep,struct timespec * time_remaining)332 __nanosleep(const struct timespec *time_to_sleep,
333 struct timespec *time_remaining)
334 {
335 pthread_t curthread = tls_get_curthread();
336 int oldcancel;
337 int ret;
338
339 oldcancel = _thr_cancel_enter(curthread);
340 ret = __sys_nanosleep(time_to_sleep, time_remaining);
341 _thr_cancel_leave(curthread, oldcancel);
342
343 return (ret);
344 }
345
346 __strong_reference(__nanosleep, nanosleep);
347
348 int
__clock_nanosleep(clock_t clock_id,int flags,const struct timespec * time_to_sleep,struct timespec * time_remaining)349 __clock_nanosleep(clock_t clock_id, int flags,
350 const struct timespec *time_to_sleep, struct timespec *time_remaining)
351 {
352 pthread_t curthread = tls_get_curthread();
353 int oldcancel;
354 int ret;
355
356 oldcancel = _thr_cancel_enter(curthread);
357 ret = __sys_clock_nanosleep(clock_id, flags, time_to_sleep,
358 time_remaining);
359 _thr_cancel_leave(curthread, oldcancel);
360
361 return (ret);
362 }
363
364 __strong_reference(__clock_nanosleep, clock_nanosleep);
365
366 int
__open(const char * path,int flags,...)367 __open(const char *path, int flags,...)
368 {
369 pthread_t curthread = tls_get_curthread();
370 int oldcancel;
371 int ret;
372 int mode = 0;
373 va_list ap;
374
375 oldcancel = _thr_cancel_enter(curthread);
376
377 /* Check if the file is being created: */
378 if (flags & O_CREAT) {
379 /* Get the creation mode: */
380 va_start(ap, flags);
381 mode = va_arg(ap, int);
382 va_end(ap);
383 }
384
385 ret = __sys_open(path, flags, mode);
386
387 _thr_cancel_leave(curthread, oldcancel);
388
389 return ret;
390 }
391
392 __strong_reference(__open, open);
393
394 int
__openat(int fd,const char * path,int flags,...)395 __openat(int fd, const char *path, int flags,...)
396 {
397 pthread_t curthread = tls_get_curthread();
398 int oldcancel;
399 int ret;
400 int mode = 0;
401 va_list ap;
402
403 oldcancel = _thr_cancel_enter(curthread);
404
405 /* Check if the file is being created: */
406 if (flags & O_CREAT) {
407 /* Get the creation mode: */
408 va_start(ap, flags);
409 mode = va_arg(ap, int);
410 va_end(ap);
411 }
412
413 ret = __sys_openat(fd, path, flags, mode);
414
415 _thr_cancel_leave(curthread, oldcancel);
416
417 return ret;
418 }
419
420 __strong_reference(__openat, openat);
421
422 int
_pause(void)423 _pause(void)
424 {
425 pthread_t curthread = tls_get_curthread();
426 int oldcancel;
427 int ret;
428
429 oldcancel = _thr_cancel_enter(curthread);
430 ret = __pause();
431 _thr_cancel_leave(curthread, oldcancel);
432
433 return ret;
434 }
435
436 __strong_reference(_pause, pause);
437
438 int
__poll(struct pollfd * fds,unsigned int nfds,int timeout)439 __poll(struct pollfd *fds, unsigned int nfds, int timeout)
440 {
441 pthread_t curthread = tls_get_curthread();
442 int oldcancel;
443 int ret;
444
445 oldcancel = _thr_cancel_enter(curthread);
446 ret = __sys_poll(fds, nfds, timeout);
447 _thr_cancel_leave(curthread, oldcancel);
448
449 return ret;
450 }
451
452 __strong_reference(__poll, poll);
453
454 int
__ppoll(struct pollfd * fds,unsigned int nfds,const struct timespec * ts,const sigset_t * mask)455 __ppoll(struct pollfd *fds, unsigned int nfds, const struct timespec *ts,
456 const sigset_t *mask)
457 {
458 pthread_t curthread = tls_get_curthread();
459 int oldcancel;
460 int ret;
461
462 oldcancel = _thr_cancel_enter(curthread);
463 ret = __sys_ppoll(fds, nfds, ts, mask);
464 _thr_cancel_leave(curthread, oldcancel);
465
466 return ret;
467 }
468
469 __strong_reference(__ppoll, ppoll);
470
471 int
__pselect(int count,fd_set * rfds,fd_set * wfds,fd_set * efds,const struct timespec * timo,const sigset_t * mask)472 __pselect(int count, fd_set *rfds, fd_set *wfds, fd_set *efds,
473 const struct timespec *timo, const sigset_t *mask)
474 {
475 pthread_t curthread = tls_get_curthread();
476 int oldcancel;
477 int ret;
478
479 oldcancel = _thr_cancel_enter(curthread);
480 ret = __sys_pselect(count, rfds, wfds, efds, timo, mask);
481 _thr_cancel_leave(curthread, oldcancel);
482
483 return (ret);
484 }
485 __strong_reference(__pselect, pselect);
486
487
488 int
_raise(int sig)489 _raise(int sig)
490 {
491 int ret;
492
493 if (!_thr_isthreaded())
494 ret = kill(getpid(), sig);
495 else
496 ret = _thr_send_sig(tls_get_curthread(), sig);
497 return (ret);
498 }
499
500 __strong_reference(_raise, raise);
501
502 ssize_t
__read(int fd,void * buf,size_t nbytes)503 __read(int fd, void *buf, size_t nbytes)
504 {
505 pthread_t curthread = tls_get_curthread();
506 int oldcancel;
507 ssize_t ret;
508
509 oldcancel = _thr_cancel_enter(curthread);
510 ret = __sys_read(fd, buf, nbytes);
511 _thr_cancel_leave(curthread, oldcancel);
512 return ret;
513 }
514
515 __strong_reference(__read, read);
516
517 ssize_t
__readv(int fd,const struct iovec * iov,int iovcnt)518 __readv(int fd, const struct iovec *iov, int iovcnt)
519 {
520 pthread_t curthread = tls_get_curthread();
521 int oldcancel;
522 ssize_t ret;
523
524 oldcancel = _thr_cancel_enter(curthread);
525 ret = __sys_readv(fd, iov, iovcnt);
526 _thr_cancel_leave(curthread, oldcancel);
527 return ret;
528 }
529
530 __strong_reference(__readv, readv);
531
532 ssize_t
__recvfrom(int s,void * b,size_t l,int f,struct sockaddr * from,socklen_t * fl)533 __recvfrom(int s, void *b, size_t l, int f, struct sockaddr *from,
534 socklen_t *fl)
535 {
536 pthread_t curthread = tls_get_curthread();
537 int oldcancel;
538 ssize_t ret;
539
540 oldcancel = _thr_cancel_enter(curthread);
541 ret = __sys_recvfrom(s, b, l, f, from, fl);
542 _thr_cancel_leave(curthread, oldcancel);
543 return (ret);
544 }
545
546 __strong_reference(__recvfrom, recvfrom);
547
548 ssize_t
__recvmsg(int s,struct msghdr * m,int f)549 __recvmsg(int s, struct msghdr *m, int f)
550 {
551 pthread_t curthread = tls_get_curthread();
552 ssize_t ret;
553 int oldcancel;
554
555 oldcancel = _thr_cancel_enter(curthread);
556 ret = __sys_recvmsg(s, m, f);
557 _thr_cancel_leave(curthread, oldcancel);
558 return (ret);
559 }
560
561 __strong_reference(__recvmsg, recvmsg);
562
563 int
__select(int numfds,fd_set * readfds,fd_set * writefds,fd_set * exceptfds,struct timeval * timeout)564 __select(int numfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
565 struct timeval *timeout)
566 {
567 pthread_t curthread = tls_get_curthread();
568 int oldcancel;
569 int ret;
570
571 oldcancel = _thr_cancel_enter(curthread);
572 ret = __sys_select(numfds, readfds, writefds, exceptfds, timeout);
573 _thr_cancel_leave(curthread, oldcancel);
574 return ret;
575 }
576
577 __strong_reference(__select, select);
578
579 ssize_t
__sendmsg(int s,const struct msghdr * m,int f)580 __sendmsg(int s, const struct msghdr *m, int f)
581 {
582 pthread_t curthread = tls_get_curthread();
583 ssize_t ret;
584 int oldcancel;
585
586 oldcancel = _thr_cancel_enter(curthread);
587 ret = __sys_sendmsg(s, m, f);
588 _thr_cancel_leave(curthread, oldcancel);
589 return (ret);
590 }
591
592 __strong_reference(__sendmsg, sendmsg);
593
594 ssize_t
__sendto(int s,const void * m,size_t l,int f,const struct sockaddr * t,socklen_t tl)595 __sendto(int s, const void *m, size_t l, int f, const struct sockaddr *t,
596 socklen_t tl)
597 {
598 pthread_t curthread = tls_get_curthread();
599 ssize_t ret;
600 int oldcancel;
601
602 oldcancel = _thr_cancel_enter(curthread);
603 ret = __sys_sendto(s, m, l, f, t, tl);
604 _thr_cancel_leave(curthread, oldcancel);
605 return (ret);
606 }
607
608 __strong_reference(__sendto, sendto);
609
610 unsigned int
_sleep(unsigned int seconds)611 _sleep(unsigned int seconds)
612 {
613 pthread_t curthread = tls_get_curthread();
614 int oldcancel;
615 unsigned int ret;
616
617 oldcancel = _thr_cancel_enter(curthread);
618 ret = __sleep(seconds);
619 _thr_cancel_leave(curthread, oldcancel);
620 return (ret);
621 }
622
623 __strong_reference(_sleep, sleep);
624
625 int
_system(const char * string)626 _system(const char *string)
627 {
628 pthread_t curthread = tls_get_curthread();
629 int oldcancel;
630 int ret;
631
632 oldcancel = _thr_cancel_enter(curthread);
633 ret = __system(string);
634 _thr_cancel_leave(curthread, oldcancel);
635 return ret;
636 }
637
638 __strong_reference(_system, system);
639
640 int
_tcdrain(int fd)641 _tcdrain(int fd)
642 {
643 pthread_t curthread = tls_get_curthread();
644 int oldcancel;
645 int ret;
646
647 oldcancel = _thr_cancel_enter(curthread);
648 ret = __tcdrain(fd);
649 _thr_cancel_leave(curthread, oldcancel);
650 return (ret);
651 }
652
653 __strong_reference(_tcdrain, tcdrain);
654
655 int
___usleep(useconds_t useconds)656 ___usleep(useconds_t useconds)
657 {
658 pthread_t curthread = tls_get_curthread();
659 int oldcancel;
660 int ret;
661
662 oldcancel = _thr_cancel_enter(curthread);
663 ret = __usleep(useconds);
664 _thr_cancel_leave(curthread, oldcancel);
665 return (ret);
666 }
667
668 __strong_reference(___usleep, usleep);
669
670 #if 0
671 /*
672 * REMOVED - vfork() works as per normal. In a threaded environment vfork()
673 * blocks the calling thread only and not other threads.
674 */
675 int
676 _vfork(void)
677 {
678 return (fork());
679 }
680
681 __strong_reference(_vfork, vfork);
682 #endif
683
684 pid_t
_wait(int * istat)685 _wait(int *istat)
686 {
687 pthread_t curthread = tls_get_curthread();
688 int oldcancel;
689 pid_t ret;
690
691 oldcancel = _thr_cancel_enter(curthread);
692 ret = __wait(istat);
693 _thr_cancel_leave(curthread, oldcancel);
694 return ret;
695 }
696
697 __strong_reference(_wait, wait);
698
699 pid_t
__wait4(pid_t pid,int * istat,int options,struct rusage * rusage)700 __wait4(pid_t pid, int *istat, int options, struct rusage *rusage)
701 {
702 pthread_t curthread = tls_get_curthread();
703 int oldcancel;
704 pid_t ret;
705
706 oldcancel = _thr_cancel_enter(curthread);
707 ret = __sys_wait4(pid, istat, options, rusage);
708 _thr_cancel_leave(curthread, oldcancel);
709 return ret;
710 }
711
712 __strong_reference(__wait4, wait4);
713
714 pid_t
_waitpid(pid_t wpid,int * status,int options)715 _waitpid(pid_t wpid, int *status, int options)
716 {
717 pthread_t curthread = tls_get_curthread();
718 int oldcancel;
719 pid_t ret;
720
721 oldcancel = _thr_cancel_enter(curthread);
722 ret = __waitpid(wpid, status, options);
723 _thr_cancel_leave(curthread, oldcancel);
724 return ret;
725 }
726
727 __strong_reference(_waitpid, waitpid);
728
729 ssize_t
__write(int fd,const void * buf,size_t nbytes)730 __write(int fd, const void *buf, size_t nbytes)
731 {
732 pthread_t curthread = tls_get_curthread();
733 int oldcancel;
734 ssize_t ret;
735
736 oldcancel = _thr_cancel_enter(curthread);
737 ret = __sys_write(fd, buf, nbytes);
738 _thr_cancel_leave(curthread, oldcancel);
739 return ret;
740 }
741
742 __strong_reference(__write, write);
743
744 ssize_t
__writev(int fd,const struct iovec * iov,int iovcnt)745 __writev(int fd, const struct iovec *iov, int iovcnt)
746 {
747 pthread_t curthread = tls_get_curthread();
748 int oldcancel;
749 ssize_t ret;
750
751 oldcancel = _thr_cancel_enter(curthread);
752 ret = __sys_writev(fd, iov, iovcnt);
753 _thr_cancel_leave(curthread, oldcancel);
754 return ret;
755 }
756
757 __strong_reference(__writev, writev);
758