17c478bdstevel@tonic-gate/*
27c478bdstevel@tonic-gate * CDDL HEADER START
37c478bdstevel@tonic-gate *
47c478bdstevel@tonic-gate * The contents of this file are subject to the terms of the
53470957raf * Common Development and Distribution License (the "License").
63470957raf * You may not use this file except in compliance with the License.
77c478bdstevel@tonic-gate *
87c478bdstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
97c478bdstevel@tonic-gate * or http://www.opensolaris.org/os/licensing.
107c478bdstevel@tonic-gate * See the License for the specific language governing permissions
117c478bdstevel@tonic-gate * and limitations under the License.
127c478bdstevel@tonic-gate *
137c478bdstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each
147c478bdstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
157c478bdstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the
167c478bdstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying
177c478bdstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner]
187c478bdstevel@tonic-gate *
197c478bdstevel@tonic-gate * CDDL HEADER END
207c478bdstevel@tonic-gate */
210293487raf
227c478bdstevel@tonic-gate/*
238fd04b8Roger A. Faulkner * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
247c478bdstevel@tonic-gate * Use is subject to license terms.
25fca543cDJ Hoffman * Copyright (c) 2015, Joyent, Inc.  All rights reserved.
267c478bdstevel@tonic-gate */
277c478bdstevel@tonic-gate
285dbfd19Theo Schlossnagle/* Copyright (c) 2013, OmniTI Computer Consulting, Inc. All rights reserved. */
295dbfd19Theo Schlossnagle
307c478bdstevel@tonic-gate#include "lint.h"
317c478bdstevel@tonic-gate#include "thr_uberdata.h"
327c478bdstevel@tonic-gate#include <stdarg.h>
337c478bdstevel@tonic-gate#include <poll.h>
347c478bdstevel@tonic-gate#include <stropts.h>
357c478bdstevel@tonic-gate#include <dlfcn.h>
36a574db8raf#include <wait.h>
37a574db8raf#include <sys/socket.h>
387c478bdstevel@tonic-gate#include <sys/uio.h>
39a574db8raf#include <sys/file.h>
40a574db8raf#include <sys/door.h>
417c478bdstevel@tonic-gate
427c478bdstevel@tonic-gate/*
437257d1braf * These leading-underbar symbols exist because mistakes were made
447257d1braf * in the past that put them into non-SUNWprivate versions of
457257d1braf * the libc mapfiles.  They should be eliminated, but oh well...
467257d1braf */
477257d1braf#pragma weak _fork = fork
487257d1braf#pragma weak _read = read
497257d1braf#pragma weak _write = write
507257d1braf#pragma weak _getmsg = getmsg
517257d1braf#pragma weak _getpmsg = getpmsg
527257d1braf#pragma weak _putmsg = putmsg
537257d1braf#pragma weak _putpmsg = putpmsg
547257d1braf#pragma weak _sleep = sleep
557257d1braf#pragma weak _close = close
567257d1braf#pragma weak _creat = creat
577257d1braf#pragma weak _fcntl = fcntl
587257d1braf#pragma weak _fsync = fsync
597257d1braf#pragma weak _lockf = lockf
607257d1braf#pragma weak _msgrcv = msgrcv
617257d1braf#pragma weak _msgsnd = msgsnd
627257d1braf#pragma weak _msync = msync
637257d1braf#pragma weak _open = open
647257d1braf#pragma weak _openat = openat
657257d1braf#pragma weak _pause = pause
667257d1braf#pragma weak _readv = readv
677257d1braf#pragma weak _sigpause = sigpause
687257d1braf#pragma weak _sigsuspend = sigsuspend
697257d1braf#pragma weak _tcdrain = tcdrain
707257d1braf#pragma weak _waitid = waitid
717257d1braf#pragma weak _writev = writev
727257d1braf
737257d1braf#if !defined(_LP64)
747257d1braf#pragma weak _creat64 = creat64
757257d1braf#pragma weak _lockf64 = lockf64
767257d1braf#pragma weak _open64 = open64
777257d1braf#pragma weak _openat64 = openat64
787257d1braf#pragma weak _pread64 = pread64
797257d1braf#pragma weak _pwrite64 = pwrite64
807257d1braf#endif
817257d1braf
827257d1braf/*
83d56c62craf * These are SUNWprivate, but they are being used by Sun Studio libcollector.
84d56c62craf */
85d56c62craf#pragma weak _fork1 = fork1
86d56c62craf#pragma weak _forkall = forkall
87d56c62craf
88d56c62craf/*
8998c1a6braf * atfork_lock protects the pthread_atfork() data structures.
9098c1a6braf *
91b6233caraf * fork_lock does double-duty.  Not only does it (and atfork_lock)
92b6233caraf * serialize calls to fork() and forkall(), but it also serializes calls
93b6233caraf * to thr_suspend() and thr_continue() (because fork() and forkall() also
94b6233caraf * suspend and continue other threads and they want no competition).
95b6233caraf *
9698c1a6braf * Functions called in dlopen()ed L10N objects can do anything, including
9798c1a6braf * call malloc() and free().  Such calls are not fork-safe when protected
9898c1a6braf * by an ordinary mutex that is acquired in libc's prefork processing
9998c1a6braf * because, with an interposed malloc library present, there would be a
10098c1a6braf * lock ordering violation due to the pthread_atfork() prefork function
10198c1a6braf * in the interposition library acquiring its malloc lock(s) before the
102b6233caraf * ordinary mutex in libc being acquired by libc's prefork functions.
103b6233caraf *
10498c1a6braf * Within libc, calls to malloc() and free() are fork-safe if the calls
10598c1a6braf * are made while holding no other libc locks.  This covers almost all
10698c1a6braf * of libc's malloc() and free() calls.  For those libc code paths, such
10798c1a6braf * as the above-mentioned L10N calls, that require serialization and that
10898c1a6braf * may call malloc() or free(), libc uses callout_lock_enter() to perform
10998c1a6braf * the serialization.  This works because callout_lock is not acquired as
11098c1a6braf * part of running the pthread_atfork() prefork handlers (to avoid the
11198c1a6braf * lock ordering violation described above).  Rather, it is simply
11298c1a6braf * reinitialized in postfork1_child() to cover the case that some
11398c1a6braf * now-defunct thread might have been suspended while holding it.
1147c478bdstevel@tonic-gate */
115b6233caraf
1162e14588rafvoid
1172e14588raffork_lock_enter(void)
1187c478bdstevel@tonic-gate{
119b6233caraf	ASSERT(curthread->ul_critical == 0);
1208cd4554raf	(void) mutex_lock(&curthread->ul_uberdata->fork_lock);
1217c478bdstevel@tonic-gate}
1227c478bdstevel@tonic-gate
1237c478bdstevel@tonic-gatevoid
1247c478bdstevel@tonic-gatefork_lock_exit(void)
1257c478bdstevel@tonic-gate{
126b6233caraf	ASSERT(curthread->ul_critical == 0);
1278cd4554raf	(void) mutex_unlock(&curthread->ul_uberdata->fork_lock);
128b6233caraf}
129b6233caraf
130a574db8raf/*
131a574db8raf * Use cancel_safe_mutex_lock() to protect against being cancelled while
132a574db8raf * holding callout_lock and calling outside of libc (via L10N plugins).
133a574db8raf * We will honor a pending cancellation request when callout_lock_exit()
134a574db8raf * is called, by calling cancel_safe_mutex_unlock().
135a574db8raf */
136b6233carafvoid
13798c1a6brafcallout_lock_enter(void)
138b6233caraf{
139b6233caraf	ASSERT(curthread->ul_critical == 0);
140a574db8raf	cancel_safe_mutex_lock(&curthread->ul_uberdata->callout_lock);
141b6233caraf}
1427c478bdstevel@tonic-gate
143b6233carafvoid
14498c1a6brafcallout_lock_exit(void)
145b6233caraf{
146b6233caraf	ASSERT(curthread->ul_critical == 0);
147a574db8raf	cancel_safe_mutex_unlock(&curthread->ul_uberdata->callout_lock);
1487c478bdstevel@tonic-gate}
1497c478bdstevel@tonic-gate
150dfb96a4abpid_t
1517257d1brafforkx(int flags)
1527c478bdstevel@tonic-gate{
1537c478bdstevel@tonic-gate	ulwp_t *self = curthread;
1547c478bdstevel@tonic-gate	uberdata_t *udp = self->ul_uberdata;
1557c478bdstevel@tonic-gate	pid_t pid;
1567c478bdstevel@tonic-gate
1577c478bdstevel@tonic-gate	if (self->ul_vfork) {
1587c478bdstevel@tonic-gate		/*
1597c478bdstevel@tonic-gate		 * We are a child of vfork(); omit all of the fork
1607c478bdstevel@tonic-gate		 * logic and go straight to the system call trap.
1617c478bdstevel@tonic-gate		 * A vfork() child of a multithreaded parent
1627c478bdstevel@tonic-gate		 * must never call fork().
1637c478bdstevel@tonic-gate		 */
1647c478bdstevel@tonic-gate		if (udp->uberflags.uf_mt) {
1657c478bdstevel@tonic-gate			errno = ENOTSUP;
1667c478bdstevel@tonic-gate			return (-1);
1677c478bdstevel@tonic-gate		}
168657b1f3raf		pid = __forkx(flags);
1697c478bdstevel@tonic-gate		if (pid == 0) {		/* child */
1708cd4554raf			udp->pid = getpid();
1717c478bdstevel@tonic-gate			self->ul_vfork = 0;
1727c478bdstevel@tonic-gate		}
1737c478bdstevel@tonic-gate		return (pid);
1747c478bdstevel@tonic-gate	}
1757c478bdstevel@tonic-gate
1762e14588raf	sigoff(self);
1772e14588raf	if (self->ul_fork) {
1787c478bdstevel@tonic-gate		/*
1797c478bdstevel@tonic-gate		 * Cannot call fork() from a fork handler.
1807c478bdstevel@tonic-gate		 */
1812e14588raf		sigon(self);
1822e14588raf		errno = EDEADLK;
1837c478bdstevel@tonic-gate		return (-1);
1847c478bdstevel@tonic-gate	}
1857c478bdstevel@tonic-gate	self->ul_fork = 1;
1867c478bdstevel@tonic-gate
1877c478bdstevel@tonic-gate	/*
1887c478bdstevel@tonic-gate	 * The functions registered by pthread_atfork() are defined by
1897c478bdstevel@tonic-gate	 * the application and its libraries and we must not hold any
1902e14588raf	 * internal lmutex_lock()-acquired locks while invoking them.
1912e14588raf	 * We hold only udp->atfork_lock to protect the atfork linkages.
1922e14588raf	 * If one of these pthread_atfork() functions attempts to fork
193b6233caraf	 * or to call pthread_atfork(), libc will detect the error and
194b6233caraf	 * fail the call with EDEADLK.  Otherwise, the pthread_atfork()
195b6233caraf	 * functions are free to do anything they please (except they
196b6233caraf	 * will not receive any signals).
1977c478bdstevel@tonic-gate	 */
1988cd4554raf	(void) mutex_lock(&udp->atfork_lock);
1993771f29Roger A. Faulkner
2003771f29Roger A. Faulkner	/*
2013771f29Roger A. Faulkner	 * Posix (SUSv3) requires fork() to be async-signal-safe.
2023771f29Roger A. Faulkner	 * This cannot be made to happen with fork handlers in place
2033771f29Roger A. Faulkner	 * (they grab locks).  To be in nominal compliance, don't run
2043771f29Roger A. Faulkner	 * any fork handlers if we are called within a signal context.
2053771f29Roger A. Faulkner	 * This leaves the child process in a questionable state with
2063771f29Roger A. Faulkner	 * respect to its locks, but at least the parent process does
2073771f29Roger A. Faulkner	 * not become deadlocked due to the calling thread attempting
2083771f29Roger A. Faulkner	 * to acquire a lock that it already owns.
2093771f29Roger A. Faulkner	 */
2103771f29Roger A. Faulkner	if (self->ul_siglink == NULL)
2113771f29Roger A. Faulkner		_prefork_handler();
2127c478bdstevel@tonic-gate
2137c478bdstevel@tonic-gate	/*
2142e14588raf	 * Block every other thread attempting thr_suspend() or thr_continue().
2152e14588raf	 */
2168cd4554raf	(void) mutex_lock(&udp->fork_lock);
2172e14588raf
2182e14588raf	/*
2197c478bdstevel@tonic-gate	 * Block all signals.
2202e14588raf	 * Just deferring them via sigoff() is not enough.
2217c478bdstevel@tonic-gate	 * We have to avoid taking a deferred signal in the child
222657b1f3raf	 * that was actually sent to the parent before __forkx().
2237c478bdstevel@tonic-gate	 */
2247c478bdstevel@tonic-gate	block_all_signals(self);
2257c478bdstevel@tonic-gate
2267c478bdstevel@tonic-gate	/*
2277c478bdstevel@tonic-gate	 * This suspends all threads but this one, leaving them
2287c478bdstevel@tonic-gate	 * suspended outside of any critical regions in the library.
229b6233caraf	 * Thus, we are assured that no lmutex_lock()-acquired library
230b6233caraf	 * locks are held while we invoke fork() from the current thread.
2317c478bdstevel@tonic-gate	 */
2327c478bdstevel@tonic-gate	suspend_fork();
2337c478bdstevel@tonic-gate
234657b1f3raf	pid = __forkx(flags);
2357c478bdstevel@tonic-gate
2367c478bdstevel@tonic-gate	if (pid == 0) {		/* child */
2377c478bdstevel@tonic-gate		/*
2387c478bdstevel@tonic-gate		 * Clear our schedctl pointer.
2397c478bdstevel@tonic-gate		 * Discard any deferred signal that was sent to the parent.
240657b1f3raf		 * Because we blocked all signals before __forkx(), a
2417c478bdstevel@tonic-gate		 * deferred signal cannot have been taken by the child.
2427c478bdstevel@tonic-gate		 */
2437c478bdstevel@tonic-gate		self->ul_schedctl_called = NULL;
2447c478bdstevel@tonic-gate		self->ul_schedctl = NULL;
2457c478bdstevel@tonic-gate		self->ul_cursig = 0;
2467c478bdstevel@tonic-gate		self->ul_siginfo.si_signo = 0;
2478cd4554raf		udp->pid = getpid();
2487c478bdstevel@tonic-gate		/* reset the library's data structures to reflect one thread */
249c242ec1Roger A. Faulkner		unregister_locks();
250f841f6araf		postfork1_child();
2517c478bdstevel@tonic-gate		restore_signals(self);
2528cd4554raf		(void) mutex_unlock(&udp->fork_lock);
2533771f29Roger A. Faulkner		if (self->ul_siglink == NULL)
2543771f29Roger A. Faulkner			_postfork_child_handler();
2557c478bdstevel@tonic-gate	} else {
256657b1f3raf		/* restart all threads that were suspended for fork() */
2577c478bdstevel@tonic-gate		continue_fork(0);
2587c478bdstevel@tonic-gate		restore_signals(self);
2598cd4554raf		(void) mutex_unlock(&udp->fork_lock);
2603771f29Roger A. Faulkner		if (self->ul_siglink == NULL)
2613771f29Roger A. Faulkner			_postfork_parent_handler();
2627c478bdstevel@tonic-gate	}
2637c478bdstevel@tonic-gate
2648cd4554raf	(void) mutex_unlock(&udp->atfork_lock);
2657c478bdstevel@tonic-gate	self->ul_fork = 0;
2662e14588raf	sigon(self);
2677c478bdstevel@tonic-gate
2687c478bdstevel@tonic-gate	return (pid);
2697c478bdstevel@tonic-gate}
2707c478bdstevel@tonic-gate
2717c478bdstevel@tonic-gate/*
272657b1f3raf * fork() is fork1() for both Posix threads and Solaris threads.
273657b1f3raf * The forkall() interface exists for applications that require
274657b1f3raf * the semantics of replicating all threads.
2757c478bdstevel@tonic-gate */
2767257d1braf#pragma weak fork1 = fork
2777c478bdstevel@tonic-gatepid_t
2787257d1braffork(void)
279657b1f3raf{
2807257d1braf	return (forkx(0));
281657b1f3raf}
282657b1f3raf
283657b1f3raf/*
284657b1f3raf * Much of the logic here is the same as in forkx().
285657b1f3raf * See the comments in forkx(), above.
286657b1f3raf */
287dfb96a4abpid_t
2887257d1brafforkallx(int flags)
2897c478bdstevel@tonic-gate{
2907c478bdstevel@tonic-gate	ulwp_t *self = curthread;
2917c478bdstevel@tonic-gate	uberdata_t *udp = self->ul_uberdata;
2927c478bdstevel@tonic-gate	pid_t pid;
2937c478bdstevel@tonic-gate
2947c478bdstevel@tonic-gate	if (self->ul_vfork) {
2957c478bdstevel@tonic-gate		if (udp->uberflags.uf_mt) {
2967c478bdstevel@tonic-gate			errno = ENOTSUP;
2977c478bdstevel@tonic-gate			return (-1);
2987c478bdstevel@tonic-gate		}
299657b1f3raf		pid = __forkallx(flags);
3007c478bdstevel@tonic-gate		if (pid == 0) {		/* child */
3018cd4554raf			udp->pid = getpid();
3027c478bdstevel@tonic-gate			self->ul_vfork = 0;
3037c478bdstevel@tonic-gate		}
3047c478bdstevel@tonic-gate		return (pid);
3057c478bdstevel@tonic-gate	}
3067c478bdstevel@tonic-gate
3072e14588raf	sigoff(self);
3082e14588raf	if (self->ul_fork) {
3092e14588raf		sigon(self);
3102e14588raf		errno = EDEADLK;
3117c478bdstevel@tonic-gate		return (-1);
3127c478bdstevel@tonic-gate	}
3137c478bdstevel@tonic-gate	self->ul_fork = 1;
3148cd4554raf	(void) mutex_lock(&udp->atfork_lock);
3158cd4554raf	(void) mutex_lock(&udp->fork_lock);
3167c478bdstevel@tonic-gate	block_all_signals(self);
3177c478bdstevel@tonic-gate	suspend_fork();
3187c478bdstevel@tonic-gate
319657b1f3raf	pid = __forkallx(flags);
3207c478bdstevel@tonic-gate
3217c478bdstevel@tonic-gate	if (pid == 0) {
3227c478bdstevel@tonic-gate		self->ul_schedctl_called = NULL;
3237c478bdstevel@tonic-gate		self->ul_schedctl = NULL;
3247c478bdstevel@tonic-gate		self->ul_cursig = 0;
3257c478bdstevel@tonic-gate		self->ul_siginfo.si_signo = 0;
3268cd4554raf		udp->pid = getpid();
327c242ec1Roger A. Faulkner		unregister_locks();
3287c478bdstevel@tonic-gate		continue_fork(1);
3297c478bdstevel@tonic-gate	} else {
3307c478bdstevel@tonic-gate		continue_fork(0);
3317c478bdstevel@tonic-gate	}
3327c478bdstevel@tonic-gate	restore_signals(self);
3338cd4554raf	(void) mutex_unlock(&udp->fork_lock);
3348cd4554raf	(void) mutex_unlock(&udp->atfork_lock);
3352e14588raf	self->ul_fork = 0;
3362e14588raf	sigon(self);
3377c478bdstevel@tonic-gate
3387c478bdstevel@tonic-gate	return (pid);
3397c478bdstevel@tonic-gate}
3407c478bdstevel@tonic-gate
341657b1f3rafpid_t
3427257d1brafforkall(void)
343657b1f3raf{
3447257d1braf	return (forkallx(0));
345657b1f3raf}
346657b1f3raf
3477c478bdstevel@tonic-gate/*
348a574db8raf * For the implementation of cancellation at cancellation points.
3497c478bdstevel@tonic-gate */
3507c478bdstevel@tonic-gate#define	PROLOGUE							\
3517c478bdstevel@tonic-gate{									\
3527c478bdstevel@tonic-gate	ulwp_t *self = curthread;					\
353a574db8raf	int nocancel =							\
354a574db8raf	    (self->ul_vfork | self->ul_nocancel | self->ul_libc_locks |	\
355a574db8raf	    self->ul_critical | self->ul_sigdefer);			\
356a574db8raf	int abort = 0;							\
3577c478bdstevel@tonic-gate	if (nocancel == 0) {						\
3587c478bdstevel@tonic-gate		self->ul_save_async = self->ul_cancel_async;		\
3597c478bdstevel@tonic-gate		if (!self->ul_cancel_disabled) {			\
3607c478bdstevel@tonic-gate			self->ul_cancel_async = 1;			\
3617c478bdstevel@tonic-gate			if (self->ul_cancel_pending)			\
3627257d1braf				pthread_exit(PTHREAD_CANCELED);		\
3637c478bdstevel@tonic-gate		}							\
3647c478bdstevel@tonic-gate		self->ul_sp = stkptr();					\
365a574db8raf	} else if (self->ul_cancel_pending &&				\
366a574db8raf	    !self->ul_cancel_disabled) {				\
367a574db8raf		set_cancel_eintr_flag(self);				\
368a574db8raf		abort = 1;						\
3697c478bdstevel@tonic-gate	}
3707c478bdstevel@tonic-gate
3717c478bdstevel@tonic-gate#define	EPILOGUE							\
3727c478bdstevel@tonic-gate	if (nocancel == 0) {						\
3737c478bdstevel@tonic-gate		self->ul_sp = 0;					\
3747c478bdstevel@tonic-gate		self->ul_cancel_async = self->ul_save_async;		\
3757c478bdstevel@tonic-gate	}								\
3767c478bdstevel@tonic-gate}
3777c478bdstevel@tonic-gate
3787c478bdstevel@tonic-gate/*
3797c478bdstevel@tonic-gate * Perform the body of the action required by most of the cancelable
3807c478bdstevel@tonic-gate * function calls.  The return(function_call) part is to allow the
3817c478bdstevel@tonic-gate * compiler to make the call be executed with tail recursion, which
3827c478bdstevel@tonic-gate * saves a register window on sparc and slightly (not much) improves
3837c478bdstevel@tonic-gate * the code for x86/x64 compilations.
3847c478bdstevel@tonic-gate */
3857c478bdstevel@tonic-gate#define	PERFORM(function_call)						\
3867c478bdstevel@tonic-gate	PROLOGUE							\
387a574db8raf	if (abort) {							\
388a574db8raf		*self->ul_errnop = EINTR;				\
389a574db8raf		return (-1);						\
390a574db8raf	}								\
3917c478bdstevel@tonic-gate	if (nocancel)							\
3927c478bdstevel@tonic-gate		return (function_call);					\
3937c478bdstevel@tonic-gate	rv = function_call;						\
3947c478bdstevel@tonic-gate	EPILOGUE							\
3957c478bdstevel@tonic-gate	return (rv);
3967c478bdstevel@tonic-gate
3977c478bdstevel@tonic-gate/*
3987c478bdstevel@tonic-gate * Specialized prologue for sigsuspend() and pollsys().
3997c478bdstevel@tonic-gate * These system calls pass a signal mask to the kernel.
4007c478bdstevel@tonic-gate * The kernel replaces the thread's signal mask with the
4017c478bdstevel@tonic-gate * temporary mask before the thread goes to sleep.  If
4027c478bdstevel@tonic-gate * a signal is received, the signal handler will execute
4037c478bdstevel@tonic-gate * with the temporary mask, as modified by the sigaction
4047c478bdstevel@tonic-gate * for the particular signal.
4057c478bdstevel@tonic-gate *
4067c478bdstevel@tonic-gate * We block all signals until we reach the kernel with the
4077c478bdstevel@tonic-gate * temporary mask.  This eliminates race conditions with
4087c478bdstevel@tonic-gate * setting the signal mask while signals are being posted.
4097c478bdstevel@tonic-gate */
4107c478bdstevel@tonic-gate#define	PROLOGUE_MASK(sigmask)						\
4117c478bdstevel@tonic-gate{									\
4127c478bdstevel@tonic-gate	ulwp_t *self = curthread;					\
413a574db8raf	int nocancel =							\
414a574db8raf	    (self->ul_vfork | self->ul_nocancel | self->ul_libc_locks |	\
415a574db8raf	    self->ul_critical | self->ul_sigdefer);			\
4167c478bdstevel@tonic-gate	if (!self->ul_vfork) {						\
4177c478bdstevel@tonic-gate		if (sigmask) {						\
4187c478bdstevel@tonic-gate			block_all_signals(self);			\
419bdf0047Roger A. Faulkner			self->ul_tmpmask = *sigmask;			\
4207c478bdstevel@tonic-gate			delete_reserved_signals(&self->ul_tmpmask);	\
4217c478bdstevel@tonic-gate			self->ul_sigsuspend = 1;			\
4227c478bdstevel@tonic-gate		}							\
4237c478bdstevel@tonic-gate		if (nocancel == 0) {					\
4247c478bdstevel@tonic-gate			self->ul_save_async = self->ul_cancel_async;	\
4257c478bdstevel@tonic-gate			if (!self->ul_cancel_disabled) {		\
4267c478bdstevel@tonic-gate				self->ul_cancel_async = 1;		\
4277c478bdstevel@tonic-gate				if (self->ul_cancel_pending) {		\
4287c478bdstevel@tonic-gate					if (self->ul_sigsuspend) {	\
4297c478bdstevel@tonic-gate						self->ul_sigsuspend = 0;\
4307c478bdstevel@tonic-gate						restore_signals(self);	\
4317c478bdstevel@tonic-gate					}				\
4327257d1braf					pthread_exit(PTHREAD_CANCELED);	\
4337c478bdstevel@tonic-gate				}					\
4347c478bdstevel@tonic-gate			}						\
4357c478bdstevel@tonic-gate			self->ul_sp = stkptr();				\
4367c478bdstevel@tonic-gate		}							\
4377c478bdstevel@tonic-gate	}
4387c478bdstevel@tonic-gate
4397c478bdstevel@tonic-gate/*
4407c478bdstevel@tonic-gate * If a signal is taken, we return from the system call wrapper with
4417c478bdstevel@tonic-gate * our original signal mask restored (see code in call_user_handler()).
4427c478bdstevel@tonic-gate * If not (self->ul_sigsuspend is still non-zero), we must restore our
4437c478bdstevel@tonic-gate * original signal mask ourself.
4447c478bdstevel@tonic-gate */
4457c478bdstevel@tonic-gate#define	EPILOGUE_MASK							\
4467c478bdstevel@tonic-gate	if (nocancel == 0) {						\
4477c478bdstevel@tonic-gate		self->ul_sp = 0;					\
4487c478bdstevel@tonic-gate		self->ul_cancel_async = self->ul_save_async;		\
4497c478bdstevel@tonic-gate	}								\
4507c478bdstevel@tonic-gate	if (self->ul_sigsuspend) {					\
4517c478bdstevel@tonic-gate		self->ul_sigsuspend = 0;				\
4527c478bdstevel@tonic-gate		restore_signals(self);					\
4537c478bdstevel@tonic-gate	}								\
4547c478bdstevel@tonic-gate}
4557c478bdstevel@tonic-gate
4567c478bdstevel@tonic-gate/*
457f841f6araf * Cancellation prologue and epilogue functions,
458f841f6araf * for cancellation points too complex to include here.
4593470957raf */
4603470957rafvoid
4613470957raf_cancel_prologue(void)
4623470957raf{
4633470957raf	ulwp_t *self = curthread;
4643470957raf
465a574db8raf	self->ul_cancel_prologue =
466a574db8raf	    (self->ul_vfork | self->ul_nocancel | self->ul_libc_locks |
467a574db8raf	    self->ul_critical | self->ul_sigdefer) != 0;
4683470957raf	if (self->ul_cancel_prologue == 0) {
4693470957raf		self->ul_save_async = self->ul_cancel_async;
4703470957raf		if (!self->ul_cancel_disabled) {
4713470957raf			self->ul_cancel_async = 1;
4723470957raf			if (self->ul_cancel_pending)
4737257d1braf				pthread_exit(PTHREAD_CANCELED);
4743470957raf		}
4753470957raf		self->ul_sp = stkptr();
476a574db8raf	} else if (self->ul_cancel_pending &&
477a574db8raf	    !self->ul_cancel_disabled) {
478a574db8raf		set_cancel_eintr_flag(self);
4793470957raf	}
4803470957raf}
4813470957raf
4823470957rafvoid
4833470957raf_cancel_epilogue(void)
4843470957raf{
4853470957raf	ulwp_t *self = curthread;
4863470957raf
4873470957raf	if (self->ul_cancel_prologue == 0) {
4883470957raf		self->ul_sp = 0;
4893470957raf		self->ul_cancel_async = self->ul_save_async;
4903470957raf	}
4913470957raf}
4923470957raf
4933470957raf/*
4947c478bdstevel@tonic-gate * Called from _thrp_join() (thr_join() is a cancellation point)
4957c478bdstevel@tonic-gate */
4967c478bdstevel@tonic-gateint
4977c478bdstevel@tonic-gatelwp_wait(thread_t tid, thread_t *found)
4987c478bdstevel@tonic-gate{
4997c478bdstevel@tonic-gate	int error;
5007c478bdstevel@tonic-gate
5017c478bdstevel@tonic-gate	PROLOGUE
502a574db8raf	if (abort)
503a574db8raf		return (EINTR);
504a574db8raf	while ((error = __lwp_wait(tid, found)) == EINTR && !cancel_active())
505a574db8raf		continue;
5067c478bdstevel@tonic-gate	EPILOGUE
5077c478bdstevel@tonic-gate	return (error);
5087c478bdstevel@tonic-gate}
5097c478bdstevel@tonic-gate
5107c478bdstevel@tonic-gatessize_t
5117257d1brafread(int fd, void *buf, size_t size)
5127c478bdstevel@tonic-gate{
513a574db8raf	extern ssize_t __read(int, void *, size_t);
5147c478bdstevel@tonic-gate	ssize_t rv;
5157c478bdstevel@tonic-gate
516a574db8raf	PERFORM(__read(fd, buf, size))
5177c478bdstevel@tonic-gate}
5187c478bdstevel@tonic-gate
5197c478bdstevel@tonic-gatessize_t
5207257d1brafwrite(int fd, const void *buf, size_t size)
5217c478bdstevel@tonic-gate{
522a574db8raf	extern ssize_t __write(int, const void *, size_t);
5237c478bdstevel@tonic-gate	ssize_t rv;
5247c478bdstevel@tonic-gate
525a574db8raf	PERFORM(__write(fd, buf, size))
5267c478bdstevel@tonic-gate}
5277c478bdstevel@tonic-gate
5287c478bdstevel@tonic-gateint
5297257d1brafgetmsg(int fd, struct strbuf *ctlptr, struct strbuf *dataptr,
5307c478bdstevel@tonic-gate	int *flagsp)
5317c478bdstevel@tonic-gate{
532a574db8raf	extern int __getmsg(int, struct strbuf *, struct strbuf *, int *);
5337c478bdstevel@tonic-gate	int rv;
5347c478bdstevel@tonic-gate
535a574db8raf	PERFORM(__getmsg(fd, ctlptr, dataptr, flagsp))
5367c478bdstevel@tonic-gate}
5377c478bdstevel@tonic-gate
5387c478bdstevel@tonic-gateint
5397257d1brafgetpmsg(int fd, struct strbuf *ctlptr, struct strbuf *dataptr,
5407c478bdstevel@tonic-gate	int *bandp, int *flagsp)
5417c478bdstevel@tonic-gate{
542a574db8raf	extern int __getpmsg(int, struct strbuf *, struct strbuf *,
5432e14588raf	    int *, int *);
5447c478bdstevel@tonic-gate	int rv;
5457c478bdstevel@tonic-gate
546a574db8raf	PERFORM(__getpmsg(fd, ctlptr, dataptr, bandp, flagsp))
5477c478bdstevel@tonic-gate}
5487c478bdstevel@tonic-gate
5497c478bdstevel@tonic-gateint
5507257d1brafputmsg(int fd, const struct strbuf *ctlptr,
5517c478bdstevel@tonic-gate	const struct strbuf *dataptr, int flags)
5527c478bdstevel@tonic-gate{
553a574db8raf	extern int __putmsg(int, const struct strbuf *,
5542e14588raf	    const struct strbuf *, int);
5557c478bdstevel@tonic-gate	int rv;
5567c478bdstevel@tonic-gate
557a574db8raf	PERFORM(__putmsg(fd, ctlptr, dataptr, flags))
5587c478bdstevel@tonic-gate}
5597c478bdstevel@tonic-gate
5607c478bdstevel@tonic-gateint
5617c478bdstevel@tonic-gate__xpg4_putmsg(int fd, const struct strbuf *ctlptr,
5627c478bdstevel@tonic-gate	const struct strbuf *dataptr, int flags)
5637c478bdstevel@tonic-gate{
564a574db8raf	extern int __putmsg(int, const struct strbuf *,
5652e14588raf	    const struct strbuf *, int);
5667c478bdstevel@tonic-gate	int rv;
5677c478bdstevel@tonic-gate
568a574db8raf	PERFORM(__putmsg(fd, ctlptr, dataptr, flags|MSG_XPG4))
5697c478bdstevel@tonic-gate}
5707c478bdstevel@tonic-gate
5717c478bdstevel@tonic-gateint
5727257d1brafputpmsg(int fd, const struct strbuf *ctlptr,
5737c478bdstevel@tonic-gate	const struct strbuf *dataptr, int band, int flags)
5747c478bdstevel@tonic-gate{
575a574db8raf	extern int __putpmsg(int, const struct strbuf *,
5762e14588raf	    const struct strbuf *, int, int);
5777c478bdstevel@tonic-gate	int rv;
5787c478bdstevel@tonic-gate
579a574db8raf	PERFORM(__putpmsg(fd, ctlptr, dataptr, band, flags))
5807c478bdstevel@tonic-gate}
5817c478bdstevel@tonic-gate
5827c478bdstevel@tonic-gateint
5837c478bdstevel@tonic-gate__xpg4_putpmsg(int fd, const struct strbuf *ctlptr,
5847c478bdstevel@tonic-gate	const struct strbuf *dataptr, int band, int flags)
5857c478bdstevel@tonic-gate{
586a574db8raf	extern int __putpmsg(int, const struct strbuf *,
5872e14588raf	    const struct strbuf *, int, int);
5887c478bdstevel@tonic-gate	int rv;
5897c478bdstevel@tonic-gate
590a574db8raf	PERFORM(__putpmsg(fd, ctlptr, dataptr, band, flags|MSG_XPG4))
5917c478bdstevel@tonic-gate}
5927c478bdstevel@tonic-gate
5937c478bdstevel@tonic-gateint
5947257d1brafnanosleep(const timespec_t *rqtp, timespec_t *rmtp)
5957c478bdstevel@tonic-gate{
5967c478bdstevel@tonic-gate	int error;
5977c478bdstevel@tonic-gate
5987c478bdstevel@tonic-gate	PROLOGUE
599a574db8raf	error = abort? EINTR : __nanosleep(rqtp, rmtp);
6007c478bdstevel@tonic-gate	EPILOGUE
6017c478bdstevel@tonic-gate	if (error) {
6027c478bdstevel@tonic-gate		errno = error;
6037c478bdstevel@tonic-gate		return (-1);
6047c478bdstevel@tonic-gate	}
6057c478bdstevel@tonic-gate	return (0);
6067c478bdstevel@tonic-gate}
6077c478bdstevel@tonic-gate
6087c478bdstevel@tonic-gateint
6097257d1brafclock_nanosleep(clockid_t clock_id, int flags,
6107c478bdstevel@tonic-gate	const timespec_t *rqtp, timespec_t *rmtp)
6117c478bdstevel@tonic-gate{
6127c478bdstevel@tonic-gate	timespec_t reltime;
6137c478bdstevel@tonic-gate	hrtime_t start;
6147c478bdstevel@tonic-gate	hrtime_t rqlapse;
6157c478bdstevel@tonic-gate	hrtime_t lapse;
6167c478bdstevel@tonic-gate	int error;
6177c478bdstevel@tonic-gate
6187c478bdstevel@tonic-gate	switch (clock_id) {
6197c478bdstevel@tonic-gate	case CLOCK_VIRTUAL:
6207c478bdstevel@tonic-gate	case CLOCK_PROCESS_CPUTIME_ID:
6217c478bdstevel@tonic-gate	case CLOCK_THREAD_CPUTIME_ID:
6227c478bdstevel@tonic-gate		return (ENOTSUP);
6237c478bdstevel@tonic-gate	case CLOCK_REALTIME:
6247c478bdstevel@tonic-gate	case CLOCK_HIGHRES:
6257c478bdstevel@tonic-gate		break;
6267c478bdstevel@tonic-gate	default:
6277c478bdstevel@tonic-gate		return (EINVAL);
6287c478bdstevel@tonic-gate	}
6297c478bdstevel@tonic-gate	if (flags & TIMER_ABSTIME) {
6307c478bdstevel@tonic-gate		abstime_to_reltime(clock_id, rqtp, &reltime);
6317c478bdstevel@tonic-gate		rmtp = NULL;
6327c478bdstevel@tonic-gate	} else {
6337c478bdstevel@tonic-gate		reltime = *rqtp;
6347c478bdstevel@tonic-gate		if (clock_id == CLOCK_HIGHRES)
6357c478bdstevel@tonic-gate			start = gethrtime();
6367c478bdstevel@tonic-gate	}
6377c478bdstevel@tonic-gaterestart:
6387c478bdstevel@tonic-gate	PROLOGUE
639a574db8raf	error = abort? EINTR : __nanosleep(&reltime, rmtp);
6407c478bdstevel@tonic-gate	EPILOGUE
6417c478bdstevel@tonic-gate	if (error == 0 && clock_id == CLOCK_HIGHRES) {
6427c478bdstevel@tonic-gate		/*
6437c478bdstevel@tonic-gate		 * Don't return yet if we didn't really get a timeout.
6447c478bdstevel@tonic-gate		 * This can happen if we return because someone resets
6457c478bdstevel@tonic-gate		 * the system clock.
6467c478bdstevel@tonic-gate		 */
6477c478bdstevel@tonic-gate		if (flags & TIMER_ABSTIME) {
6487c478bdstevel@tonic-gate			if ((hrtime_t)(uint32_t)rqtp->tv_sec * NANOSEC +
6497c478bdstevel@tonic-gate			    rqtp->tv_nsec > gethrtime()) {
6507c478bdstevel@tonic-gate				abstime_to_reltime(clock_id, rqtp, &reltime);
6517c478bdstevel@tonic-gate				goto restart;
6527c478bdstevel@tonic-gate			}
6537c478bdstevel@tonic-gate		} else {
6547c478bdstevel@tonic-gate			rqlapse = (hrtime_t)(uint32_t)rqtp->tv_sec * NANOSEC +
6552e14588raf			    rqtp->tv_nsec;
6567c478bdstevel@tonic-gate			lapse = gethrtime() - start;
6577c478bdstevel@tonic-gate			if (rqlapse > lapse) {
6587c478bdstevel@tonic-gate				hrt2ts(rqlapse - lapse, &reltime);
6597c478bdstevel@tonic-gate				goto restart;
6607c478bdstevel@tonic-gate			}
6617c478bdstevel@tonic-gate		}
6627c478bdstevel@tonic-gate	}
6637c478bdstevel@tonic-gate	if (error == 0 && clock_id == CLOCK_REALTIME &&
6647c478bdstevel@tonic-gate	    (flags & TIMER_ABSTIME)) {
6657c478bdstevel@tonic-gate		/*
6667c478bdstevel@tonic-gate		 * Don't return yet just because someone reset the
6677c478bdstevel@tonic-gate		 * system clock.  Recompute the new relative time
6687c478bdstevel@tonic-gate		 * and reissue the nanosleep() call if necessary.
6697c478bdstevel@tonic-gate		 *
6707c478bdstevel@tonic-gate		 * Resetting the system clock causes all sorts of
6717c478bdstevel@tonic-gate		 * problems and the SUSV3 standards body should
6727c478bdstevel@tonic-gate		 * have made the behavior of clock_nanosleep() be
6737c478bdstevel@tonic-gate		 * implementation-defined in such a case rather than
6747c478bdstevel@tonic-gate		 * being specific about honoring the new system time.
6757c478bdstevel@tonic-gate		 * Standards bodies are filled with fools and idiots.
6767c478bdstevel@tonic-gate		 */
6777c478bdstevel@tonic-gate		abstime_to_reltime(clock_id, rqtp, &reltime);
6787c478bdstevel@tonic-gate		if (reltime.tv_sec != 0 || reltime.tv_nsec != 0)
6797c478bdstevel@tonic-gate			goto restart;
6807c478bdstevel@tonic-gate	}
6817c478bdstevel@tonic-gate	return (error);
6827c478bdstevel@tonic-gate}
6837c478bdstevel@tonic-gate
6847c478bdstevel@tonic-gateunsigned int
6857257d1brafsleep(unsigned int sec)
6867c478bdstevel@tonic-gate{
6877c478bdstevel@tonic-gate	unsigned int rem = 0;
6887c478bdstevel@tonic-gate	timespec_t ts;
6897c478bdstevel@tonic-gate	timespec_t tsr;
6907c478bdstevel@tonic-gate
6917c478bdstevel@tonic-gate	ts.tv_sec = (time_t)sec;
6927c478bdstevel@tonic-gate	ts.tv_nsec = 0;
6937257d1braf	if (nanosleep(&ts, &tsr) == -1 && errno == EINTR) {
6947c478bdstevel@tonic-gate		rem = (unsigned int)tsr.tv_sec;
6957c478bdstevel@tonic-gate		if (tsr.tv_nsec >= NANOSEC / 2)
6967c478bdstevel@tonic-gate			rem++;
6977c478bdstevel@tonic-gate	}
6987c478bdstevel@tonic-gate	return (rem);
6997c478bdstevel@tonic-gate}
7007c478bdstevel@tonic-gate
7017c478bdstevel@tonic-gateint
7027257d1brafusleep(useconds_t usec)
7037c478bdstevel@tonic-gate{
7047c478bdstevel@tonic-gate	timespec_t ts;
7057c478bdstevel@tonic-gate
7067c478bdstevel@tonic-gate	ts.tv_sec = usec / MICROSEC;
7077c478bdstevel@tonic-gate	ts.tv_nsec = (long)(usec % MICROSEC) * 1000;
7087257d1braf	(void) nanosleep(&ts, NULL);
7097c478bdstevel@tonic-gate	return (0);
7107c478bdstevel@tonic-gate}
7117c478bdstevel@tonic-gate
7127c478bdstevel@tonic-gateint
7137257d1brafclose(int fildes)
7147c478bdstevel@tonic-gate{
715f841f6araf	extern void _aio_close(int);
716a574db8raf	extern int __close(int);
7177c478bdstevel@tonic-gate	int rv;
7187c478bdstevel@tonic-gate
719720d4a3raf	/*
720720d4a3raf	 * If we call _aio_close() while in a critical region,
721720d4a3raf	 * we will draw an ASSERT() failure, so don't do it.
722720d4a3raf	 * No calls to close() from within libc need _aio_close();
723720d4a3raf	 * only the application's calls to close() need this,
724720d4a3raf	 * and such calls are never from a libc critical region.
725720d4a3raf	 */
726720d4a3raf	if (curthread->ul_critical == 0)
727720d4a3raf		_aio_close(fildes);
728a574db8raf	PERFORM(__close(fildes))
7297c478bdstevel@tonic-gate}
7307c478bdstevel@tonic-gate
7317c478bdstevel@tonic-gateint
7327257d1brafdoor_call(int d, door_arg_t *params)
733a574db8raf{
734a574db8raf	extern int __door_call(int, door_arg_t *);
735a574db8raf	int rv;
736a574db8raf
737a574db8raf	PERFORM(__door_call(d, params))
738a574db8raf}
739a574db8raf
7407c478bdstevel@tonic-gateint
7417257d1braffcntl(int fildes, int cmd, ...)
7427c478bdstevel@tonic-gate{
743a574db8raf	extern int __fcntl(int, int, ...);
7447c478bdstevel@tonic-gate	intptr_t arg;
7457c478bdstevel@tonic-gate	int rv;
7467c478bdstevel@tonic-gate	va_list ap;
7477c478bdstevel@tonic-gate
7487c478bdstevel@tonic-gate	va_start(ap, cmd);
7497c478bdstevel@tonic-gate	arg = va_arg(ap, intptr_t);
7507c478bdstevel@tonic-gate	va_end(ap);
7517c478bdstevel@tonic-gate	if (cmd != F_SETLKW)
752a574db8raf		return (__fcntl(fildes, cmd, arg));
753a574db8raf	PERFORM(__fcntl(fildes, cmd, arg))
7547c478bdstevel@tonic-gate}
7557c478bdstevel@tonic-gate
7567c478bdstevel@tonic-gateint
7577257d1braffdatasync(int fildes)
7581f8cf95raf{
759a574db8raf	extern int __fdsync(int, int);
7601f8cf95raf	int rv;
7611f8cf95raf
762a574db8raf	PERFORM(__fdsync(fildes, FDSYNC))
7631f8cf95raf}
7641f8cf95raf
7651f8cf95rafint
7667257d1braffsync(int fildes)
7677c478bdstevel@tonic-gate{
768a574db8raf	extern int __fdsync(int, int);
7697c478bdstevel@tonic-gate	int rv;
7707c478bdstevel@tonic-gate
771a574db8raf	PERFORM(__fdsync(fildes, FSYNC))
7727c478bdstevel@tonic-gate}
7737c478bdstevel@tonic-gate
7747c478bdstevel@tonic-gateint
7757257d1braflockf(int fildes, int function, off_t size)
7767c478bdstevel@tonic-gate{
777a574db8raf	extern int __lockf(int, int, off_t);
7787c478bdstevel@tonic-gate	int rv;
7797c478bdstevel@tonic-gate
780a574db8raf	PERFORM(__lockf(fildes, function, size))
7817c478bdstevel@tonic-gate}
7827c478bdstevel@tonic-gate
7837c478bdstevel@tonic-gate#if !defined(_LP64)
7847c478bdstevel@tonic-gateint
7857257d1braflockf64(int fildes, int function, off64_t size)
7867c478bdstevel@tonic-gate{
787a574db8raf	extern int __lockf64(int, int, off64_t);
7887c478bdstevel@tonic-gate	int rv;
7897c478bdstevel@tonic-gate
790a574db8raf	PERFORM(__lockf64(fildes, function, size))
7917c478bdstevel@tonic-gate}
7927c478bdstevel@tonic-gate#endif	/* !_LP64 */
7937c478bdstevel@tonic-gate
7947c478bdstevel@tonic-gatessize_t
7957257d1brafmsgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp, int msgflg)
7967c478bdstevel@tonic-gate{
797a574db8raf	extern ssize_t __msgrcv(int, void *, size_t, long, int);
7987c478bdstevel@tonic-gate	ssize_t rv;
7997c478bdstevel@tonic-gate
800a574db8raf	PERFORM(__msgrcv(msqid, msgp, msgsz, msgtyp, msgflg))
801a574db8raf}
802a574db8raf
803a574db8rafint
8047257d1brafmsgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg)
805a574db8raf{
806a574db8raf	extern int __msgsnd(int, const void *, size_t, int);
807a574db8raf	int rv;
808a574db8raf
809a574db8raf	PERFORM(__msgsnd(msqid, msgp, msgsz, msgflg))
8107c478bdstevel@tonic-gate}
8117c478bdstevel@tonic-gate
8127c478bdstevel@tonic-gateint
8137257d1brafmsync(caddr_t addr, size_t len, int flags)
8147c478bdstevel@tonic-gate{
815a574db8raf	extern int __msync(caddr_t, size_t, int);
8167c478bdstevel@tonic-gate	int rv;
8177c478bdstevel@tonic-gate
818a574db8raf	PERFORM(__msync(addr, len, flags))
8197c478bdstevel@tonic-gate}
8207c478bdstevel@tonic-gate
8217c478bdstevel@tonic-gateint
8228fd04b8Roger A. Faulkneropenat(int fd, const char *path, int oflag, ...)
8237c478bdstevel@tonic-gate{
824a574db8raf	mode_t mode;
8257c478bdstevel@tonic-gate	int rv;
826a574db8raf	va_list ap;
8277c478bdstevel@tonic-gate
828a574db8raf	va_start(ap, oflag);
829a574db8raf	mode = va_arg(ap, mode_t);
830a574db8raf	va_end(ap);
8318fd04b8Roger A. Faulkner	PERFORM(__openat(fd, path, oflag, mode))
8327c478bdstevel@tonic-gate}
8337c478bdstevel@tonic-gate
8347c478bdstevel@tonic-gateint
8358fd04b8Roger A. Faulkneropen(const char *path, int oflag, ...)
8367c478bdstevel@tonic-gate{
8377c478bdstevel@tonic-gate	mode_t mode;
8387c478bdstevel@tonic-gate	int rv;
8397c478bdstevel@tonic-gate	va_list ap;
8407c478bdstevel@tonic-gate
8417c478bdstevel@tonic-gate	va_start(ap, oflag);
8427c478bdstevel@tonic-gate	mode = va_arg(ap, mode_t);
8437c478bdstevel@tonic-gate	va_end(ap);
8448fd04b8Roger A. Faulkner	PERFORM(__open(path, oflag, mode))
8458fd04b8Roger A. Faulkner}
8468fd04b8Roger A. Faulkner
8478fd04b8Roger A. Faulknerint
8488fd04b8Roger A. Faulknercreat(const char *path, mode_t mode)
8498fd04b8Roger A. Faulkner{
8508fd04b8Roger A. Faulkner	return (open(path, O_WRONLY | O_CREAT | O_TRUNC, mode));
8517c478bdstevel@tonic-gate}
8527c478bdstevel@tonic-gate
8537c478bdstevel@tonic-gate#if !defined(_LP64)
854a574db8rafint
8558fd04b8Roger A. Faulkneropenat64(int fd, const char *path, int oflag, ...)
856a574db8raf{
857a574db8raf	mode_t mode;
858a574db8raf	int rv;
859a574db8raf	va_list ap;
860a574db8raf
861a574db8raf	va_start(ap, oflag);
862a574db8raf	mode = va_arg(ap, mode_t);
863a574db8raf	va_end(ap);
8648fd04b8Roger A. Faulkner	PERFORM(__openat64(fd, path, oflag, mode))
865a574db8raf}
866a574db8raf
8677c478bdstevel@tonic-gateint
8688fd04b8Roger A. Faulkneropen64(const char *path, int oflag, ...)
8697c478bdstevel@tonic-gate{
8707c478bdstevel@tonic-gate	mode_t mode;
8717c478bdstevel@tonic-gate	int rv;
8727c478bdstevel@tonic-gate	va_list ap;
8737c478bdstevel@tonic-gate
8747c478bdstevel@tonic-gate	va_start(ap, oflag);
8757c478bdstevel@tonic-gate	mode = va_arg(ap, mode_t);
8767c478bdstevel@tonic-gate	va_end(ap);
8778fd04b8Roger A. Faulkner	PERFORM(__open64(path, oflag, mode))
8788fd04b8Roger A. Faulkner}
8798fd04b8Roger A. Faulkner
8808fd04b8Roger A. Faulknerint
8818fd04b8Roger A. Faulknercreat64(const char *path, mode_t mode)
8828fd04b8Roger A. Faulkner{
8838fd04b8Roger A. Faulkner	return (open64(path, O_WRONLY | O_CREAT | O_TRUNC, mode));
8847c478bdstevel@tonic-gate}
8857c478bdstevel@tonic-gate#endif	/* !_LP64 */
8867c478bdstevel@tonic-gate
8877c478bdstevel@tonic-gateint
8887257d1brafpause(void)
8897c478bdstevel@tonic-gate{
890a574db8raf	extern int __pause(void);
8917c478bdstevel@tonic-gate	int rv;
8927c478bdstevel@tonic-gate
893a574db8raf	PERFORM(__pause())
8947c478bdstevel@tonic-gate}
8957c478bdstevel@tonic-gate
8967c478bdstevel@tonic-gatessize_t
8977257d1brafpread(int fildes, void *buf, size_t nbyte, off_t offset)
8987c478bdstevel@tonic-gate{
899a574db8raf	extern ssize_t __pread(int, void *, size_t, off_t);
9007c478bdstevel@tonic-gate	ssize_t rv;
9017c478bdstevel@tonic-gate
902a574db8raf	PERFORM(__pread(fildes, buf, nbyte, offset))
9037c478bdstevel@tonic-gate}
9047c478bdstevel@tonic-gate
9057c478bdstevel@tonic-gate#if !defined(_LP64)
9067c478bdstevel@tonic-gatessize_t
9077257d1brafpread64(int fildes, void *buf, size_t nbyte, off64_t offset)
9087c478bdstevel@tonic-gate{
909a574db8raf	extern ssize_t __pread64(int, void *, size_t, off64_t);
9107c478bdstevel@tonic-gate	ssize_t rv;
9117c478bdstevel@tonic-gate
912a574db8raf	PERFORM(__pread64(fildes, buf, nbyte, offset))
9137c478bdstevel@tonic-gate}
914fca543cDJ Hoffman
915fca543cDJ Hoffmanssize_t
916fca543cDJ Hoffmanpreadv64(int fildes, const struct iovec *iov, int iovcnt, off64_t offset)
917fca543cDJ Hoffman{
918fca543cDJ Hoffman
919fca543cDJ Hoffman	extern ssize_t __preadv64(int, const struct iovec *, int, off_t, off_t);
920fca543cDJ Hoffman	ssize_t rv;
921fca543cDJ Hoffman
922fca543cDJ Hoffman	PERFORM(__preadv64(fildes, iov, iovcnt, offset & 0xffffffffULL,
923fca543cDJ Hoffman	    offset>>32))
924fca543cDJ Hoffman}
9257c478bdstevel@tonic-gate#endif	/* !_LP64 */
9267c478bdstevel@tonic-gate
9277c478bdstevel@tonic-gatessize_t
928fca543cDJ Hoffmanpreadv(int fildes, const struct iovec *iov, int iovcnt, off_t offset)
929fca543cDJ Hoffman{
930fca543cDJ Hoffman
931fca543cDJ Hoffman	extern ssize_t __preadv(int, const struct iovec *, int, off_t, off_t);
932fca543cDJ Hoffman	ssize_t rv;
933fca543cDJ Hoffman
934fca543cDJ Hoffman	PERFORM(__preadv(fildes, iov, iovcnt, offset, 0))
935fca543cDJ Hoffman}
936fca543cDJ Hoffmanssize_t
9377257d1brafpwrite(int fildes, const void *buf, size_t nbyte, off_t offset)
9387c478bdstevel@tonic-gate{
939a574db8raf	extern ssize_t __pwrite(int, const void *, size_t, off_t);
9407c478bdstevel@tonic-gate	ssize_t rv;
9417c478bdstevel@tonic-gate
942a574db8raf	PERFORM(__pwrite(fildes, buf, nbyte, offset))
9437c478bdstevel@tonic-gate}
9447c478bdstevel@tonic-gate
9457c478bdstevel@tonic-gate#if !defined(_LP64)
9467c478bdstevel@tonic-gatessize_t
9477257d1brafpwrite64(int fildes, const void *buf, size_t nbyte, off64_t offset)
9487c478bdstevel@tonic-gate{
949a574db8raf	extern ssize_t __pwrite64(int, const void *, size_t, off64_t);
9507c478bdstevel@tonic-gate	ssize_t rv;
9517c478bdstevel@tonic-gate
952a574db8raf	PERFORM(__pwrite64(fildes, buf, nbyte, offset))
9537c478bdstevel@tonic-gate}
954fca543cDJ Hoffman
955fca543cDJ Hoffmanssize_t
956fca543cDJ Hoffmanpwritev64(int fildes, const struct iovec *iov, int iovcnt, off64_t offset)
957fca543cDJ Hoffman{
958fca543cDJ Hoffman
959fca543cDJ Hoffman	extern ssize_t __pwritev64(int,
960fca543cDJ Hoffman	    const struct iovec *, int, off_t, off_t);
961fca543cDJ Hoffman	ssize_t rv;
962fca543cDJ Hoffman
963fca543cDJ Hoffman	PERFORM(__pwritev64(fildes, iov, iovcnt, offset &
964fca543cDJ Hoffman	    0xffffffffULL, offset>>32))
965fca543cDJ Hoffman}
966fca543cDJ Hoffman
9677c478bdstevel@tonic-gate#endif	/* !_LP64 */
9687c478bdstevel@tonic-gate
9697c478bdstevel@tonic-gatessize_t
970fca543cDJ Hoffmanpwritev(int fildes, const struct iovec *iov, int iovcnt, off_t offset)
971fca543cDJ Hoffman{
972fca543cDJ Hoffman	extern ssize_t __pwritev(int, const struct iovec *, int, off_t, off_t);
973fca543cDJ Hoffman	ssize_t rv;
974fca543cDJ Hoffman
975fca543cDJ Hoffman	PERFORM(__pwritev(fildes, iov, iovcnt, offset, 0))
976fca543cDJ Hoffman}
977fca543cDJ Hoffman
978fca543cDJ Hoffmanssize_t
9797257d1brafreadv(int fildes, const struct iovec *iov, int iovcnt)
9807c478bdstevel@tonic-gate{
981a574db8raf	extern ssize_t __readv(int, const struct iovec *, int);
9827c478bdstevel@tonic-gate	ssize_t rv;
9837c478bdstevel@tonic-gate
984a574db8raf	PERFORM(__readv(fildes, iov, iovcnt))
9857c478bdstevel@tonic-gate}
9867c478bdstevel@tonic-gate
9877c478bdstevel@tonic-gateint
988