/*-
* Copyright (c) 2002, 2007 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by Nathan J. Williams and Andrew Doran.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
/* Disable namespace mangling, Fortification is useless here anyway. */
#undef _FORTIFY_SOURCE
/* Need to use libc-private names for atomic operations. */
#include "../../common/lib/libc/atomic/atomic_op_namespace.h"
#ifndef lint
/*
* This is necessary because the names are always weak (they are not
* POSIX functions).
*/
#define fsync_range _fsync_range
#define pollts _pollts
/*
* XXX this is necessary to get the prototypes for the __sigsuspend14
* XXX and __msync13 internal names, instead of the application-visible
* XXX sigsuspend and msync names. It's kind of gross, but we're pretty
* XXX intimate with libc already.
*/
#define __LIBC12_SOURCE__
/*
* Provide declarations for the underlying libc syscall stubs. These
* _sys_* functions are symbols defined by libc which invoke the system
* call, without testing for cancellation. Below, we define non-_sys_*
* wrappers which surround calls to _sys_* by the equivalent of
* pthread_testcancel(). Both libc and libpthread define the
* non-_sys_* wrappers, but they are weak in libc and strong in
* libpthread, so programs linked against both will get the libpthread
* wrappers that test for cancellation.
*/
__typeof(accept) _sys_accept;
__typeof(__aio_suspend50) _sys___aio_suspend50;
__typeof(clock_nanosleep) _sys_clock_nanosleep;
__typeof(close) _sys_close;
__typeof(connect) _sys_connect;
__typeof(fcntl) _sys_fcntl;
__typeof(fdatasync) _sys_fdatasync;
__typeof(fsync) _sys_fsync;
__typeof(fsync_range) _sys_fsync_range;
__typeof(__kevent100) _sys___kevent100;
__typeof(mq_receive) _sys_mq_receive;
__typeof(mq_send) _sys_mq_send;
__typeof(__mq_timedreceive50) _sys___mq_timedreceive50;
__typeof(__mq_timedsend50) _sys___mq_timedsend50;
__typeof(msgrcv) _sys_msgrcv;
__typeof(msgsnd) _sys_msgsnd;
__typeof(__msync13) _sys___msync13;
__typeof(__nanosleep50) _sys___nanosleep50;
__typeof(open) _sys_open;
__typeof(openat) _sys_openat;
__typeof(paccept) _sys_paccept;
__typeof(poll) _sys_poll;
__typeof(__pollts50) _sys___pollts50;
__typeof(pread) _sys_pread;
__typeof(__pselect50) _sys___pselect50;
__typeof(pwrite) _sys_pwrite;
__typeof(read) _sys_read;
__typeof(readv) _sys_readv;
__typeof(recvfrom) _sys_recvfrom;
__typeof(recvmmsg) _sys_recvmmsg;
__typeof(recvmsg) _sys_recvmsg;
__typeof(__select50) _sys___select50;
__typeof(sendmmsg) _sys_sendmmsg;
__typeof(sendmsg) _sys_sendmsg;
__typeof(sendto) _sys_sendto;
__typeof(__sigsuspend14) _sys___sigsuspend14;
__typeof(__wait450) _sys___wait450;
__typeof(write) _sys_write;
__typeof(writev) _sys_writev;
#define TESTCANCEL(id) do { \
if (__predict_true(!__uselibcstub) && \
__predict_false(atomic_load_relaxed(&(id)->pt_cancel) & \
PT_CANCEL_CANCELLED)) { \
membar_acquire(); \
pthread__cancelled(); \
} \
} while (0)
int
accept(int s, struct sockaddr *addr, socklen_t *addrlen)
{
int retval;
pthread_t self;
int
__nanosleep50(const struct timespec *rqtp, struct timespec *rmtp)
{
int retval;
pthread_t self;
self = pthread__self();
TESTCANCEL(self);
/*
* For now, just nanosleep. In the future, maybe pass a ucontext_t
* to _lwp_nanosleep() and allow it to recycle our kernel stack.
*/
retval = _sys___nanosleep50(rqtp, rmtp);
TESTCANCEL(self);
return retval;
}
int
open(const char *path, int flags, ...)
{
int retval;
pthread_t self;
va_list ap;