17c478bd9Sstevel@tonic-gate /*
27c478bd9Sstevel@tonic-gate * CDDL HEADER START
37c478bd9Sstevel@tonic-gate *
47c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the
534709573Sraf * Common Development and Distribution License (the "License").
634709573Sraf * You may not use this file except in compliance with the License.
77c478bd9Sstevel@tonic-gate *
87c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
97c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing.
107c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions
117c478bd9Sstevel@tonic-gate * and limitations under the License.
127c478bd9Sstevel@tonic-gate *
137c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each
147c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
157c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the
167c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying
177c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner]
187c478bd9Sstevel@tonic-gate *
197c478bd9Sstevel@tonic-gate * CDDL HEADER END
207c478bd9Sstevel@tonic-gate */
210293487cSraf
227c478bd9Sstevel@tonic-gate /*
238fd04b83SRoger A. Faulkner * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
247c478bd9Sstevel@tonic-gate * Use is subject to license terms.
25fca543caSDJ Hoffman * Copyright (c) 2015, Joyent, Inc. All rights reserved.
267c478bd9Sstevel@tonic-gate */
277c478bd9Sstevel@tonic-gate
285dbfd19aSTheo Schlossnagle /* Copyright (c) 2013, OmniTI Computer Consulting, Inc. All rights reserved. */
295dbfd19aSTheo Schlossnagle
307c478bd9Sstevel@tonic-gate #include "lint.h"
317c478bd9Sstevel@tonic-gate #include "thr_uberdata.h"
32*4763305eSRobert Mustacchi #include "libc.h"
337c478bd9Sstevel@tonic-gate #include <stdarg.h>
347c478bd9Sstevel@tonic-gate #include <poll.h>
357c478bd9Sstevel@tonic-gate #include <stropts.h>
367c478bd9Sstevel@tonic-gate #include <dlfcn.h>
37a574db85Sraf #include <wait.h>
38a574db85Sraf #include <sys/socket.h>
397c478bd9Sstevel@tonic-gate #include <sys/uio.h>
40a574db85Sraf #include <sys/file.h>
41a574db85Sraf #include <sys/door.h>
427c478bd9Sstevel@tonic-gate
437c478bd9Sstevel@tonic-gate /*
447257d1b4Sraf * These leading-underbar symbols exist because mistakes were made
457257d1b4Sraf * in the past that put them into non-SUNWprivate versions of
467257d1b4Sraf * the libc mapfiles. They should be eliminated, but oh well...
477257d1b4Sraf */
487257d1b4Sraf #pragma weak _fork = fork
497257d1b4Sraf #pragma weak _read = read
507257d1b4Sraf #pragma weak _write = write
517257d1b4Sraf #pragma weak _getmsg = getmsg
527257d1b4Sraf #pragma weak _getpmsg = getpmsg
537257d1b4Sraf #pragma weak _putmsg = putmsg
547257d1b4Sraf #pragma weak _putpmsg = putpmsg
557257d1b4Sraf #pragma weak _sleep = sleep
567257d1b4Sraf #pragma weak _close = close
577257d1b4Sraf #pragma weak _creat = creat
587257d1b4Sraf #pragma weak _fcntl = fcntl
597257d1b4Sraf #pragma weak _fsync = fsync
607257d1b4Sraf #pragma weak _lockf = lockf
617257d1b4Sraf #pragma weak _msgrcv = msgrcv
627257d1b4Sraf #pragma weak _msgsnd = msgsnd
637257d1b4Sraf #pragma weak _msync = msync
647257d1b4Sraf #pragma weak _open = open
657257d1b4Sraf #pragma weak _openat = openat
667257d1b4Sraf #pragma weak _pause = pause
677257d1b4Sraf #pragma weak _readv = readv
687257d1b4Sraf #pragma weak _sigpause = sigpause
697257d1b4Sraf #pragma weak _sigsuspend = sigsuspend
707257d1b4Sraf #pragma weak _tcdrain = tcdrain
717257d1b4Sraf #pragma weak _waitid = waitid
727257d1b4Sraf #pragma weak _writev = writev
737257d1b4Sraf
747257d1b4Sraf #if !defined(_LP64)
757257d1b4Sraf #pragma weak _creat64 = creat64
767257d1b4Sraf #pragma weak _lockf64 = lockf64
777257d1b4Sraf #pragma weak _open64 = open64
787257d1b4Sraf #pragma weak _openat64 = openat64
797257d1b4Sraf #pragma weak _pread64 = pread64
807257d1b4Sraf #pragma weak _pwrite64 = pwrite64
817257d1b4Sraf #endif
827257d1b4Sraf
837257d1b4Sraf /*
84d56c62ccSraf * These are SUNWprivate, but they are being used by Sun Studio libcollector.
85d56c62ccSraf */
86d56c62ccSraf #pragma weak _fork1 = fork1
87d56c62ccSraf #pragma weak _forkall = forkall
88d56c62ccSraf
89d56c62ccSraf /*
9098c1a6b4Sraf * atfork_lock protects the pthread_atfork() data structures.
9198c1a6b4Sraf *
92b6233ca5Sraf * fork_lock does double-duty. Not only does it (and atfork_lock)
93b6233ca5Sraf * serialize calls to fork() and forkall(), but it also serializes calls
94b6233ca5Sraf * to thr_suspend() and thr_continue() (because fork() and forkall() also
95b6233ca5Sraf * suspend and continue other threads and they want no competition).
96b6233ca5Sraf *
9798c1a6b4Sraf * Functions called in dlopen()ed L10N objects can do anything, including
9898c1a6b4Sraf * call malloc() and free(). Such calls are not fork-safe when protected
9998c1a6b4Sraf * by an ordinary mutex that is acquired in libc's prefork processing
10098c1a6b4Sraf * because, with an interposed malloc library present, there would be a
10198c1a6b4Sraf * lock ordering violation due to the pthread_atfork() prefork function
10298c1a6b4Sraf * in the interposition library acquiring its malloc lock(s) before the
103b6233ca5Sraf * ordinary mutex in libc being acquired by libc's prefork functions.
104b6233ca5Sraf *
10598c1a6b4Sraf * Within libc, calls to malloc() and free() are fork-safe if the calls
10698c1a6b4Sraf * are made while holding no other libc locks. This covers almost all
10798c1a6b4Sraf * of libc's malloc() and free() calls. For those libc code paths, such
10898c1a6b4Sraf * as the above-mentioned L10N calls, that require serialization and that
10998c1a6b4Sraf * may call malloc() or free(), libc uses callout_lock_enter() to perform
11098c1a6b4Sraf * the serialization. This works because callout_lock is not acquired as
11198c1a6b4Sraf * part of running the pthread_atfork() prefork handlers (to avoid the
11298c1a6b4Sraf * lock ordering violation described above). Rather, it is simply
11398c1a6b4Sraf * reinitialized in postfork1_child() to cover the case that some
11498c1a6b4Sraf * now-defunct thread might have been suspended while holding it.
1157c478bd9Sstevel@tonic-gate */
116b6233ca5Sraf
1172e145884Sraf void
fork_lock_enter(void)1182e145884Sraf fork_lock_enter(void)
1197c478bd9Sstevel@tonic-gate {
120b6233ca5Sraf ASSERT(curthread->ul_critical == 0);
1218cd45542Sraf (void) mutex_lock(&curthread->ul_uberdata->fork_lock);
1227c478bd9Sstevel@tonic-gate }
1237c478bd9Sstevel@tonic-gate
1247c478bd9Sstevel@tonic-gate void
fork_lock_exit(void)1257c478bd9Sstevel@tonic-gate fork_lock_exit(void)
1267c478bd9Sstevel@tonic-gate {
127b6233ca5Sraf ASSERT(curthread->ul_critical == 0);
1288cd45542Sraf (void) mutex_unlock(&curthread->ul_uberdata->fork_lock);
129b6233ca5Sraf }
1307c478bd9Sstevel@tonic-gate
131a574db85Sraf /*
132a574db85Sraf * Use cancel_safe_mutex_lock() to protect against being cancelled while
133a574db85Sraf * holding callout_lock and calling outside of libc (via L10N plugins).
134a574db85Sraf * We will honor a pending cancellation request when callout_lock_exit()
135a574db85Sraf * is called, by calling cancel_safe_mutex_unlock().
136a574db85Sraf */
137b6233ca5Sraf void
callout_lock_enter(void)13898c1a6b4Sraf callout_lock_enter(void)
139b6233ca5Sraf {
140b6233ca5Sraf ASSERT(curthread->ul_critical == 0);
141a574db85Sraf cancel_safe_mutex_lock(&curthread->ul_uberdata->callout_lock);
142b6233ca5Sraf }
143b6233ca5Sraf
144b6233ca5Sraf void
callout_lock_exit(void)14598c1a6b4Sraf callout_lock_exit(void)
146b6233ca5Sraf {
147b6233ca5Sraf ASSERT(curthread->ul_critical == 0);
148a574db85Sraf cancel_safe_mutex_unlock(&curthread->ul_uberdata->callout_lock);
1497c478bd9Sstevel@tonic-gate }
1507c478bd9Sstevel@tonic-gate
151dfb96a4fSab196087 pid_t
forkx(int flags)1527257d1b4Sraf forkx(int flags)
1537c478bd9Sstevel@tonic-gate {
1547c478bd9Sstevel@tonic-gate ulwp_t *self = curthread;
1557c478bd9Sstevel@tonic-gate uberdata_t *udp = self->ul_uberdata;
1567c478bd9Sstevel@tonic-gate pid_t pid;
1577c478bd9Sstevel@tonic-gate
1587c478bd9Sstevel@tonic-gate if (self->ul_vfork) {
1597c478bd9Sstevel@tonic-gate /*
1607c478bd9Sstevel@tonic-gate * We are a child of vfork(); omit all of the fork
1617c478bd9Sstevel@tonic-gate * logic and go straight to the system call trap.
1627c478bd9Sstevel@tonic-gate * A vfork() child of a multithreaded parent
1637c478bd9Sstevel@tonic-gate * must never call fork().
1647c478bd9Sstevel@tonic-gate */
1657c478bd9Sstevel@tonic-gate if (udp->uberflags.uf_mt) {
1667c478bd9Sstevel@tonic-gate errno = ENOTSUP;
1677c478bd9Sstevel@tonic-gate return (-1);
1687c478bd9Sstevel@tonic-gate }
169657b1f3dSraf pid = __forkx(flags);
1707c478bd9Sstevel@tonic-gate if (pid == 0) { /* child */
1718cd45542Sraf udp->pid = getpid();
1727c478bd9Sstevel@tonic-gate self->ul_vfork = 0;
1737c478bd9Sstevel@tonic-gate }
1747c478bd9Sstevel@tonic-gate return (pid);
1757c478bd9Sstevel@tonic-gate }
1767c478bd9Sstevel@tonic-gate
1772e145884Sraf sigoff(self);
1782e145884Sraf if (self->ul_fork) {
1797c478bd9Sstevel@tonic-gate /*
1807c478bd9Sstevel@tonic-gate * Cannot call fork() from a fork handler.
1817c478bd9Sstevel@tonic-gate */
1822e145884Sraf sigon(self);
1832e145884Sraf errno = EDEADLK;
1847c478bd9Sstevel@tonic-gate return (-1);
1857c478bd9Sstevel@tonic-gate }
1867c478bd9Sstevel@tonic-gate self->ul_fork = 1;
1877c478bd9Sstevel@tonic-gate
1887c478bd9Sstevel@tonic-gate /*
1897c478bd9Sstevel@tonic-gate * The functions registered by pthread_atfork() are defined by
1907c478bd9Sstevel@tonic-gate * the application and its libraries and we must not hold any
1912e145884Sraf * internal lmutex_lock()-acquired locks while invoking them.
1922e145884Sraf * We hold only udp->atfork_lock to protect the atfork linkages.
1932e145884Sraf * If one of these pthread_atfork() functions attempts to fork
194b6233ca5Sraf * or to call pthread_atfork(), libc will detect the error and
195b6233ca5Sraf * fail the call with EDEADLK. Otherwise, the pthread_atfork()
196b6233ca5Sraf * functions are free to do anything they please (except they
197b6233ca5Sraf * will not receive any signals).
1987c478bd9Sstevel@tonic-gate */
1998cd45542Sraf (void) mutex_lock(&udp->atfork_lock);
2003771f298SRoger A. Faulkner
2013771f298SRoger A. Faulkner /*
2023771f298SRoger A. Faulkner * Posix (SUSv3) requires fork() to be async-signal-safe.
2033771f298SRoger A. Faulkner * This cannot be made to happen with fork handlers in place
2043771f298SRoger A. Faulkner * (they grab locks). To be in nominal compliance, don't run
2053771f298SRoger A. Faulkner * any fork handlers if we are called within a signal context.
2063771f298SRoger A. Faulkner * This leaves the child process in a questionable state with
2073771f298SRoger A. Faulkner * respect to its locks, but at least the parent process does
2083771f298SRoger A. Faulkner * not become deadlocked due to the calling thread attempting
2093771f298SRoger A. Faulkner * to acquire a lock that it already owns.
2103771f298SRoger A. Faulkner */
2113771f298SRoger A. Faulkner if (self->ul_siglink == NULL)
2127c478bd9Sstevel@tonic-gate _prefork_handler();
2137c478bd9Sstevel@tonic-gate
2147c478bd9Sstevel@tonic-gate /*
2152e145884Sraf * Block every other thread attempting thr_suspend() or thr_continue().
2162e145884Sraf */
2178cd45542Sraf (void) mutex_lock(&udp->fork_lock);
2182e145884Sraf
2192e145884Sraf /*
2207c478bd9Sstevel@tonic-gate * Block all signals.
2212e145884Sraf * Just deferring them via sigoff() is not enough.
2227c478bd9Sstevel@tonic-gate * We have to avoid taking a deferred signal in the child
223657b1f3dSraf * that was actually sent to the parent before __forkx().
2247c478bd9Sstevel@tonic-gate */
2257c478bd9Sstevel@tonic-gate block_all_signals(self);
2267c478bd9Sstevel@tonic-gate
2277c478bd9Sstevel@tonic-gate /*
2287c478bd9Sstevel@tonic-gate * This suspends all threads but this one, leaving them
2297c478bd9Sstevel@tonic-gate * suspended outside of any critical regions in the library.
230b6233ca5Sraf * Thus, we are assured that no lmutex_lock()-acquired library
231b6233ca5Sraf * locks are held while we invoke fork() from the current thread.
2327c478bd9Sstevel@tonic-gate */
2337c478bd9Sstevel@tonic-gate suspend_fork();
2347c478bd9Sstevel@tonic-gate
235657b1f3dSraf pid = __forkx(flags);
2367c478bd9Sstevel@tonic-gate
2377c478bd9Sstevel@tonic-gate if (pid == 0) { /* child */
2387c478bd9Sstevel@tonic-gate /*
2397c478bd9Sstevel@tonic-gate * Clear our schedctl pointer.
2407c478bd9Sstevel@tonic-gate * Discard any deferred signal that was sent to the parent.
241657b1f3dSraf * Because we blocked all signals before __forkx(), a
2427c478bd9Sstevel@tonic-gate * deferred signal cannot have been taken by the child.
2437c478bd9Sstevel@tonic-gate */
2447c478bd9Sstevel@tonic-gate self->ul_schedctl_called = NULL;
2457c478bd9Sstevel@tonic-gate self->ul_schedctl = NULL;
2467c478bd9Sstevel@tonic-gate self->ul_cursig = 0;
2477c478bd9Sstevel@tonic-gate self->ul_siginfo.si_signo = 0;
2488cd45542Sraf udp->pid = getpid();
2497c478bd9Sstevel@tonic-gate /* reset the library's data structures to reflect one thread */
250c242ec1bSRoger A. Faulkner unregister_locks();
251f841f6adSraf postfork1_child();
2527c478bd9Sstevel@tonic-gate restore_signals(self);
2538cd45542Sraf (void) mutex_unlock(&udp->fork_lock);
2543771f298SRoger A. Faulkner if (self->ul_siglink == NULL)
2557c478bd9Sstevel@tonic-gate _postfork_child_handler();
2567c478bd9Sstevel@tonic-gate } else {
257657b1f3dSraf /* restart all threads that were suspended for fork() */
2587c478bd9Sstevel@tonic-gate continue_fork(0);
2597c478bd9Sstevel@tonic-gate restore_signals(self);
2608cd45542Sraf (void) mutex_unlock(&udp->fork_lock);
2613771f298SRoger A. Faulkner if (self->ul_siglink == NULL)
2627c478bd9Sstevel@tonic-gate _postfork_parent_handler();
2637c478bd9Sstevel@tonic-gate }
2647c478bd9Sstevel@tonic-gate
2658cd45542Sraf (void) mutex_unlock(&udp->atfork_lock);
2667c478bd9Sstevel@tonic-gate self->ul_fork = 0;
2672e145884Sraf sigon(self);
2687c478bd9Sstevel@tonic-gate
2697c478bd9Sstevel@tonic-gate return (pid);
2707c478bd9Sstevel@tonic-gate }
2717c478bd9Sstevel@tonic-gate
2727c478bd9Sstevel@tonic-gate /*
273657b1f3dSraf * fork() is fork1() for both Posix threads and Solaris threads.
274657b1f3dSraf * The forkall() interface exists for applications that require
275657b1f3dSraf * the semantics of replicating all threads.
2767c478bd9Sstevel@tonic-gate */
2777257d1b4Sraf #pragma weak fork1 = fork
2787c478bd9Sstevel@tonic-gate pid_t
fork(void)2797257d1b4Sraf fork(void)
280657b1f3dSraf {
2817257d1b4Sraf return (forkx(0));
282657b1f3dSraf }
283657b1f3dSraf
284657b1f3dSraf /*
285657b1f3dSraf * Much of the logic here is the same as in forkx().
286657b1f3dSraf * See the comments in forkx(), above.
287657b1f3dSraf */
288dfb96a4fSab196087 pid_t
forkallx(int flags)2897257d1b4Sraf forkallx(int flags)
2907c478bd9Sstevel@tonic-gate {
2917c478bd9Sstevel@tonic-gate ulwp_t *self = curthread;
2927c478bd9Sstevel@tonic-gate uberdata_t *udp = self->ul_uberdata;
2937c478bd9Sstevel@tonic-gate pid_t pid;
2947c478bd9Sstevel@tonic-gate
2957c478bd9Sstevel@tonic-gate if (self->ul_vfork) {
2967c478bd9Sstevel@tonic-gate if (udp->uberflags.uf_mt) {
2977c478bd9Sstevel@tonic-gate errno = ENOTSUP;
2987c478bd9Sstevel@tonic-gate return (-1);
2997c478bd9Sstevel@tonic-gate }
300657b1f3dSraf pid = __forkallx(flags);
3017c478bd9Sstevel@tonic-gate if (pid == 0) { /* child */
3028cd45542Sraf udp->pid = getpid();
3037c478bd9Sstevel@tonic-gate self->ul_vfork = 0;
3047c478bd9Sstevel@tonic-gate }
3057c478bd9Sstevel@tonic-gate return (pid);
3067c478bd9Sstevel@tonic-gate }
3077c478bd9Sstevel@tonic-gate
3082e145884Sraf sigoff(self);
3092e145884Sraf if (self->ul_fork) {
3102e145884Sraf sigon(self);
3112e145884Sraf errno = EDEADLK;
3127c478bd9Sstevel@tonic-gate return (-1);
3137c478bd9Sstevel@tonic-gate }
3147c478bd9Sstevel@tonic-gate self->ul_fork = 1;
3158cd45542Sraf (void) mutex_lock(&udp->atfork_lock);
3168cd45542Sraf (void) mutex_lock(&udp->fork_lock);
3177c478bd9Sstevel@tonic-gate block_all_signals(self);
3187c478bd9Sstevel@tonic-gate suspend_fork();
3197c478bd9Sstevel@tonic-gate
320657b1f3dSraf pid = __forkallx(flags);
3217c478bd9Sstevel@tonic-gate
3227c478bd9Sstevel@tonic-gate if (pid == 0) {
3237c478bd9Sstevel@tonic-gate self->ul_schedctl_called = NULL;
3247c478bd9Sstevel@tonic-gate self->ul_schedctl = NULL;
3257c478bd9Sstevel@tonic-gate self->ul_cursig = 0;
3267c478bd9Sstevel@tonic-gate self->ul_siginfo.si_signo = 0;
3278cd45542Sraf udp->pid = getpid();
328c242ec1bSRoger A. Faulkner unregister_locks();
3297c478bd9Sstevel@tonic-gate continue_fork(1);
3307c478bd9Sstevel@tonic-gate } else {
3317c478bd9Sstevel@tonic-gate continue_fork(0);
3327c478bd9Sstevel@tonic-gate }
3337c478bd9Sstevel@tonic-gate restore_signals(self);
3348cd45542Sraf (void) mutex_unlock(&udp->fork_lock);
3358cd45542Sraf (void) mutex_unlock(&udp->atfork_lock);
3362e145884Sraf self->ul_fork = 0;
3372e145884Sraf sigon(self);
3387c478bd9Sstevel@tonic-gate
3397c478bd9Sstevel@tonic-gate return (pid);
3407c478bd9Sstevel@tonic-gate }
3417c478bd9Sstevel@tonic-gate
342657b1f3dSraf pid_t
forkall(void)3437257d1b4Sraf forkall(void)
344657b1f3dSraf {
3457257d1b4Sraf return (forkallx(0));
346657b1f3dSraf }
347657b1f3dSraf
3487c478bd9Sstevel@tonic-gate /*
349a574db85Sraf * For the implementation of cancellation at cancellation points.
3507c478bd9Sstevel@tonic-gate */
3517c478bd9Sstevel@tonic-gate #define PROLOGUE \
3527c478bd9Sstevel@tonic-gate { \
3537c478bd9Sstevel@tonic-gate ulwp_t *self = curthread; \
354a574db85Sraf int nocancel = \
355a574db85Sraf (self->ul_vfork | self->ul_nocancel | self->ul_libc_locks | \
356a574db85Sraf self->ul_critical | self->ul_sigdefer); \
357a574db85Sraf int abort = 0; \
3587c478bd9Sstevel@tonic-gate if (nocancel == 0) { \
3597c478bd9Sstevel@tonic-gate self->ul_save_async = self->ul_cancel_async; \
3607c478bd9Sstevel@tonic-gate if (!self->ul_cancel_disabled) { \
3617c478bd9Sstevel@tonic-gate self->ul_cancel_async = 1; \
3627c478bd9Sstevel@tonic-gate if (self->ul_cancel_pending) \
3637257d1b4Sraf pthread_exit(PTHREAD_CANCELED); \
3647c478bd9Sstevel@tonic-gate } \
3657c478bd9Sstevel@tonic-gate self->ul_sp = stkptr(); \
366a574db85Sraf } else if (self->ul_cancel_pending && \
367a574db85Sraf !self->ul_cancel_disabled) { \
368a574db85Sraf set_cancel_eintr_flag(self); \
369a574db85Sraf abort = 1; \
3707c478bd9Sstevel@tonic-gate }
3717c478bd9Sstevel@tonic-gate
3727c478bd9Sstevel@tonic-gate #define EPILOGUE \
3737c478bd9Sstevel@tonic-gate if (nocancel == 0) { \
3747c478bd9Sstevel@tonic-gate self->ul_sp = 0; \
3757c478bd9Sstevel@tonic-gate self->ul_cancel_async = self->ul_save_async; \
3767c478bd9Sstevel@tonic-gate } \
3777c478bd9Sstevel@tonic-gate }
3787c478bd9Sstevel@tonic-gate
3797c478bd9Sstevel@tonic-gate /*
3807c478bd9Sstevel@tonic-gate * Perform the body of the action required by most of the cancelable
3817c478bd9Sstevel@tonic-gate * function calls. The return(function_call) part is to allow the
3827c478bd9Sstevel@tonic-gate * compiler to make the call be executed with tail recursion, which
3837c478bd9Sstevel@tonic-gate * saves a register window on sparc and slightly (not much) improves
3847c478bd9Sstevel@tonic-gate * the code for x86/x64 compilations.
3857c478bd9Sstevel@tonic-gate */
3867c478bd9Sstevel@tonic-gate #define PERFORM(function_call) \
3877c478bd9Sstevel@tonic-gate PROLOGUE \
388a574db85Sraf if (abort) { \
389a574db85Sraf *self->ul_errnop = EINTR; \
390a574db85Sraf return (-1); \
391a574db85Sraf } \
3927c478bd9Sstevel@tonic-gate if (nocancel) \
3937c478bd9Sstevel@tonic-gate return (function_call); \
3947c478bd9Sstevel@tonic-gate rv = function_call; \
3957c478bd9Sstevel@tonic-gate EPILOGUE \
3967c478bd9Sstevel@tonic-gate return (rv);
3977c478bd9Sstevel@tonic-gate
3987c478bd9Sstevel@tonic-gate /*
3997c478bd9Sstevel@tonic-gate * Specialized prologue for sigsuspend() and pollsys().
4007c478bd9Sstevel@tonic-gate * These system calls pass a signal mask to the kernel.
4017c478bd9Sstevel@tonic-gate * The kernel replaces the thread's signal mask with the
4027c478bd9Sstevel@tonic-gate * temporary mask before the thread goes to sleep. If
4037c478bd9Sstevel@tonic-gate * a signal is received, the signal handler will execute
4047c478bd9Sstevel@tonic-gate * with the temporary mask, as modified by the sigaction
4057c478bd9Sstevel@tonic-gate * for the particular signal.
4067c478bd9Sstevel@tonic-gate *
4077c478bd9Sstevel@tonic-gate * We block all signals until we reach the kernel with the
4087c478bd9Sstevel@tonic-gate * temporary mask. This eliminates race conditions with
4097c478bd9Sstevel@tonic-gate * setting the signal mask while signals are being posted.
4107c478bd9Sstevel@tonic-gate */
4117c478bd9Sstevel@tonic-gate #define PROLOGUE_MASK(sigmask) \
4127c478bd9Sstevel@tonic-gate { \
4137c478bd9Sstevel@tonic-gate ulwp_t *self = curthread; \
414a574db85Sraf int nocancel = \
415a574db85Sraf (self->ul_vfork | self->ul_nocancel | self->ul_libc_locks | \
416a574db85Sraf self->ul_critical | self->ul_sigdefer); \
4177c478bd9Sstevel@tonic-gate if (!self->ul_vfork) { \
4187c478bd9Sstevel@tonic-gate if (sigmask) { \
4197c478bd9Sstevel@tonic-gate block_all_signals(self); \
420bdf0047cSRoger A. Faulkner self->ul_tmpmask = *sigmask; \
4217c478bd9Sstevel@tonic-gate delete_reserved_signals(&self->ul_tmpmask); \
4227c478bd9Sstevel@tonic-gate self->ul_sigsuspend = 1; \
4237c478bd9Sstevel@tonic-gate } \
4247c478bd9Sstevel@tonic-gate if (nocancel == 0) { \
4257c478bd9Sstevel@tonic-gate self->ul_save_async = self->ul_cancel_async; \
4267c478bd9Sstevel@tonic-gate if (!self->ul_cancel_disabled) { \
4277c478bd9Sstevel@tonic-gate self->ul_cancel_async = 1; \
4287c478bd9Sstevel@tonic-gate if (self->ul_cancel_pending) { \
4297c478bd9Sstevel@tonic-gate if (self->ul_sigsuspend) { \
4307c478bd9Sstevel@tonic-gate self->ul_sigsuspend = 0;\
4317c478bd9Sstevel@tonic-gate restore_signals(self); \
4327c478bd9Sstevel@tonic-gate } \
4337257d1b4Sraf pthread_exit(PTHREAD_CANCELED); \
4347c478bd9Sstevel@tonic-gate } \
4357c478bd9Sstevel@tonic-gate } \
4367c478bd9Sstevel@tonic-gate self->ul_sp = stkptr(); \
4377c478bd9Sstevel@tonic-gate } \
4387c478bd9Sstevel@tonic-gate }
4397c478bd9Sstevel@tonic-gate
4407c478bd9Sstevel@tonic-gate /*
4417c478bd9Sstevel@tonic-gate * If a signal is taken, we return from the system call wrapper with
4427c478bd9Sstevel@tonic-gate * our original signal mask restored (see code in call_user_handler()).
4437c478bd9Sstevel@tonic-gate * If not (self->ul_sigsuspend is still non-zero), we must restore our
4447c478bd9Sstevel@tonic-gate * original signal mask ourself.
4457c478bd9Sstevel@tonic-gate */
4467c478bd9Sstevel@tonic-gate #define EPILOGUE_MASK \
4477c478bd9Sstevel@tonic-gate if (nocancel == 0) { \
4487c478bd9Sstevel@tonic-gate self->ul_sp = 0; \
4497c478bd9Sstevel@tonic-gate self->ul_cancel_async = self->ul_save_async; \
4507c478bd9Sstevel@tonic-gate } \
4517c478bd9Sstevel@tonic-gate if (self->ul_sigsuspend) { \
4527c478bd9Sstevel@tonic-gate self->ul_sigsuspend = 0; \
4537c478bd9Sstevel@tonic-gate restore_signals(self); \
4547c478bd9Sstevel@tonic-gate } \
4557c478bd9Sstevel@tonic-gate }
4567c478bd9Sstevel@tonic-gate
4577c478bd9Sstevel@tonic-gate /*
458f841f6adSraf * Cancellation prologue and epilogue functions,
459f841f6adSraf * for cancellation points too complex to include here.
46034709573Sraf */
46134709573Sraf void
_cancel_prologue(void)46234709573Sraf _cancel_prologue(void)
46334709573Sraf {
46434709573Sraf ulwp_t *self = curthread;
46534709573Sraf
466a574db85Sraf self->ul_cancel_prologue =
467a574db85Sraf (self->ul_vfork | self->ul_nocancel | self->ul_libc_locks |
468a574db85Sraf self->ul_critical | self->ul_sigdefer) != 0;
46934709573Sraf if (self->ul_cancel_prologue == 0) {
47034709573Sraf self->ul_save_async = self->ul_cancel_async;
47134709573Sraf if (!self->ul_cancel_disabled) {
47234709573Sraf self->ul_cancel_async = 1;
47334709573Sraf if (self->ul_cancel_pending)
4747257d1b4Sraf pthread_exit(PTHREAD_CANCELED);
47534709573Sraf }
47634709573Sraf self->ul_sp = stkptr();
477a574db85Sraf } else if (self->ul_cancel_pending &&
478a574db85Sraf !self->ul_cancel_disabled) {
479a574db85Sraf set_cancel_eintr_flag(self);
48034709573Sraf }
48134709573Sraf }
48234709573Sraf
48334709573Sraf void
_cancel_epilogue(void)48434709573Sraf _cancel_epilogue(void)
48534709573Sraf {
48634709573Sraf ulwp_t *self = curthread;
48734709573Sraf
48834709573Sraf if (self->ul_cancel_prologue == 0) {
48934709573Sraf self->ul_sp = 0;
49034709573Sraf self->ul_cancel_async = self->ul_save_async;
49134709573Sraf }
49234709573Sraf }
49334709573Sraf
49434709573Sraf /*
4957c478bd9Sstevel@tonic-gate * Called from _thrp_join() (thr_join() is a cancellation point)
4967c478bd9Sstevel@tonic-gate */
4977c478bd9Sstevel@tonic-gate int
lwp_wait(thread_t tid,thread_t * found)4987c478bd9Sstevel@tonic-gate lwp_wait(thread_t tid, thread_t *found)
4997c478bd9Sstevel@tonic-gate {
5007c478bd9Sstevel@tonic-gate int error;
5017c478bd9Sstevel@tonic-gate
5027c478bd9Sstevel@tonic-gate PROLOGUE
503a574db85Sraf if (abort)
504a574db85Sraf return (EINTR);
505a574db85Sraf while ((error = __lwp_wait(tid, found)) == EINTR && !cancel_active())
506a574db85Sraf continue;
5077c478bd9Sstevel@tonic-gate EPILOGUE
5087c478bd9Sstevel@tonic-gate return (error);
5097c478bd9Sstevel@tonic-gate }
5107c478bd9Sstevel@tonic-gate
5117c478bd9Sstevel@tonic-gate ssize_t
read(int fd,void * buf,size_t size)5127257d1b4Sraf read(int fd, void *buf, size_t size)
5137c478bd9Sstevel@tonic-gate {
514a574db85Sraf extern ssize_t __read(int, void *, size_t);
5157c478bd9Sstevel@tonic-gate ssize_t rv;
5167c478bd9Sstevel@tonic-gate
517a574db85Sraf PERFORM(__read(fd, buf, size))
5187c478bd9Sstevel@tonic-gate }
5197c478bd9Sstevel@tonic-gate
5207c478bd9Sstevel@tonic-gate ssize_t
write(int fd,const void * buf,size_t size)5217257d1b4Sraf write(int fd, const void *buf, size_t size)
5227c478bd9Sstevel@tonic-gate {
523a574db85Sraf extern ssize_t __write(int, const void *, size_t);
5247c478bd9Sstevel@tonic-gate ssize_t rv;
5257c478bd9Sstevel@tonic-gate
526a574db85Sraf PERFORM(__write(fd, buf, size))
5277c478bd9Sstevel@tonic-gate }
5287c478bd9Sstevel@tonic-gate
5297c478bd9Sstevel@tonic-gate int
getmsg(int fd,struct strbuf * ctlptr,struct strbuf * dataptr,int * flagsp)5307257d1b4Sraf getmsg(int fd, struct strbuf *ctlptr, struct strbuf *dataptr,
5317c478bd9Sstevel@tonic-gate int *flagsp)
5327c478bd9Sstevel@tonic-gate {
533a574db85Sraf extern int __getmsg(int, struct strbuf *, struct strbuf *, int *);
5347c478bd9Sstevel@tonic-gate int rv;
5357c478bd9Sstevel@tonic-gate
536a574db85Sraf PERFORM(__getmsg(fd, ctlptr, dataptr, flagsp))
5377c478bd9Sstevel@tonic-gate }
5387c478bd9Sstevel@tonic-gate
5397c478bd9Sstevel@tonic-gate int
getpmsg(int fd,struct strbuf * ctlptr,struct strbuf * dataptr,int * bandp,int * flagsp)5407257d1b4Sraf getpmsg(int fd, struct strbuf *ctlptr, struct strbuf *dataptr,
5417c478bd9Sstevel@tonic-gate int *bandp, int *flagsp)
5427c478bd9Sstevel@tonic-gate {
543a574db85Sraf extern int __getpmsg(int, struct strbuf *, struct strbuf *,
5447c478bd9Sstevel@tonic-gate int *, int *);
5457c478bd9Sstevel@tonic-gate int rv;
5467c478bd9Sstevel@tonic-gate
547a574db85Sraf PERFORM(__getpmsg(fd, ctlptr, dataptr, bandp, flagsp))
5487c478bd9Sstevel@tonic-gate }
5497c478bd9Sstevel@tonic-gate
5507c478bd9Sstevel@tonic-gate int
putmsg(int fd,const struct strbuf * ctlptr,const struct strbuf * dataptr,int flags)5517257d1b4Sraf putmsg(int fd, const struct strbuf *ctlptr,
5527c478bd9Sstevel@tonic-gate const struct strbuf *dataptr, int flags)
5537c478bd9Sstevel@tonic-gate {
554a574db85Sraf extern int __putmsg(int, const struct strbuf *,
5557c478bd9Sstevel@tonic-gate const struct strbuf *, int);
5567c478bd9Sstevel@tonic-gate int rv;
5577c478bd9Sstevel@tonic-gate
558a574db85Sraf PERFORM(__putmsg(fd, ctlptr, dataptr, flags))
5597c478bd9Sstevel@tonic-gate }
5607c478bd9Sstevel@tonic-gate
5617c478bd9Sstevel@tonic-gate int
__xpg4_putmsg(int fd,const struct strbuf * ctlptr,const struct strbuf * dataptr,int flags)5627c478bd9Sstevel@tonic-gate __xpg4_putmsg(int fd, const struct strbuf *ctlptr,
5637c478bd9Sstevel@tonic-gate const struct strbuf *dataptr, int flags)
5647c478bd9Sstevel@tonic-gate {
565a574db85Sraf extern int __putmsg(int, const struct strbuf *,
5667c478bd9Sstevel@tonic-gate const struct strbuf *, int);
5677c478bd9Sstevel@tonic-gate int rv;
5687c478bd9Sstevel@tonic-gate
569a574db85Sraf PERFORM(__putmsg(fd, ctlptr, dataptr, flags|MSG_XPG4))
5707c478bd9Sstevel@tonic-gate }
5717c478bd9Sstevel@tonic-gate
5727c478bd9Sstevel@tonic-gate int
putpmsg(int fd,const struct strbuf * ctlptr,const struct strbuf * dataptr,int band,int flags)5737257d1b4Sraf putpmsg(int fd, const struct strbuf *ctlptr,
5747c478bd9Sstevel@tonic-gate const struct strbuf *dataptr, int band, int flags)
5757c478bd9Sstevel@tonic-gate {
576a574db85Sraf extern int __putpmsg(int, const struct strbuf *,
5777c478bd9Sstevel@tonic-gate const struct strbuf *, int, int);
5787c478bd9Sstevel@tonic-gate int rv;
5797c478bd9Sstevel@tonic-gate
580a574db85Sraf PERFORM(__putpmsg(fd, ctlptr, dataptr, band, flags))
5817c478bd9Sstevel@tonic-gate }
5827c478bd9Sstevel@tonic-gate
5837c478bd9Sstevel@tonic-gate int
__xpg4_putpmsg(int fd,const struct strbuf * ctlptr,const struct strbuf * dataptr,int band,int flags)5847c478bd9Sstevel@tonic-gate __xpg4_putpmsg(int fd, const struct strbuf *ctlptr,
5857c478bd9Sstevel@tonic-gate const struct strbuf *dataptr, int band, int flags)
5867c478bd9Sstevel@tonic-gate {
587a574db85Sraf extern int __putpmsg(int, const struct strbuf *,
5887c478bd9Sstevel@tonic-gate const struct strbuf *, int, int);
5897c478bd9Sstevel@tonic-gate int rv;
5907c478bd9Sstevel@tonic-gate
591a574db85Sraf PERFORM(__putpmsg(fd, ctlptr, dataptr, band, flags|MSG_XPG4))
5927c478bd9Sstevel@tonic-gate }
5937c478bd9Sstevel@tonic-gate
5947c478bd9Sstevel@tonic-gate int
nanosleep(const timespec_t * rqtp,timespec_t * rmtp)5957257d1b4Sraf nanosleep(const timespec_t *rqtp, timespec_t *rmtp)
5967c478bd9Sstevel@tonic-gate {
5977c478bd9Sstevel@tonic-gate int error;
5987c478bd9Sstevel@tonic-gate
5997c478bd9Sstevel@tonic-gate PROLOGUE
600a574db85Sraf error = abort? EINTR : __nanosleep(rqtp, rmtp);
6017c478bd9Sstevel@tonic-gate EPILOGUE
6027c478bd9Sstevel@tonic-gate if (error) {
6037c478bd9Sstevel@tonic-gate errno = error;
6047c478bd9Sstevel@tonic-gate return (-1);
6057c478bd9Sstevel@tonic-gate }
6067c478bd9Sstevel@tonic-gate return (0);
6077c478bd9Sstevel@tonic-gate }
6087c478bd9Sstevel@tonic-gate
6097c478bd9Sstevel@tonic-gate int
clock_nanosleep(clockid_t clock_id,int flags,const timespec_t * rqtp,timespec_t * rmtp)6107257d1b4Sraf clock_nanosleep(clockid_t clock_id, int flags,
6117c478bd9Sstevel@tonic-gate const timespec_t *rqtp, timespec_t *rmtp)
6127c478bd9Sstevel@tonic-gate {
6137c478bd9Sstevel@tonic-gate timespec_t reltime;
6147c478bd9Sstevel@tonic-gate hrtime_t start;
6157c478bd9Sstevel@tonic-gate hrtime_t rqlapse;
6167c478bd9Sstevel@tonic-gate hrtime_t lapse;
6177c478bd9Sstevel@tonic-gate int error;
6187c478bd9Sstevel@tonic-gate
6197c478bd9Sstevel@tonic-gate switch (clock_id) {
6207c478bd9Sstevel@tonic-gate case CLOCK_VIRTUAL:
6217c478bd9Sstevel@tonic-gate case CLOCK_PROCESS_CPUTIME_ID:
6227c478bd9Sstevel@tonic-gate case CLOCK_THREAD_CPUTIME_ID:
6237c478bd9Sstevel@tonic-gate return (ENOTSUP);
6247c478bd9Sstevel@tonic-gate case CLOCK_REALTIME:
6257c478bd9Sstevel@tonic-gate case CLOCK_HIGHRES:
6267c478bd9Sstevel@tonic-gate break;
6277c478bd9Sstevel@tonic-gate default:
6287c478bd9Sstevel@tonic-gate return (EINVAL);
6297c478bd9Sstevel@tonic-gate }
6307c478bd9Sstevel@tonic-gate if (flags & TIMER_ABSTIME) {
6317c478bd9Sstevel@tonic-gate abstime_to_reltime(clock_id, rqtp, &reltime);
6327c478bd9Sstevel@tonic-gate rmtp = NULL;
6337c478bd9Sstevel@tonic-gate } else {
6347c478bd9Sstevel@tonic-gate reltime = *rqtp;
6357c478bd9Sstevel@tonic-gate if (clock_id == CLOCK_HIGHRES)
6367c478bd9Sstevel@tonic-gate start = gethrtime();
6377c478bd9Sstevel@tonic-gate }
6387c478bd9Sstevel@tonic-gate restart:
6397c478bd9Sstevel@tonic-gate PROLOGUE
640a574db85Sraf error = abort? EINTR : __nanosleep(&reltime, rmtp);
6417c478bd9Sstevel@tonic-gate EPILOGUE
6427c478bd9Sstevel@tonic-gate if (error == 0 && clock_id == CLOCK_HIGHRES) {
6437c478bd9Sstevel@tonic-gate /*
6447c478bd9Sstevel@tonic-gate * Don't return yet if we didn't really get a timeout.
6457c478bd9Sstevel@tonic-gate * This can happen if we return because someone resets
6467c478bd9Sstevel@tonic-gate * the system clock.
6477c478bd9Sstevel@tonic-gate */
6487c478bd9Sstevel@tonic-gate if (flags & TIMER_ABSTIME) {
6497c478bd9Sstevel@tonic-gate if ((hrtime_t)(uint32_t)rqtp->tv_sec * NANOSEC +
6507c478bd9Sstevel@tonic-gate rqtp->tv_nsec > gethrtime()) {
6517c478bd9Sstevel@tonic-gate abstime_to_reltime(clock_id, rqtp, &reltime);
6527c478bd9Sstevel@tonic-gate goto restart;
6537c478bd9Sstevel@tonic-gate }
6547c478bd9Sstevel@tonic-gate } else {
6557c478bd9Sstevel@tonic-gate rqlapse = (hrtime_t)(uint32_t)rqtp->tv_sec * NANOSEC +
6567c478bd9Sstevel@tonic-gate rqtp->tv_nsec;
6577c478bd9Sstevel@tonic-gate lapse = gethrtime() - start;
6587c478bd9Sstevel@tonic-gate if (rqlapse > lapse) {
6597c478bd9Sstevel@tonic-gate hrt2ts(rqlapse - lapse, &reltime);
6607c478bd9Sstevel@tonic-gate goto restart;
6617c478bd9Sstevel@tonic-gate }
6627c478bd9Sstevel@tonic-gate }
6637c478bd9Sstevel@tonic-gate }
6647c478bd9Sstevel@tonic-gate if (error == 0 && clock_id == CLOCK_REALTIME &&
6657c478bd9Sstevel@tonic-gate (flags & TIMER_ABSTIME)) {
6667c478bd9Sstevel@tonic-gate /*
6677c478bd9Sstevel@tonic-gate * Don't return yet just because someone reset the
6687c478bd9Sstevel@tonic-gate * system clock. Recompute the new relative time
6697c478bd9Sstevel@tonic-gate * and reissue the nanosleep() call if necessary.
6707c478bd9Sstevel@tonic-gate *
6717c478bd9Sstevel@tonic-gate * Resetting the system clock causes all sorts of
6727c478bd9Sstevel@tonic-gate * problems and the SUSV3 standards body should
6737c478bd9Sstevel@tonic-gate * have made the behavior of clock_nanosleep() be
6747c478bd9Sstevel@tonic-gate * implementation-defined in such a case rather than
6757c478bd9Sstevel@tonic-gate * being specific about honoring the new system time.
6767c478bd9Sstevel@tonic-gate * Standards bodies are filled with fools and idiots.
6777c478bd9Sstevel@tonic-gate */
6787c478bd9Sstevel@tonic-gate abstime_to_reltime(clock_id, rqtp, &reltime);
6797c478bd9Sstevel@tonic-gate if (reltime.tv_sec != 0 || reltime.tv_nsec != 0)
6807c478bd9Sstevel@tonic-gate goto restart;
6817c478bd9Sstevel@tonic-gate }
6827c478bd9Sstevel@tonic-gate return (error);
6837c478bd9Sstevel@tonic-gate }
6847c478bd9Sstevel@tonic-gate
6857c478bd9Sstevel@tonic-gate unsigned int
sleep(unsigned int sec)6867257d1b4Sraf sleep(unsigned int sec)
6877c478bd9Sstevel@tonic-gate {
6887c478bd9Sstevel@tonic-gate unsigned int rem = 0;
6897c478bd9Sstevel@tonic-gate timespec_t ts;
6907c478bd9Sstevel@tonic-gate timespec_t tsr;
6917c478bd9Sstevel@tonic-gate
6927c478bd9Sstevel@tonic-gate ts.tv_sec = (time_t)sec;
6937c478bd9Sstevel@tonic-gate ts.tv_nsec = 0;
6947257d1b4Sraf if (nanosleep(&ts, &tsr) == -1 && errno == EINTR) {
6957c478bd9Sstevel@tonic-gate rem = (unsigned int)tsr.tv_sec;
6967c478bd9Sstevel@tonic-gate if (tsr.tv_nsec >= NANOSEC / 2)
6977c478bd9Sstevel@tonic-gate rem++;
6987c478bd9Sstevel@tonic-gate }
6997c478bd9Sstevel@tonic-gate return (rem);
7007c478bd9Sstevel@tonic-gate }
7017c478bd9Sstevel@tonic-gate
7027c478bd9Sstevel@tonic-gate int
usleep(useconds_t usec)7037257d1b4Sraf usleep(useconds_t usec)
7047c478bd9Sstevel@tonic-gate {
7057c478bd9Sstevel@tonic-gate timespec_t ts;
7067c478bd9Sstevel@tonic-gate
7077c478bd9Sstevel@tonic-gate ts.tv_sec = usec / MICROSEC;
7087c478bd9Sstevel@tonic-gate ts.tv_nsec = (long)(usec % MICROSEC) * 1000;
7097257d1b4Sraf (void) nanosleep(&ts, NULL);
7107c478bd9Sstevel@tonic-gate return (0);
7117c478bd9Sstevel@tonic-gate }
7127c478bd9Sstevel@tonic-gate
7137c478bd9Sstevel@tonic-gate int
close(int fildes)7147257d1b4Sraf close(int fildes)
7157c478bd9Sstevel@tonic-gate {
716f841f6adSraf extern void _aio_close(int);
717a574db85Sraf extern int __close(int);
7187c478bd9Sstevel@tonic-gate int rv;
7197c478bd9Sstevel@tonic-gate
720720d4a35Sraf /*
721720d4a35Sraf * If we call _aio_close() while in a critical region,
722720d4a35Sraf * we will draw an ASSERT() failure, so don't do it.
723720d4a35Sraf * No calls to close() from within libc need _aio_close();
724720d4a35Sraf * only the application's calls to close() need this,
725720d4a35Sraf * and such calls are never from a libc critical region.
726720d4a35Sraf */
727720d4a35Sraf if (curthread->ul_critical == 0)
728f841f6adSraf _aio_close(fildes);
729a574db85Sraf PERFORM(__close(fildes))
7307c478bd9Sstevel@tonic-gate }
7317c478bd9Sstevel@tonic-gate
7327c478bd9Sstevel@tonic-gate int
door_call(int d,door_arg_t * params)7337257d1b4Sraf door_call(int d, door_arg_t *params)
7347c478bd9Sstevel@tonic-gate {
735a574db85Sraf extern int __door_call(int, door_arg_t *);
736a574db85Sraf int rv;
737a574db85Sraf
738a574db85Sraf PERFORM(__door_call(d, params))
739a574db85Sraf }
740a574db85Sraf
741a574db85Sraf int
fcntl(int fildes,int cmd,...)7427257d1b4Sraf fcntl(int fildes, int cmd, ...)
743a574db85Sraf {
744a574db85Sraf extern int __fcntl(int, int, ...);
7450250c53aSRobert Mustacchi intptr_t arg, arg1 = 0;
7467c478bd9Sstevel@tonic-gate int rv;
7477c478bd9Sstevel@tonic-gate va_list ap;
7487c478bd9Sstevel@tonic-gate
7497c478bd9Sstevel@tonic-gate va_start(ap, cmd);
7500250c53aSRobert Mustacchi switch (cmd) {
7510250c53aSRobert Mustacchi case F_DUP3FD:
7520250c53aSRobert Mustacchi arg = va_arg(ap, int);
7530250c53aSRobert Mustacchi arg1 = va_arg(ap, int);
7540250c53aSRobert Mustacchi break;
7550250c53aSRobert Mustacchi default:
7567c478bd9Sstevel@tonic-gate arg = va_arg(ap, intptr_t);
7570250c53aSRobert Mustacchi break;
7580250c53aSRobert Mustacchi }
7597c478bd9Sstevel@tonic-gate va_end(ap);
7607c478bd9Sstevel@tonic-gate if (cmd != F_SETLKW)
7610250c53aSRobert Mustacchi return (__fcntl(fildes, cmd, arg, arg1));
762a574db85Sraf PERFORM(__fcntl(fildes, cmd, arg))
7637c478bd9Sstevel@tonic-gate }
7647c478bd9Sstevel@tonic-gate
7657c478bd9Sstevel@tonic-gate int
fdatasync(int fildes)7667257d1b4Sraf fdatasync(int fildes)
7671f8cf95fSraf {
7681f8cf95fSraf int rv;
7691f8cf95fSraf
770*4763305eSRobert Mustacchi PERFORM(__fdsync(fildes, FDSYNC_DATA))
7711f8cf95fSraf }
7721f8cf95fSraf
7731f8cf95fSraf int
fsync(int fildes)7747257d1b4Sraf fsync(int fildes)
7757c478bd9Sstevel@tonic-gate {
7767c478bd9Sstevel@tonic-gate int rv;
7777c478bd9Sstevel@tonic-gate
778*4763305eSRobert Mustacchi PERFORM(__fdsync(fildes, FDSYNC_FILE))
779*4763305eSRobert Mustacchi }
780*4763305eSRobert Mustacchi
781*4763305eSRobert Mustacchi int
syncfs(int fildes)782*4763305eSRobert Mustacchi syncfs(int fildes)
783*4763305eSRobert Mustacchi {
784*4763305eSRobert Mustacchi int rv;
785*4763305eSRobert Mustacchi
786*4763305eSRobert Mustacchi PERFORM(__fdsync(fildes, FDSYNC_FS))
7877c478bd9Sstevel@tonic-gate }
7887c478bd9Sstevel@tonic-gate
7897c478bd9Sstevel@tonic-gate int
lockf(int fildes,int function,off_t size)7907257d1b4Sraf lockf(int fildes, int function, off_t size)
7917c478bd9Sstevel@tonic-gate {
792a574db85Sraf extern int __lockf(int, int, off_t);
7937c478bd9Sstevel@tonic-gate int rv;
7947c478bd9Sstevel@tonic-gate
795a574db85Sraf PERFORM(__lockf(fildes, function, size))
7967c478bd9Sstevel@tonic-gate }
7977c478bd9Sstevel@tonic-gate
7987c478bd9Sstevel@tonic-gate #if !defined(_LP64)
7997c478bd9Sstevel@tonic-gate int
lockf64(int fildes,int function,off64_t size)8007257d1b4Sraf lockf64(int fildes, int function, off64_t size)
8017c478bd9Sstevel@tonic-gate {
802a574db85Sraf extern int __lockf64(int, int, off64_t);
8037c478bd9Sstevel@tonic-gate int rv;
8047c478bd9Sstevel@tonic-gate
805a574db85Sraf PERFORM(__lockf64(fildes, function, size))
8067c478bd9Sstevel@tonic-gate }
8077c478bd9Sstevel@tonic-gate #endif /* !_LP64 */
8087c478bd9Sstevel@tonic-gate
8097c478bd9Sstevel@tonic-gate ssize_t
msgrcv(int msqid,void * msgp,size_t msgsz,long msgtyp,int msgflg)8107257d1b4Sraf msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp, int msgflg)
8117c478bd9Sstevel@tonic-gate {
812a574db85Sraf extern ssize_t __msgrcv(int, void *, size_t, long, int);
8137c478bd9Sstevel@tonic-gate ssize_t rv;
8147c478bd9Sstevel@tonic-gate
815a574db85Sraf PERFORM(__msgrcv(msqid, msgp, msgsz, msgtyp, msgflg))
8167c478bd9Sstevel@tonic-gate }
8177c478bd9Sstevel@tonic-gate
8187c478bd9Sstevel@tonic-gate int
msgsnd(int msqid,const void * msgp,size_t msgsz,int msgflg)8197257d1b4Sraf msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg)
8207c478bd9Sstevel@tonic-gate {
821a574db85Sraf extern int __msgsnd(int, const void *, size_t, int);
8227c478bd9Sstevel@tonic-gate int rv;
8237c478bd9Sstevel@tonic-gate
824a574db85Sraf PERFORM(__msgsnd(msqid, msgp, msgsz, msgflg))
8257c478bd9Sstevel@tonic-gate }
8267c478bd9Sstevel@tonic-gate
8277c478bd9Sstevel@tonic-gate int
msync(void * addr,size_t len,int flags)828df5cd018SRobert Mustacchi msync(void *addr, size_t len, int flags)
8297c478bd9Sstevel@tonic-gate {
830a574db85Sraf extern int __msync(caddr_t, size_t, int);
8317c478bd9Sstevel@tonic-gate int rv;
8327c478bd9Sstevel@tonic-gate
833a574db85Sraf PERFORM(__msync(addr, len, flags))
8347c478bd9Sstevel@tonic-gate }
8357c478bd9Sstevel@tonic-gate
8367c478bd9Sstevel@tonic-gate int
openat(int fd,const char * path,int oflag,...)8378fd04b83SRoger A. Faulkner openat(int fd, const char *path, int oflag, ...)
8388fd04b83SRoger A. Faulkner {
8398fd04b83SRoger A. Faulkner mode_t mode;
8408fd04b83SRoger A. Faulkner int rv;
8418fd04b83SRoger A. Faulkner va_list ap;
8428fd04b83SRoger A. Faulkner
8438fd04b83SRoger A. Faulkner va_start(ap, oflag);
8448fd04b83SRoger A. Faulkner mode = va_arg(ap, mode_t);
8458fd04b83SRoger A. Faulkner va_end(ap);
8468fd04b83SRoger A. Faulkner PERFORM(__openat(fd, path, oflag, mode))
8478fd04b83SRoger A. Faulkner }
8488fd04b83SRoger A. Faulkner
8498fd04b83SRoger A. Faulkner int
open(const char * path,int oflag,...)8507257d1b4Sraf open(const char *path, int oflag, ...)
8517c478bd9Sstevel@tonic-gate {
8527c478bd9Sstevel@tonic-gate mode_t mode;
8537c478bd9Sstevel@tonic-gate int rv;
8547c478bd9Sstevel@tonic-gate va_list ap;
8557c478bd9Sstevel@tonic-gate
8567c478bd9Sstevel@tonic-gate va_start(ap, oflag);
8577c478bd9Sstevel@tonic-gate mode = va_arg(ap, mode_t);
8587c478bd9Sstevel@tonic-gate va_end(ap);
859a574db85Sraf PERFORM(__open(path, oflag, mode))
8607c478bd9Sstevel@tonic-gate }
8617c478bd9Sstevel@tonic-gate
8627c478bd9Sstevel@tonic-gate int
creat(const char * path,mode_t mode)8638fd04b83SRoger A. Faulkner creat(const char *path, mode_t mode)
8647c478bd9Sstevel@tonic-gate {
8658fd04b83SRoger A. Faulkner return (open(path, O_WRONLY | O_CREAT | O_TRUNC, mode));
8668fd04b83SRoger A. Faulkner }
8678fd04b83SRoger A. Faulkner
8688fd04b83SRoger A. Faulkner #if !defined(_LP64)
8698fd04b83SRoger A. Faulkner int
openat64(int fd,const char * path,int oflag,...)8708fd04b83SRoger A. Faulkner openat64(int fd, const char *path, int oflag, ...)
8718fd04b83SRoger A. Faulkner {
8727c478bd9Sstevel@tonic-gate mode_t mode;
8737c478bd9Sstevel@tonic-gate int rv;
8747c478bd9Sstevel@tonic-gate va_list ap;
8757c478bd9Sstevel@tonic-gate
8767c478bd9Sstevel@tonic-gate va_start(ap, oflag);
8777c478bd9Sstevel@tonic-gate mode = va_arg(ap, mode_t);
8787c478bd9Sstevel@tonic-gate va_end(ap);
8798fd04b83SRoger A. Faulkner PERFORM(__openat64(fd, path, oflag, mode))
8807c478bd9Sstevel@tonic-gate }
8817c478bd9Sstevel@tonic-gate
882a574db85Sraf int
open64(const char * path,int oflag,...)8837257d1b4Sraf open64(const char *path, int oflag, ...)
8847c478bd9Sstevel@tonic-gate {
885a574db85Sraf mode_t mode;
886a574db85Sraf int rv;
887a574db85Sraf va_list ap;
8887c478bd9Sstevel@tonic-gate
889a574db85Sraf va_start(ap, oflag);
890a574db85Sraf mode = va_arg(ap, mode_t);
891a574db85Sraf va_end(ap);
892a574db85Sraf PERFORM(__open64(path, oflag, mode))
893a574db85Sraf }
894a574db85Sraf
895a574db85Sraf int
creat64(const char * path,mode_t mode)8968fd04b83SRoger A. Faulkner creat64(const char *path, mode_t mode)
897a574db85Sraf {
8988fd04b83SRoger A. Faulkner return (open64(path, O_WRONLY | O_CREAT | O_TRUNC, mode));
8997c478bd9Sstevel@tonic-gate }
9007c478bd9Sstevel@tonic-gate #endif /* !_LP64 */
9017c478bd9Sstevel@tonic-gate
902a574db85Sraf int
pause(void)9037257d1b4Sraf pause(void)
9047c478bd9Sstevel@tonic-gate {
905a574db85Sraf extern int __pause(void);
906a574db85Sraf int rv;
907a574db85Sraf
908a574db85Sraf PERFORM(__pause())
909a574db85Sraf }
910a574db85Sraf
911a574db85Sraf ssize_t
pread(int fildes,void * buf,size_t nbyte,off_t offset)9127257d1b4Sraf pread(int fildes, void *buf, size_t nbyte, off_t offset)
913a574db85Sraf {
914a574db85Sraf extern ssize_t __pread(int, void *, size_t, off_t);
9157c478bd9Sstevel@tonic-gate ssize_t rv;
9167c478bd9Sstevel@tonic-gate
917a574db85Sraf PERFORM(__pread(fildes, buf, nbyte, offset))
9187c478bd9Sstevel@tonic-gate }
9197c478bd9Sstevel@tonic-gate
9207c478bd9Sstevel@tonic-gate #if !defined(_LP64)
9217c478bd9Sstevel@tonic-gate ssize_t
pread64(int fildes,void * buf,size_t nbyte,off64_t offset)9227257d1b4Sraf pread64(int fildes, void *buf, size_t nbyte, off64_t offset)
9237c478bd9Sstevel@tonic-gate {
924a574db85Sraf extern ssize_t __pread64(int, void *, size_t, off64_t);
9257c478bd9Sstevel@tonic-gate ssize_t rv;
9267c478bd9Sstevel@tonic-gate
927a574db85Sraf PERFORM(__pread64(fildes, buf, nbyte, offset))
9287c478bd9Sstevel@tonic-gate }
929fca543caSDJ Hoffman
930fca543caSDJ Hoffman ssize_t
preadv64(int fildes,const struct iovec * iov,int iovcnt,off64_t offset)931fca543caSDJ Hoffman preadv64(int fildes, const struct iovec *iov, int iovcnt, off64_t offset)
932fca543caSDJ Hoffman {
933fca543caSDJ Hoffman
934fca543caSDJ Hoffman extern ssize_t __preadv64(int, const struct iovec *, int, off_t, off_t);
935fca543caSDJ Hoffman ssize_t rv;
936fca543caSDJ Hoffman
937fca543caSDJ Hoffman PERFORM(__preadv64(fildes, iov, iovcnt, offset & 0xffffffffULL,
938fca543caSDJ Hoffman offset>>32))
939fca543caSDJ Hoffman }
9407c478bd9Sstevel@tonic-gate #endif /* !_LP64 */
9417c478bd9Sstevel@tonic-gate
9427c478bd9Sstevel@tonic-gate ssize_t
preadv(int fildes,const struct iovec * iov,int iovcnt,off_t offset)943fca543caSDJ Hoffman preadv(int fildes, const struct iovec *iov, int iovcnt, off_t offset)
944fca543caSDJ Hoffman {
945fca543caSDJ Hoffman
946fca543caSDJ Hoffman extern ssize_t __preadv(int, const struct iovec *, int, off_t, off_t);
947fca543caSDJ Hoffman ssize_t rv;
948fca543caSDJ Hoffman
949fca543caSDJ Hoffman PERFORM(__preadv(fildes, iov, iovcnt, offset, 0))
950fca543caSDJ Hoffman }
951fca543caSDJ Hoffman ssize_t
pwrite(int fildes,const void * buf,size_t nbyte,off_t offset)9527257d1b4Sraf pwrite(int fildes, const void *buf, size_t nbyte, off_t offset)
9537c478bd9Sstevel@tonic-gate {
954a574db85Sraf extern ssize_t __pwrite(int, const void *, size_t, off_t);
9557c478bd9Sstevel@tonic-gate ssize_t rv;
9567c478bd9Sstevel@tonic-gate
957a574db85Sraf PERFORM(__pwrite(fildes, buf, nbyte, offset))
9587c478bd9Sstevel@tonic-gate }
9597c478bd9Sstevel@tonic-gate
960a574db85Sraf #if !defined(_LP64)
961a574db85Sraf ssize_t
pwrite64(int fildes,const void * buf,size_t nbyte,off64_t offset)9627257d1b4Sraf pwrite64(int fildes, const void *buf, size_t nbyte, off64_t offset)
9637c478bd9Sstevel@tonic-gate {
964a574db85Sraf extern ssize_t __pwrite64(int, const void *, size_t, off64_t);
965a574db85Sraf ssize_t rv;
966a574db85Sraf
967a574db85Sraf PERFORM(__pwrite64(fildes, buf, nbyte, offset))
968a574db85Sraf }
969fca543caSDJ Hoffman
970fca543caSDJ Hoffman ssize_t
pwritev64(int fildes,const struct iovec * iov,int iovcnt,off64_t offset)971fca543caSDJ Hoffman pwritev64(int fildes, const struct iovec *iov, int iovcnt, off64_t offset)
972fca543caSDJ Hoffman {
973fca543caSDJ Hoffman
974fca543caSDJ Hoffman extern ssize_t __pwritev64(int,
975fca543caSDJ Hoffman const struct iovec *, int, off_t, off_t);
976fca543caSDJ Hoffman ssize_t rv;
977fca543caSDJ Hoffman
978fca543caSDJ Hoffman PERFORM(__pwritev64(fildes, iov, iovcnt, offset &
979fca543caSDJ Hoffman 0xffffffffULL, offset>>32))
980fca543caSDJ Hoffman }
981fca543caSDJ Hoffman
982a574db85Sraf #endif /* !_LP64 */
983a574db85Sraf
984a574db85Sraf ssize_t
pwritev(int fildes,const struct iovec * iov,int iovcnt,off_t offset)985fca543caSDJ Hoffman pwritev(int fildes, const struct iovec *iov, int iovcnt, off_t offset)
986fca543caSDJ Hoffman {
987fca543caSDJ Hoffman extern ssize_t __pwritev(int, const struct iovec *, int, off_t, off_t);
988fca543caSDJ Hoffman ssize_t rv;
989fca543caSDJ Hoffman
990fca543caSDJ Hoffman PERFORM(__pwritev(fildes, iov, iovcnt, offset, 0))
991fca543caSDJ Hoffman }
992fca543caSDJ Hoffman
993fca543caSDJ Hoffman ssize_t
readv(int fildes,const struct iovec * iov,int iovcnt)9947257d1b4Sraf readv(int fildes, const struct iovec *iov, int iovcnt)
995a574db85Sraf {
996a574db85Sraf extern ssize_t __readv(int, const struct iovec *, int);
997a574db85Sraf ssize_t rv;
998a574db85Sraf
999a574db85Sraf PERFORM(__readv(fildes, iov, iovcnt))
1000a574db85Sraf }
1001a574db85Sraf
1002a574db85Sraf int
sigpause(int sig)10037257d1b4Sraf sigpause(int sig)
1004a574db85Sraf {
1005a574db85Sraf extern int __sigpause(int);
10067c478bd9Sstevel@tonic-gate int rv;
10077c478bd9Sstevel@tonic-gate
1008a574db85Sraf PERFORM(__sigpause(sig))
10097c478bd9Sstevel@tonic-gate }
10107c478bd9Sstevel@tonic-gate
10117c478bd9Sstevel@tonic-gate int
sigsuspend(const sigset_t * set)10127257d1b4Sraf sigsuspend(const sigset_t *set)
10137c478bd9Sstevel@tonic-gate {
10147c478bd9Sstevel@tonic-gate extern int __sigsuspend(const sigset_t *);
10157c478bd9Sstevel@tonic-gate int rv;
10167c478bd9Sstevel@tonic-gate
10177c478bd9Sstevel@tonic-gate PROLOGUE_MASK(set)
10187c478bd9Sstevel@tonic-gate rv = __sigsuspend(set);
10197c478bd9Sstevel@tonic-gate EPILOGUE_MASK
10207c478bd9Sstevel@tonic-gate return (rv);
10217c478bd9Sstevel@tonic-gate }
10227c478bd9Sstevel@tonic-gate
10237c478bd9Sstevel@tonic-gate int
_pollsys(struct pollfd * fds,nfds_t nfd,const timespec_t * timeout,const sigset_t * sigmask)10247c478bd9Sstevel@tonic-gate _pollsys(struct pollfd *fds, nfds_t nfd, const timespec_t *timeout,
10257c478bd9Sstevel@tonic-gate const sigset_t *sigmask)
10267c478bd9Sstevel@tonic-gate {
10277c478bd9Sstevel@tonic-gate extern int __pollsys(struct pollfd *, nfds_t, const timespec_t *,
10287c478bd9Sstevel@tonic-gate const sigset_t *);
10297c478bd9Sstevel@tonic-gate int rv;
10307c478bd9Sstevel@tonic-gate
10317c478bd9Sstevel@tonic-gate PROLOGUE_MASK(sigmask)
10327c478bd9Sstevel@tonic-gate rv = __pollsys(fds, nfd, timeout, sigmask);
10337c478bd9Sstevel@tonic-gate EPILOGUE_MASK
10347c478bd9Sstevel@tonic-gate return (rv);
10357c478bd9Sstevel@tonic-gate }
10367c478bd9Sstevel@tonic-gate
10377c478bd9Sstevel@tonic-gate int
sigtimedwait(const sigset_t * set,siginfo_t * infop,const timespec_t * timeout)10387257d1b4Sraf sigtimedwait(const sigset_t *set, siginfo_t *infop, const timespec_t *timeout)
10397c478bd9Sstevel@tonic-gate {
1040f841f6adSraf extern int __sigtimedwait(const sigset_t *, siginfo_t *,
10417c478bd9Sstevel@tonic-gate const timespec_t *);
10427c478bd9Sstevel@tonic-gate siginfo_t info;
10437c478bd9Sstevel@tonic-gate int sig;
10447c478bd9Sstevel@tonic-gate
10457c478bd9Sstevel@tonic-gate PROLOGUE
1046a574db85Sraf if (abort) {
1047a574db85Sraf *self->ul_errnop = EINTR;
1048a574db85Sraf sig = -1;
1049a574db85Sraf } else {
1050f841f6adSraf sig = __sigtimedwait(set, &info, timeout);
10517c478bd9Sstevel@tonic-gate if (sig == SIGCANCEL &&
10527c478bd9Sstevel@tonic-gate (SI_FROMKERNEL(&info) || info.si_code == SI_LWP)) {
10537c478bd9Sstevel@tonic-gate do_sigcancel();
1054a574db85Sraf *self->ul_errnop = EINTR;
10557c478bd9Sstevel@tonic-gate sig = -1;
10567c478bd9Sstevel@tonic-gate }
1057a574db85Sraf }
10587c478bd9Sstevel@tonic-gate EPILOGUE
10597c478bd9Sstevel@tonic-gate if (sig != -1 && infop)
10608cd45542Sraf (void) memcpy(infop, &info, sizeof (*infop));
10617c478bd9Sstevel@tonic-gate return (sig);
10627c478bd9Sstevel@tonic-gate }
10637c478bd9Sstevel@tonic-gate
10647c478bd9Sstevel@tonic-gate int
sigwait(sigset_t * set)10657257d1b4Sraf sigwait(sigset_t *set)
10667c478bd9Sstevel@tonic-gate {
10677257d1b4Sraf return (sigtimedwait(set, NULL, NULL));
1068f841f6adSraf }
1069f841f6adSraf
1070f841f6adSraf int
sigwaitinfo(const sigset_t * set,siginfo_t * info)10717257d1b4Sraf sigwaitinfo(const sigset_t *set, siginfo_t *info)
1072f841f6adSraf {
10737257d1b4Sraf return (sigtimedwait(set, info, NULL));
1074f841f6adSraf }
1075f841f6adSraf
1076f841f6adSraf int
sigqueue(pid_t pid,int signo,const union sigval value)10777257d1b4Sraf sigqueue(pid_t pid, int signo, const union sigval value)
1078f841f6adSraf {
1079f841f6adSraf extern int __sigqueue(pid_t pid, int signo,
1080f841f6adSraf /* const union sigval */ void *value, int si_code, int block);
1081f841f6adSraf return (__sigqueue(pid, signo, value.sival_ptr, SI_QUEUE, 0));
10827c478bd9Sstevel@tonic-gate }
10837c478bd9Sstevel@tonic-gate
10847c478bd9Sstevel@tonic-gate int
_so_accept(int sock,struct sockaddr * addr,uint_t * addrlen,int version,int flags)10855dbfd19aSTheo Schlossnagle _so_accept(int sock, struct sockaddr *addr, uint_t *addrlen, int version,
10865dbfd19aSTheo Schlossnagle int flags)
10877c478bd9Sstevel@tonic-gate {
10885dbfd19aSTheo Schlossnagle extern int __so_accept(int, struct sockaddr *, uint_t *, int, int);
10897c478bd9Sstevel@tonic-gate int rv;
10907c478bd9Sstevel@tonic-gate
10915dbfd19aSTheo Schlossnagle PERFORM(__so_accept(sock, addr, addrlen, version, flags))
10927c478bd9Sstevel@tonic-gate }
10937c478bd9Sstevel@tonic-gate
10947c478bd9Sstevel@tonic-gate int
_so_connect(int sock,struct sockaddr * addr,uint_t addrlen,int version)1095a574db85Sraf _so_connect(int sock, struct sockaddr *addr, uint_t addrlen, int version)
10967c478bd9Sstevel@tonic-gate {
1097a574db85Sraf extern int __so_connect(int, struct sockaddr *, uint_t, int);
10987c478bd9Sstevel@tonic-gate int rv;
10997c478bd9Sstevel@tonic-gate
1100a574db85Sraf PERFORM(__so_connect(sock, addr, addrlen, version))
11017c478bd9Sstevel@tonic-gate }
11027c478bd9Sstevel@tonic-gate
1103a574db85Sraf int
_so_recv(int sock,void * buf,size_t len,int flags)1104a574db85Sraf _so_recv(int sock, void *buf, size_t len, int flags)
11057c478bd9Sstevel@tonic-gate {
1106a574db85Sraf extern int __so_recv(int, void *, size_t, int);
1107a574db85Sraf int rv;
11087c478bd9Sstevel@tonic-gate
1109a574db85Sraf PERFORM(__so_recv(sock, buf, len, flags))
11107c478bd9Sstevel@tonic-gate }
11117c478bd9Sstevel@tonic-gate
1112a574db85Sraf int
_so_recvfrom(int sock,void * buf,size_t len,int flags,struct sockaddr * addr,int * addrlen)1113a574db85Sraf _so_recvfrom(int sock, void *buf, size_t len, int flags,
1114a574db85Sraf struct sockaddr *addr, int *addrlen)
1115a574db85Sraf {
1116a574db85Sraf extern int __so_recvfrom(int, void *, size_t, int,
1117a574db85Sraf struct sockaddr *, int *);
1118a574db85Sraf int rv;
1119a574db85Sraf
1120a574db85Sraf PERFORM(__so_recvfrom(sock, buf, len, flags, addr, addrlen))
1121a574db85Sraf }
1122a574db85Sraf
1123a574db85Sraf int
_so_recvmsg(int sock,struct msghdr * msg,int flags)1124a574db85Sraf _so_recvmsg(int sock, struct msghdr *msg, int flags)
1125a574db85Sraf {
1126a574db85Sraf extern int __so_recvmsg(int, struct msghdr *, int);
1127a574db85Sraf int rv;
1128a574db85Sraf
1129a574db85Sraf PERFORM(__so_recvmsg(sock, msg, flags))
1130a574db85Sraf }
1131a574db85Sraf
1132a574db85Sraf int
_so_send(int sock,const void * buf,size_t len,int flags)1133a574db85Sraf _so_send(int sock, const void *buf, size_t len, int flags)
1134a574db85Sraf {
1135a574db85Sraf extern int __so_send(int, const void *, size_t, int);
1136a574db85Sraf int rv;
1137a574db85Sraf
1138a574db85Sraf PERFORM(__so_send(sock, buf, len, flags))
1139a574db85Sraf }
1140a574db85Sraf
1141a574db85Sraf int
_so_sendmsg(int sock,const struct msghdr * msg,int flags)1142a574db85Sraf _so_sendmsg(int sock, const struct msghdr *msg, int flags)
1143a574db85Sraf {
1144a574db85Sraf extern int __so_sendmsg(int, const struct msghdr *, int);
1145a574db85Sraf int rv;
1146a574db85Sraf
1147a574db85Sraf PERFORM(__so_sendmsg(sock, msg, flags))
1148a574db85Sraf }
1149a574db85Sraf
1150a574db85Sraf int
_so_sendto(int sock,const void * buf,size_t len,int flags,const struct sockaddr * addr,int * addrlen)1151a574db85Sraf _so_sendto(int sock, const void *buf, size_t len, int flags,
1152a574db85Sraf const struct sockaddr *addr, int *addrlen)
1153a574db85Sraf {
1154a574db85Sraf extern int __so_sendto(int, const void *, size_t, int,
1155a574db85Sraf const struct sockaddr *, int *);
1156a574db85Sraf int rv;
1157a574db85Sraf
1158a574db85Sraf PERFORM(__so_sendto(sock, buf, len, flags, addr, addrlen))
1159a574db85Sraf }
1160a574db85Sraf
1161a574db85Sraf int
tcdrain(int fildes)11627257d1b4Sraf tcdrain(int fildes)
1163a574db85Sraf {
1164a574db85Sraf extern int __tcdrain(int);
1165a574db85Sraf int rv;
1166a574db85Sraf
1167a574db85Sraf PERFORM(__tcdrain(fildes))
1168a574db85Sraf }
1169a574db85Sraf
1170a574db85Sraf int
waitid(idtype_t idtype,id_t id,siginfo_t * infop,int options)11717257d1b4Sraf waitid(idtype_t idtype, id_t id, siginfo_t *infop, int options)
1172a574db85Sraf {
1173a574db85Sraf extern int __waitid(idtype_t, id_t, siginfo_t *, int);
1174a574db85Sraf int rv;
1175a574db85Sraf
1176a574db85Sraf if (options & WNOHANG)
1177a574db85Sraf return (__waitid(idtype, id, infop, options));
1178a574db85Sraf PERFORM(__waitid(idtype, id, infop, options))
1179a574db85Sraf }
1180a574db85Sraf
11817c478bd9Sstevel@tonic-gate ssize_t
writev(int fildes,const struct iovec * iov,int iovcnt)11827257d1b4Sraf writev(int fildes, const struct iovec *iov, int iovcnt)
11837c478bd9Sstevel@tonic-gate {
1184a574db85Sraf extern ssize_t __writev(int, const struct iovec *, int);
11857c478bd9Sstevel@tonic-gate ssize_t rv;
11867c478bd9Sstevel@tonic-gate
1187a574db85Sraf PERFORM(__writev(fildes, iov, iovcnt))
11887c478bd9Sstevel@tonic-gate }
1189