thr_syscalls.c revision 211524
190792Sgshapiro/*
290792Sgshapiro * Copyright (C) 2005 David Xu <davidxu@freebsd.org>.
3261363Sgshapiro * Copyright (c) 2003 Daniel Eischen <deischen@freebsd.org>.
490792Sgshapiro * Copyright (C) 2000 Jason Evans <jasone@freebsd.org>.
590792Sgshapiro * All rights reserved.
690792Sgshapiro *
790792Sgshapiro * Redistribution and use in source and binary forms, with or without
890792Sgshapiro * modification, are permitted provided that the following conditions
990792Sgshapiro * are met:
1090792Sgshapiro * 1. Redistributions of source code must retain the above copyright
1190792Sgshapiro *    notice(s), this list of conditions and the following disclaimer as
1290792Sgshapiro *    the first lines of this file unmodified other than the possible
1390792Sgshapiro *    addition of one or more copyright notices.
1490792Sgshapiro * 2. Redistributions in binary form must reproduce the above copyright
1590792Sgshapiro *    notice(s), this list of conditions and the following disclaimer in
1690792Sgshapiro *    the documentation and/or other materials provided with the
1790792Sgshapiro *    distribution.
1890792Sgshapiro *
1990792Sgshapiro * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) ``AS IS'' AND ANY
2090792Sgshapiro * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2190792Sgshapiro * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
2290792Sgshapiro * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) BE
2390792Sgshapiro * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
2490792Sgshapiro * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
2590792Sgshapiro * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
2690792Sgshapiro * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
2790792Sgshapiro * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
2890792Sgshapiro * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
2990792Sgshapiro * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
3090792Sgshapiro *
3190792Sgshapiro * $FreeBSD: head/lib/libthr/thread/thr_syscalls.c 211524 2010-08-20 05:15:39Z davidxu $
3290792Sgshapiro */
3390792Sgshapiro
3490792Sgshapiro/*
3590792Sgshapiro * Copyright (c) 1995-1998 John Birrell <jb@cimlogic.com.au>
3690792Sgshapiro * All rights reserved.
3790792Sgshapiro *
3890792Sgshapiro * Redistribution and use in source and binary forms, with or without
3990792Sgshapiro * modification, are permitted provided that the following conditions
4098121Sgshapiro * are met:
4190792Sgshapiro * 1. Redistributions of source code must retain the above copyright
4290792Sgshapiro *    notice, this list of conditions and the following disclaimer.
4390792Sgshapiro * 2. Redistributions in binary form must reproduce the above copyright
4490792Sgshapiro *    notice, this list of conditions and the following disclaimer in the
4590792Sgshapiro *    documentation and/or other materials provided with the distribution.
4690792Sgshapiro * 3. Neither the name of the author nor the names of any co-contributors
4790792Sgshapiro *    may be used to endorse or promote products derived from this software
4890792Sgshapiro *    without specific prior written permission.
4990792Sgshapiro *
5090792Sgshapiro * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
5190792Sgshapiro * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
5290792Sgshapiro * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
5398121Sgshapiro * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
5490792Sgshapiro * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
5590792Sgshapiro * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
5690792Sgshapiro * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
5790792Sgshapiro * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
5890792Sgshapiro * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
5990792Sgshapiro * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
6090792Sgshapiro * SUCH DAMAGE.
6190792Sgshapiro *
62266692Sgshapiro */
6390792Sgshapiro
6490792Sgshapiro#include "namespace.h"
6590792Sgshapiro#include <sys/types.h>
6690792Sgshapiro#include <sys/mman.h>
6790792Sgshapiro#include <sys/param.h>
6890792Sgshapiro#include <sys/select.h>
6990792Sgshapiro#include <sys/signalvar.h>
7090792Sgshapiro#include <sys/socket.h>
7190792Sgshapiro#include <sys/stat.h>
7290792Sgshapiro#include <sys/time.h>
7390792Sgshapiro#include <sys/uio.h>
7498121Sgshapiro#include <sys/wait.h>
7590792Sgshapiro#include <aio.h>
7690792Sgshapiro#include <dirent.h>
7790792Sgshapiro#include <errno.h>
7890792Sgshapiro#include <fcntl.h>
7990792Sgshapiro#include <poll.h>
8090792Sgshapiro#include <signal.h>
8190792Sgshapiro#include <stdarg.h>
8290792Sgshapiro#include <stdio.h>
8390792Sgshapiro#include <stdlib.h>
8490792Sgshapiro#include <string.h>
8590792Sgshapiro#include <termios.h>
8690792Sgshapiro#include <unistd.h>
8790792Sgshapiro#include <pthread.h>
88157001Sgshapiro#include "un-namespace.h"
8990792Sgshapiro
9090792Sgshapiro#include "thr_private.h"
9190792Sgshapiro
9290792Sgshapiroextern int	__creat(const char *, mode_t);
9390792Sgshapiroextern int	__pselect(int, fd_set *, fd_set *, fd_set *,
9490792Sgshapiro			const struct timespec *, const sigset_t *);
95extern unsigned	__sleep(unsigned int);
96extern int	__system(const char *);
97extern int	__tcdrain(int);
98extern int	__usleep(useconds_t);
99extern pid_t	__wait(int *);
100extern pid_t	__waitpid(pid_t, int *, int);
101extern int	__sys_aio_suspend(const struct aiocb * const[], int,
102			const struct timespec *);
103extern int	__sys_accept(int, struct sockaddr *, socklen_t *);
104extern int	__sys_connect(int, const struct sockaddr *, socklen_t);
105extern int	__sys_fsync(int);
106extern int	__sys_msync(void *, size_t, int);
107extern int	__sys_pselect(int, fd_set *, fd_set *, fd_set *,
108			const struct timespec *, const sigset_t *);
109extern int	__sys_poll(struct pollfd *, unsigned, int);
110extern ssize_t	__sys_recv(int, void *, size_t, int);
111extern ssize_t	__sys_recvfrom(int, void *, size_t, int, struct sockaddr *, socklen_t *);
112extern ssize_t	__sys_recvmsg(int, struct msghdr *, int);
113extern int	__sys_select(int, fd_set *, fd_set *, fd_set *, struct timeval *);
114extern int	__sys_sendfile(int, int, off_t, size_t, struct sf_hdtr *,
115			off_t *, int);
116extern ssize_t	__sys_sendmsg(int, const struct msghdr *, int);
117extern ssize_t	__sys_sendto(int, const void *,size_t, int, const struct sockaddr *, socklen_t);
118extern ssize_t	__sys_readv(int, const struct iovec *, int);
119extern pid_t	__sys_wait4(pid_t, int *, int, struct rusage *);
120extern ssize_t	__sys_writev(int, const struct iovec *, int);
121
122int	___creat(const char *, mode_t);
123int	___pselect(int, fd_set *, fd_set *, fd_set *,
124		const struct timespec *, const sigset_t *);
125unsigned	___sleep(unsigned);
126int	___system(const char *);
127int	___tcdrain(int);
128int	___usleep(useconds_t useconds);
129pid_t	___wait(int *);
130pid_t	___waitpid(pid_t, int *, int);
131int	__accept(int, struct sockaddr *, socklen_t *);
132int	__aio_suspend(const struct aiocb * const iocbs[], int,
133		const struct timespec *);
134int	__close(int);
135int	__connect(int, const struct sockaddr *, socklen_t);
136int	__fcntl(int, int,...);
137#ifdef SYSCALL_COMPAT
138extern int __fcntl_compat(int, int,...);
139#endif
140int	__fsync(int);
141int	__msync(void *, size_t, int);
142int	__nanosleep(const struct timespec *, struct timespec *);
143int	__open(const char *, int,...);
144int	__openat(int, const char *, int,...);
145int	__poll(struct pollfd *, unsigned int, int);
146ssize_t	__read(int, void *buf, size_t);
147ssize_t	__readv(int, const struct iovec *, int);
148ssize_t	__recvfrom(int, void *, size_t, int f, struct sockaddr *, socklen_t *);
149ssize_t	__recvmsg(int, struct msghdr *, int);
150int	__select(int, fd_set *, fd_set *, fd_set *, struct timeval *);
151ssize_t	__sendmsg(int, const struct msghdr *, int);
152ssize_t	__sendto(int, const void *, size_t, int,
153		const struct sockaddr *, socklen_t);
154pid_t	__wait3(int *, int, struct rusage *);
155pid_t	__wait4(pid_t, int *, int, struct rusage *);
156ssize_t	__write(int, const void *, size_t);
157ssize_t	__writev(int, const struct iovec *, int);
158
159__weak_reference(__accept, accept);
160
161/*
162 * Cancellation behavior:
163 *   If thread is canceled, no socket is created.
164 */
165int
166__accept(int s, struct sockaddr *addr, socklen_t *addrlen)
167{
168	struct pthread *curthread;
169	int ret;
170
171	curthread = _get_curthread();
172	_thr_cancel_enter_defer(curthread, 1);
173	ret = __sys_accept(s, addr, addrlen);
174	_thr_cancel_leave_defer(curthread, ret == -1);
175
176 	return (ret);
177}
178
179__weak_reference(__aio_suspend, aio_suspend);
180
181int
182__aio_suspend(const struct aiocb * const iocbs[], int niocb, const struct
183    timespec *timeout)
184{
185	struct pthread *curthread = _get_curthread();
186	int ret;
187
188	_thr_cancel_enter(curthread);
189	ret = __sys_aio_suspend(iocbs, niocb, timeout);
190	_thr_cancel_leave(curthread);
191
192	return (ret);
193}
194
195__weak_reference(__close, close);
196
197/*
198 * Cancellation behavior:
199 *   According to manual of close(), the file descriptor is always deleted.
200 *   Here, thread is only canceled after the system call, so the file
201 *   descriptor is always deleted despite whether the thread is canceled
202 *   or not.
203 */
204int
205__close(int fd)
206{
207	struct pthread	*curthread = _get_curthread();
208	int	ret;
209
210	_thr_cancel_enter_defer(curthread, 0);
211	ret = __sys_close(fd);
212	_thr_cancel_leave_defer(curthread, 1);
213
214	return (ret);
215}
216
217__weak_reference(__connect, connect);
218
219/*
220 * Cancellation behavior:
221 *   If the thread is canceled, connection is not made.
222 */
223int
224__connect(int fd, const struct sockaddr *name, socklen_t namelen)
225{
226	struct pthread *curthread = _get_curthread();
227	int ret;
228
229	_thr_cancel_enter_defer(curthread, 0);
230	ret = __sys_connect(fd, name, namelen);
231	_thr_cancel_leave_defer(curthread, ret == -1);
232
233 	return (ret);
234}
235
236__weak_reference(___creat, creat);
237
238/*
239 * Cancellation behavior:
240 *   If thread is canceled, file is not created.
241 */
242int
243___creat(const char *path, mode_t mode)
244{
245	struct pthread *curthread = _get_curthread();
246	int ret;
247
248	_thr_cancel_enter_defer(curthread, 1);
249	ret = __creat(path, mode);
250	_thr_cancel_leave_defer(curthread, ret == -1);
251
252	return ret;
253}
254
255__weak_reference(__fcntl, fcntl);
256
257/*
258 * Cancellation behavior:
259 *   According to specification, only F_SETLKW is a cancellation point.
260 *   Thread is only canceled at start, or canceled if the system call
261 *   is failure, this means the function does not generate side effect
262 *   if it is canceled.
263 */
264int
265__fcntl(int fd, int cmd,...)
266{
267	struct pthread *curthread = _get_curthread();
268	int	ret;
269	va_list	ap;
270
271	va_start(ap, cmd);
272	switch (cmd) {
273	case F_DUPFD:
274	case F_DUP2FD:
275		ret = __sys_fcntl(fd, cmd, va_arg(ap, int));
276		break;
277	case F_SETFD:
278	case F_SETFL:
279		ret = __sys_fcntl(fd, cmd, va_arg(ap, int));
280		break;
281	case F_GETFD:
282	case F_GETFL:
283		ret = __sys_fcntl(fd, cmd);
284		break;
285	case F_OSETLKW:
286	case F_SETLKW:
287		_thr_cancel_enter_defer(curthread, 1);
288#ifdef SYSCALL_COMPAT
289		ret = __fcntl_compat(fd, cmd, va_arg(ap, void *));
290#else
291		ret = __sys_fcntl(fd, cmd, va_arg(ap, void *));
292#endif
293		_thr_cancel_leave_defer(curthread, ret == -1);
294		break;
295	default:
296#ifdef SYSCALL_COMPAT
297		ret = __fcntl_compat(fd, cmd, va_arg(ap, void *));
298#else
299		ret = __sys_fcntl(fd, cmd, va_arg(ap, void *));
300#endif
301	}
302	va_end(ap);
303
304	return (ret);
305}
306
307__weak_reference(__fsync, fsync);
308
309/*
310 * Cancellation behavior:
311 *   Thread may be canceled after system call.
312 */
313int
314__fsync(int fd)
315{
316	struct pthread *curthread = _get_curthread();
317	int	ret;
318
319	_thr_cancel_enter_defer(curthread, 0);
320	ret = __sys_fsync(fd);
321	_thr_cancel_leave_defer(curthread, 1);
322
323	return (ret);
324}
325
326__weak_reference(__msync, msync);
327
328/*
329 * Cancellation behavior:
330 *   Thread may be canceled after system call.
331 */
332int
333__msync(void *addr, size_t len, int flags)
334{
335	struct pthread *curthread = _get_curthread();
336	int	ret;
337
338	_thr_cancel_enter_defer(curthread, 0);
339	ret = __sys_msync(addr, len, flags);
340	_thr_cancel_leave_defer(curthread, 1);
341
342	return ret;
343}
344
345__weak_reference(__nanosleep, nanosleep);
346
347int
348__nanosleep(const struct timespec *time_to_sleep,
349    struct timespec *time_remaining)
350{
351	struct pthread *curthread = _get_curthread();
352	int		ret;
353
354	_thr_cancel_enter(curthread);
355	ret = __sys_nanosleep(time_to_sleep, time_remaining);
356	_thr_cancel_leave(curthread);
357
358	return (ret);
359}
360
361__weak_reference(__open, open);
362
363/*
364 * Cancellation behavior:
365 *   If the thread is canceled, file is not opened.
366 */
367int
368__open(const char *path, int flags,...)
369{
370	struct pthread *curthread = _get_curthread();
371	int	ret;
372	int	mode = 0;
373	va_list	ap;
374
375	/* Check if the file is being created: */
376	if (flags & O_CREAT) {
377		/* Get the creation mode: */
378		va_start(ap, flags);
379		mode = va_arg(ap, int);
380		va_end(ap);
381	}
382
383	_thr_cancel_enter_defer(curthread, 1);
384	ret = __sys_open(path, flags, mode);
385	_thr_cancel_leave_defer(curthread, ret == -1);
386
387	return ret;
388}
389
390__weak_reference(__openat, openat);
391
392/*
393 * Cancellation behavior:
394 *   If the thread is canceled, file is not opened.
395 */
396int
397__openat(int fd, const char *path, int flags, ...)
398{
399	struct pthread *curthread = _get_curthread();
400	int	ret;
401	int	mode = 0;
402	va_list	ap;
403
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	_thr_cancel_enter_defer(curthread, 1);
414	ret = __sys_openat(fd, path, flags, mode);
415	_thr_cancel_leave_defer(curthread, ret == -1);
416
417	return ret;
418}
419
420__weak_reference(__poll, poll);
421
422/*
423 * Cancellation behavior:
424 *   Thread may be canceled at start, but if the system call returns something,
425 *   the thread is not canceled.
426 */
427int
428__poll(struct pollfd *fds, unsigned int nfds, int timeout)
429{
430	struct pthread *curthread = _get_curthread();
431	int ret;
432
433	_thr_cancel_enter_defer(curthread, 1);
434	ret = __sys_poll(fds, nfds, timeout);
435	_thr_cancel_leave_defer(curthread, ret == -1);
436
437	return ret;
438}
439
440__weak_reference(___pselect, pselect);
441
442/*
443 * Cancellation behavior:
444 *   Thread may be canceled at start, but if the system call returns something,
445 *   the thread is not canceled.
446 */
447int
448___pselect(int count, fd_set *rfds, fd_set *wfds, fd_set *efds,
449	const struct timespec *timo, const sigset_t *mask)
450{
451	struct pthread *curthread = _get_curthread();
452	int ret;
453
454	_thr_cancel_enter_defer(curthread, 1);
455	ret = __sys_pselect(count, rfds, wfds, efds, timo, mask);
456	_thr_cancel_leave_defer(curthread, ret == -1);
457
458	return (ret);
459}
460
461__weak_reference(__read, read);
462
463/*
464 * Cancellation behavior:
465 *   Thread may be canceled at start, but if the system call got some data,
466 *   the thread is not canceled.
467 */
468ssize_t
469__read(int fd, void *buf, size_t nbytes)
470{
471	struct pthread *curthread = _get_curthread();
472	ssize_t	ret;
473
474	_thr_cancel_enter_defer(curthread, 1);
475	ret = __sys_read(fd, buf, nbytes);
476	_thr_cancel_leave_defer(curthread, ret == -1);
477
478	return ret;
479}
480
481__weak_reference(__readv, readv);
482
483/*
484 * Cancellation behavior:
485 *   Thread may be canceled at start, but if the system call got some data,
486 *   the thread is not canceled.
487 */
488ssize_t
489__readv(int fd, const struct iovec *iov, int iovcnt)
490{
491	struct pthread *curthread = _get_curthread();
492	ssize_t ret;
493
494	_thr_cancel_enter_defer(curthread, 1);
495	ret = __sys_readv(fd, iov, iovcnt);
496	_thr_cancel_leave_defer(curthread, ret == -1);
497	return ret;
498}
499
500__weak_reference(__recvfrom, recvfrom);
501
502/*
503 * Cancellation behavior:
504 *   Thread may be canceled at start, but if the system call got some data,
505 *   the thread is not canceled.
506 */
507ssize_t
508__recvfrom(int s, void *b, size_t l, int f, struct sockaddr *from,
509    socklen_t *fl)
510{
511	struct pthread *curthread = _get_curthread();
512	ssize_t ret;
513
514	_thr_cancel_enter_defer(curthread, 1);
515	ret = __sys_recvfrom(s, b, l, f, from, fl);
516	_thr_cancel_leave_defer(curthread, ret == -1);
517	return (ret);
518}
519
520__weak_reference(__recvmsg, recvmsg);
521
522/*
523 * Cancellation behavior:
524 *   Thread may be canceled at start, but if the system call got some data,
525 *   the thread is not canceled.
526 */
527ssize_t
528__recvmsg(int s, struct msghdr *m, int f)
529{
530	struct pthread *curthread = _get_curthread();
531	ssize_t ret;
532
533	_thr_cancel_enter_defer(curthread, 1);
534	ret = __sys_recvmsg(s, m, f);
535	_thr_cancel_leave_defer(curthread, ret == -1);
536	return (ret);
537}
538
539__weak_reference(__select, select);
540
541/*
542 * Cancellation behavior:
543 *   Thread may be canceled at start, but if the system call returns something,
544 *   the thread is not canceled.
545 */
546int
547__select(int numfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
548	struct timeval *timeout)
549{
550	struct pthread *curthread = _get_curthread();
551	int ret;
552
553	_thr_cancel_enter_defer(curthread, 1);
554	ret = __sys_select(numfds, readfds, writefds, exceptfds, timeout);
555	_thr_cancel_leave_defer(curthread, ret == -1);
556	return ret;
557}
558
559__weak_reference(__sendmsg, sendmsg);
560
561/*
562 * Cancellation behavior:
563 *   Thread may be canceled at start, but if the system call sent
564 *   data, the thread is not canceled.
565 */
566ssize_t
567__sendmsg(int s, const struct msghdr *m, int f)
568{
569	struct pthread *curthread = _get_curthread();
570	ssize_t ret;
571
572	_thr_cancel_enter_defer(curthread, 1);
573	ret = __sys_sendmsg(s, m, f);
574	_thr_cancel_leave_defer(curthread, ret <= 0);
575	return (ret);
576}
577
578__weak_reference(__sendto, sendto);
579
580/*
581 * Cancellation behavior:
582 *   Thread may be canceled at start, but if the system call sent some
583 *   data, the thread is not canceled.
584 */
585ssize_t
586__sendto(int s, const void *m, size_t l, int f, const struct sockaddr *t,
587    socklen_t tl)
588{
589	struct pthread *curthread = _get_curthread();
590	ssize_t ret;
591
592	_thr_cancel_enter_defer(curthread, 1);
593	ret = __sys_sendto(s, m, l, f, t, tl);
594	_thr_cancel_leave_defer(curthread, ret <= 0);
595	return (ret);
596}
597
598__weak_reference(___sleep, sleep);
599
600unsigned int
601___sleep(unsigned int seconds)
602{
603	struct pthread *curthread = _get_curthread();
604	unsigned int	ret;
605
606	_thr_cancel_enter(curthread);
607	ret = __sleep(seconds);
608	_thr_cancel_leave(curthread);
609
610	return (ret);
611}
612
613__weak_reference(___system, system);
614
615int
616___system(const char *string)
617{
618	struct pthread *curthread = _get_curthread();
619	int	ret;
620
621	_thr_cancel_enter(curthread);
622	ret = __system(string);
623	_thr_cancel_leave(curthread);
624
625	return ret;
626}
627
628__weak_reference(___tcdrain, tcdrain);
629
630/*
631 * Cancellation behavior:
632 *   If thread is canceled, the system call is not completed,
633 *   this means not all bytes were drained.
634 */
635int
636___tcdrain(int fd)
637{
638	struct pthread *curthread = _get_curthread();
639	int	ret;
640
641	_thr_cancel_enter_defer(curthread, 1);
642	ret = __tcdrain(fd);
643	_thr_cancel_leave_defer(curthread, ret == -1);
644	return (ret);
645}
646
647__weak_reference(___usleep, usleep);
648
649int
650___usleep(useconds_t useconds)
651{
652	struct pthread *curthread = _get_curthread();
653	int		ret;
654
655	_thr_cancel_enter(curthread);
656	ret = __usleep(useconds);
657	_thr_cancel_leave(curthread);
658
659	return (ret);
660}
661
662__weak_reference(___wait, wait);
663
664/*
665 * Cancellation behavior:
666 *   Thread may be canceled at start, but if the system call returns
667 *   a child pid, the thread is not canceled.
668 */
669pid_t
670___wait(int *istat)
671{
672	struct pthread *curthread = _get_curthread();
673	pid_t	ret;
674
675	_thr_cancel_enter_defer(curthread, 1);
676	ret = __wait(istat);
677	_thr_cancel_leave_defer(curthread, ret <= 0);
678
679	return ret;
680}
681
682__weak_reference(__wait3, wait3);
683
684/*
685 * Cancellation behavior:
686 *   Thread may be canceled at start, but if the system call returns
687 *   a child pid, the thread is not canceled.
688 */
689pid_t
690__wait3(int *status, int options, struct rusage *rusage)
691{
692	struct pthread *curthread = _get_curthread();
693	pid_t ret;
694
695	_thr_cancel_enter_defer(curthread, 1);
696	ret = _wait4(WAIT_ANY, status, options, rusage);
697	_thr_cancel_leave_defer(curthread, ret <= 0);
698
699	return (ret);
700}
701
702__weak_reference(__wait4, wait4);
703
704/*
705 * Cancellation behavior:
706 *   Thread may be canceled at start, but if the system call returns
707 *   a child pid, the thread is not canceled.
708 */
709pid_t
710__wait4(pid_t pid, int *status, int options, struct rusage *rusage)
711{
712	struct pthread *curthread = _get_curthread();
713	pid_t ret;
714
715	_thr_cancel_enter_defer(curthread, 1);
716	ret = __sys_wait4(pid, status, options, rusage);
717	_thr_cancel_leave_defer(curthread, ret <= 0);
718
719	return ret;
720}
721
722__weak_reference(___waitpid, waitpid);
723
724/*
725 * Cancellation behavior:
726 *   Thread may be canceled at start, but if the system call returns
727 *   a child pid, the thread is not canceled.
728 */
729pid_t
730___waitpid(pid_t wpid, int *status, int options)
731{
732	struct pthread *curthread = _get_curthread();
733	pid_t	ret;
734
735	_thr_cancel_enter_defer(curthread, 1);
736	ret = __waitpid(wpid, status, options);
737	_thr_cancel_leave_defer(curthread, ret <= 0);
738
739	return ret;
740}
741
742__weak_reference(__write, write);
743
744/*
745 * Cancellation behavior:
746 *   Thread may be canceled at start, but if the thread wrote some data,
747 *   it is not canceled.
748 */
749ssize_t
750__write(int fd, const void *buf, size_t nbytes)
751{
752	struct pthread *curthread = _get_curthread();
753	ssize_t	ret;
754
755	_thr_cancel_enter_defer(curthread, 1);
756	ret = __sys_write(fd, buf, nbytes);
757	_thr_cancel_leave_defer(curthread, (ret <= 0));
758	return ret;
759}
760
761__weak_reference(__writev, writev);
762
763/*
764 * Cancellation behavior:
765 *   Thread may be canceled at start, but if the thread wrote some data,
766 *   it is not canceled.
767 */
768ssize_t
769__writev(int fd, const struct iovec *iov, int iovcnt)
770{
771	struct pthread *curthread = _get_curthread();
772	ssize_t ret;
773
774	_thr_cancel_enter_defer(curthread, 1);
775	ret = __sys_writev(fd, iov, iovcnt);
776	_thr_cancel_leave_defer(curthread, (ret <= 0));
777	return ret;
778}
779