Landing BeOS BONE support.

Thanks to Matthew Zahorik <maz@albany.net> & Paul Ashford <arougthopher@lizardland.net> for the patch.
Bug #71697 r=wtc/cls
This commit is contained in:
seawood%netscape.com 2002-01-10 09:50:36 +00:00
parent 28d27d47f8
commit 7fd9ab2b4e
9 changed files with 604 additions and 318 deletions

84
nsprpub/configure vendored
View File

@ -3004,6 +3004,46 @@ EOF
_OPTIMIZE_FLAGS=-O2
_DEBUG_FLAGS='-gdwarf-2 -O0'
MKSHLIB='$(CCC) $(DSO_LDOPTS) -o $@'
echo $ac_n "checking for gethostbyaddr in -lbind""... $ac_c" 1>&6
echo "configure:3009: checking for gethostbyaddr in -lbind" >&5
ac_lib_var=`echo bind'_'gethostbyaddr | sed 'y%./+-%__p_%'`
if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
ac_save_LIBS="$LIBS"
LIBS="-lbind $LIBS"
cat > conftest.$ac_ext <<EOF
#line 3017 "configure"
#include "confdefs.h"
/* Override any gcc2 internal prototype to avoid an error. */
/* We use char because int might match the return type of a gcc2
builtin and then its argument prototype would still apply. */
char gethostbyaddr();
int main() {
gethostbyaddr()
; return 0; }
EOF
if { (eval echo configure:3028: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
eval "ac_cv_lib_$ac_lib_var=yes"
else
echo "configure: failed program was:" >&5
cat conftest.$ac_ext >&5
rm -rf conftest*
eval "ac_cv_lib_$ac_lib_var=no"
fi
rm -f conftest*
LIBS="$ac_save_LIBS"
fi
if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
echo "$ac_t""yes" 1>&6
OS_LIBS="$OS_LIBS -lbind -lsocket"
else
echo "$ac_t""no" 1>&6
fi
;;
powerpc)
CC=mwcc
@ -4101,17 +4141,17 @@ EOF
ac_safe=`echo "machine/builtins.h" | sed 'y%./+-%__p_%'`
echo $ac_n "checking for machine/builtins.h""... $ac_c" 1>&6
echo "configure:4105: checking for machine/builtins.h" >&5
echo "configure:4145: checking for machine/builtins.h" >&5
if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
#line 4110 "configure"
#line 4150 "configure"
#include "confdefs.h"
#include <machine/builtins.h>
EOF
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
{ (eval echo configure:4115: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
{ (eval echo configure:4155: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
if test -z "$ac_err"; then
rm -rf conftest*
@ -4621,12 +4661,12 @@ esac
if test -z "$SKIP_LIBRARY_CHECKS"; then
echo $ac_n "checking for dlopen""... $ac_c" 1>&6
echo "configure:4625: checking for dlopen" >&5
echo "configure:4665: checking for dlopen" >&5
if eval "test \"`echo '$''{'ac_cv_func_dlopen'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
#line 4630 "configure"
#line 4670 "configure"
#include "confdefs.h"
/* System header to define __stub macros and hopefully few prototypes,
which can conflict with char dlopen(); below. */
@ -4649,7 +4689,7 @@ dlopen();
; return 0; }
EOF
if { (eval echo configure:4653: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
if { (eval echo configure:4693: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
eval "ac_cv_func_dlopen=yes"
else
@ -4668,7 +4708,7 @@ else
echo "$ac_t""no" 1>&6
echo $ac_n "checking for dlopen in -ldl""... $ac_c" 1>&6
echo "configure:4672: checking for dlopen in -ldl" >&5
echo "configure:4712: checking for dlopen in -ldl" >&5
ac_lib_var=`echo dl'_'dlopen | sed 'y%./+-%__p_%'`
if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
@ -4676,7 +4716,7 @@ else
ac_save_LIBS="$LIBS"
LIBS="-ldl $LIBS"
cat > conftest.$ac_ext <<EOF
#line 4680 "configure"
#line 4720 "configure"
#include "confdefs.h"
/* Override any gcc2 internal prototype to avoid an error. */
/* We use char because int might match the return type of a gcc2
@ -4687,7 +4727,7 @@ int main() {
dlopen()
; return 0; }
EOF
if { (eval echo configure:4691: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
if { (eval echo configure:4731: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
eval "ac_cv_lib_$ac_lib_var=yes"
else
@ -4715,13 +4755,13 @@ fi
if test $ac_cv_prog_gcc = yes; then
echo $ac_n "checking whether ${CC-cc} needs -traditional""... $ac_c" 1>&6
echo "configure:4719: checking whether ${CC-cc} needs -traditional" >&5
echo "configure:4759: checking whether ${CC-cc} needs -traditional" >&5
if eval "test \"`echo '$''{'ac_cv_prog_gcc_traditional'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
ac_pattern="Autoconf.*'x'"
cat > conftest.$ac_ext <<EOF
#line 4725 "configure"
#line 4765 "configure"
#include "confdefs.h"
#include <sgtty.h>
Autoconf TIOCGETP
@ -4739,7 +4779,7 @@ rm -f conftest*
if test $ac_cv_prog_gcc_traditional = no; then
cat > conftest.$ac_ext <<EOF
#line 4743 "configure"
#line 4783 "configure"
#include "confdefs.h"
#include <termio.h>
Autoconf TCGETA
@ -4763,12 +4803,12 @@ fi
for ac_func in lchown strerror
do
echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
echo "configure:4767: checking for $ac_func" >&5
echo "configure:4807: checking for $ac_func" >&5
if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
#line 4772 "configure"
#line 4812 "configure"
#include "confdefs.h"
/* System header to define __stub macros and hopefully few prototypes,
which can conflict with char $ac_func(); below. */
@ -4791,7 +4831,7 @@ $ac_func();
; return 0; }
EOF
if { (eval echo configure:4795: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
if { (eval echo configure:4835: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
eval "ac_cv_func_$ac_func=yes"
else
@ -4829,7 +4869,7 @@ fi
echo $ac_n "checking for pthread_create in -lpthreads""... $ac_c" 1>&6
echo "configure:4833: checking for pthread_create in -lpthreads" >&5
echo "configure:4873: checking for pthread_create in -lpthreads" >&5
echo "
#include <pthread.h>
void *foo(void *v) { int a = 1; }
@ -4851,7 +4891,7 @@ echo "
echo "$ac_t""no" 1>&6
echo $ac_n "checking for pthread_create in -lpthread""... $ac_c" 1>&6
echo "configure:4855: checking for pthread_create in -lpthread" >&5
echo "configure:4895: checking for pthread_create in -lpthread" >&5
echo "
#include <pthread.h>
void *foo(void *v) { int a = 1; }
@ -4873,7 +4913,7 @@ echo "
echo "$ac_t""no" 1>&6
echo $ac_n "checking for pthread_create in -lc_r""... $ac_c" 1>&6
echo "configure:4877: checking for pthread_create in -lc_r" >&5
echo "configure:4917: checking for pthread_create in -lc_r" >&5
echo "
#include <pthread.h>
void *foo(void *v) { int a = 1; }
@ -4895,7 +4935,7 @@ echo "
echo "$ac_t""no" 1>&6
echo $ac_n "checking for pthread_create in -lc""... $ac_c" 1>&6
echo "configure:4899: checking for pthread_create in -lc" >&5
echo "configure:4939: checking for pthread_create in -lc" >&5
echo "
#include <pthread.h>
void *foo(void *v) { int a = 1; }
@ -5045,7 +5085,7 @@ if test -n "$USE_PTHREADS"; then
rm -f conftest*
ac_cv_have_dash_pthread=no
echo $ac_n "checking whether ${CC-cc} accepts -pthread""... $ac_c" 1>&6
echo "configure:5049: checking whether ${CC-cc} accepts -pthread" >&5
echo "configure:5089: checking whether ${CC-cc} accepts -pthread" >&5
echo 'int main() { return 0; }' | cat > conftest.c
${CC-cc} -pthread -o conftest conftest.c > conftest.out 2>&1
if test $? -eq 0; then
@ -5061,7 +5101,7 @@ echo "configure:5049: checking whether ${CC-cc} accepts -pthread" >&5
ac_cv_have_dash_pthreads=no
if test "$ac_cv_have_dash_pthread" = "no"; then
echo $ac_n "checking whether ${CC-cc} accepts -pthreads""... $ac_c" 1>&6
echo "configure:5065: checking whether ${CC-cc} accepts -pthreads" >&5
echo "configure:5105: checking whether ${CC-cc} accepts -pthreads" >&5
echo 'int main() { return 0; }' | cat > conftest.c
${CC-cc} -pthreads -o conftest conftest.c > conftest.out 2>&1
if test $? -eq 0; then
@ -5533,7 +5573,7 @@ s%\[%\\&%g
s%\]%\\&%g
s%\$%$$%g
EOF
DEFS=`sed -f conftest.defs confdefs.h | tr '\012' ' ' | tr '\015' ' '`
DEFS=`sed -f conftest.defs confdefs.h | tr '\012' ' ' | tr '\015' ' '`
rm -f conftest.defs

View File

@ -745,6 +745,7 @@ case "$target" in
_OPTIMIZE_FLAGS=-O2
_DEBUG_FLAGS='-gdwarf-2 -O0'
MKSHLIB='$(CCC) $(DSO_LDOPTS) -o $@'
AC_CHECK_LIB(bind, gethostbyaddr, [OS_LIBS="$OS_LIBS -lbind -lsocket"])
;;
powerpc)
CC=mwcc

View File

@ -141,17 +141,21 @@ struct _MDSegment {
** File- and directory-related definitions
*/
#ifndef BONE_VERSION
#define BE_SOCK_SHUTDOWN_READ 0x01
#define BE_SOCK_SHUTDOWN_WRITE 0x02
#endif
struct _MDFileDesc {
PRInt32 osfd;
PRInt32 sock_state;
PRBool accepted_socket;
PRNetAddr peer_addr;
#ifndef BONE_VERSION
PRBool connectValueValid;
int connectReturnValue;
int connectReturnError;
#endif
};
struct _MDDir {
@ -175,14 +179,17 @@ struct _MDFileMap {
* Network related definitions.
*/
#ifndef BONE_VERSION
#define IPPROTO_IP 0
#define AF_UNIX 2
#define TCP_NODELAY SO_NONBLOCK
#define SO_LINGER -1
#define SO_ERROR 4
#endif
#define _PR_INTERRUPT_CHECK_INTERVAL_SECS 5
#ifndef BONE_VERSION
/* these aren't actually used. if they are, we're screwed */
struct protoent {
char *p_name; /* official protocol name */
@ -192,6 +199,7 @@ struct protoent {
struct protoent* getprotobyname(const char* name);
struct protoent* getprotobynumber(int number);
#endif
/*
* malloc() related definitions.
@ -509,7 +517,7 @@ NSPR_API(PRInt32) _MD_open(const char *name, PRIntn osflags, PRIntn mode);
NSPR_API(PRInt32) _MD_close_file(PRInt32 osfd);
NSPR_API(PRInt32) _MD_read(PRFileDesc *fd, void *buf, PRInt32 amount);
NSPR_API(PRInt32) _MD_write(PRFileDesc *fd, const void *buf, PRInt32 amount);
NSPR_API(PRInt32) _MD_writev(PRFileDesc *fd, struct PRIOVec *iov, PRInt32 iov_size, PRIntervalTime timeout);
NSPR_API(PRInt32) _MD_writev(PRFileDesc *fd, const PRIOVec *iov, PRInt32 iov_size, PRIntervalTime timeout);
NSPR_API(PRInt32) _MD_lseek(PRFileDesc *fd, PRInt32 offset, int whence);
NSPR_API(PRInt64) _MD_lseek64(PRFileDesc *fd, PRInt64 offset, int whence);
NSPR_API(PRInt32) _MD_fsync(PRFileDesc *fd);

View File

@ -735,7 +735,7 @@ PR_IMPLEMENT(PRStatus) PR_CreatePipe(
(*readPipe)->secret->inheritable = _PR_TRI_TRUE;
(*writePipe)->secret->inheritable = _PR_TRI_TRUE;
return PR_SUCCESS;
#elif defined(XP_UNIX) || defined(XP_OS2)
#elif defined(XP_UNIX) || defined(XP_OS2) || defined(XP_BEOS)
#ifdef XP_OS2
HFILE pipefd[2];
#else
@ -765,9 +765,13 @@ PR_IMPLEMENT(PRStatus) PR_CreatePipe(
close(pipefd[1]);
return PR_FAILURE;
}
_MD_MakeNonblock(*readPipe);
#ifndef XP_BEOS /* Pipes are nonblocking on BeOS */
_PR_MD_MAKE_NONBLOCK(*readPipe);
#endif
_PR_MD_INIT_FD_INHERITABLE(*readPipe, PR_FALSE);
_MD_MakeNonblock(*writePipe);
#ifndef XP_BEOS /* Pipes are nonblocking on BeOS */
_PR_MD_MAKE_NONBLOCK(*writePipe);
#endif
_PR_MD_INIT_FD_INHERITABLE(*writePipe, PR_FALSE);
return PR_SUCCESS;
#else

View File

@ -57,7 +57,7 @@
#include <netinet/in_systm.h> /* n_short, n_long, n_time */
#endif
#if defined(XP_UNIX) || defined(OS2)
#if defined(XP_UNIX) || defined(OS2) || (defined(XP_BEOS) && defined(BONE_VERSION))
#include <netinet/tcp.h> /* TCP_NODELAY, TCP_MAXSEG */
#endif
@ -86,7 +86,7 @@ PRStatus PR_CALLBACK _PR_SocketGetSocketOption(PRFileDesc *fd, PRSocketOptionDat
{
case PR_SockOpt_Linger:
{
#if !defined(XP_BEOS)
#if !defined(XP_BEOS) || defined(BONE_VERSION)
struct linger linger;
length = sizeof(linger);
rv = _PR_MD_GETSOCKOPT(
@ -244,7 +244,7 @@ PRStatus PR_CALLBACK _PR_SocketSetSocketOption(PRFileDesc *fd, const PRSocketOpt
{
case PR_SockOpt_Linger:
{
#if !defined(XP_BEOS)
#if !defined(XP_BEOS) || defined(BONE_VERSION)
struct linger linger;
linger.l_onoff = data->value.linger.polarity;
linger.l_linger = PR_IntervalToSeconds(data->value.linger.linger);

View File

@ -223,12 +223,14 @@ _MD_write (PRFileDesc *fd, const void *buf, PRInt32 amount)
return( rv );
}
#ifndef BONE_VERSION /* Writev moves to bnet.c with BONE */
PRInt32
_MD_writev (PRFileDesc *fd, struct PRIOVec *iov, PRInt32 iov_size,
_MD_writev (PRFileDesc *fd, const PRIOVec *iov, PRInt32 iov_size,
PRIntervalTime timeout)
{
return PR_NOT_IMPLEMENTED_ERROR;
}
#endif
PRInt32
_MD_lseek (PRFileDesc *fd, PRInt32 offset, int whence)
@ -524,191 +526,227 @@ int rv, err;
}
PRInt32
_MD_pr_poll (PRPollDesc *pds, PRIntn npds, PRIntervalTime timeout)
_MD_pr_poll(PRPollDesc *pds, PRIntn npds, PRIntervalTime timeout)
{
PRInt32 rc = 0;
fd_set rd, wr;
struct timeval tv, *tvp = NULL;
PRInt32 rv = 0;
PRThread *me = _PR_MD_CURRENT_THREAD();
/*
* This code is almost a duplicate of w32poll.c's _PR_MD_PR_POLL().
*/
fd_set rd, wt, ex;
PRFileDesc *bottom;
PRPollDesc *pd, *epd;
int i = 0, j = 0;
int maxfd = -1;
PRInt32 osfd;
PRInt16 in_flags;
PRFileDesc *bottom;
PRInt32 maxfd = -1, ready, err;
PRIntervalTime remaining, elapsed, start;
/*printf("POLL: entering _MD_pr_poll\n");*/
/*
* Is it an empty set? If so, just sleep for the timeout and return
*/
if (npds < 1)
{
/*printf("POLL: empty set. exiting _MD_pr_poll\n");*/
PR_Sleep(timeout);
return rc;
}
struct timeval tv, *tvp = NULL;
FD_ZERO(&rd);
FD_ZERO(&wr);
/*
* first, sort out the new connects, the reads, and the writes
*/
epd = pds + npds;
for(pd = pds; pd < epd; pd++)
if (_PR_PENDING_INTERRUPT(me))
{
in_flags = pd->in_flags;
bottom = pd->fd;
if(bottom != 0 && in_flags != 0)
{
while(bottom->lower != 0)
{
bottom = bottom->lower;
}
osfd = bottom->secret->md.osfd;
if(in_flags & PR_POLL_WRITE || in_flags & PR_POLL_EXCEPT)
{
/*printf("POLL: adding to write\n");*/
FD_SET(osfd, &wr);
if( osfd > maxfd ) maxfd = osfd;
}
if(in_flags & PR_POLL_READ || in_flags & PR_POLL_EXCEPT)
{
/*printf("POLL: adding to read\n");*/
FD_SET(osfd, &rd);
if( osfd > maxfd ) maxfd = osfd;
}
}
}
me->flags &= ~_PR_INTERRUPT;
PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0);
return -1;
}
if(maxfd >= 0)
if (0 == npds) {
PR_Sleep(timeout);
return rv;
}
FD_ZERO(&rd);
FD_ZERO(&wt);
FD_ZERO(&ex);
ready = 0;
for (pd = pds, epd = pd + npds; pd < epd; pd++)
{
PRInt32 n;
do {
PRIntervalTime start = PR_IntervalNow();
if (timeout != PR_INTERVAL_NO_TIMEOUT)
{
/*printf("POLL: timeout = %ld\n", (long) PR_IntervalToMicroseconds(timeout));*/
tv.tv_sec = PR_IntervalToSeconds(timeout);
tv.tv_usec = PR_IntervalToMicroseconds(timeout) % PR_USEC_PER_SEC;
tvp = &tv;
}
n = select(maxfd + 1, &rd, &wr, 0, tvp);
/*printf("POLL: maxfd = %d, select returns %d, errno = %d %s\n", maxfd, n, errno, strerror(errno));*/
if (n == 0 || (n < 0 && errno == EINTR))
{
if (timeout != PR_INTERVAL_NO_TIMEOUT)
{
timeout -= PR_IntervalNow() - start;
if(timeout <= 0)
{
/* timed out */
n = 0;
}
}
}
} while(n < 0 && errno == EINTR);
PRInt16 in_flags_read = 0, in_flags_write = 0;
PRInt16 out_flags_read = 0, out_flags_write = 0;
if(n > 0)
if ((NULL != pd->fd) && (0 != pd->in_flags))
{
epd = pds + npds;
for(pd = pds; pd < epd; pd++)
if (pd->in_flags & PR_POLL_READ)
{
int selected;
in_flags = pd->in_flags;
bottom = pd->fd;
selected = 0;
if(bottom != 0 && in_flags != 0)
in_flags_read = (pd->fd->methods->poll)(pd->fd, pd->in_flags & ~PR_POLL_WRITE, &out_flags_read);
}
if (pd->in_flags & PR_POLL_WRITE)
{
in_flags_write = (pd->fd->methods->poll)(pd->fd, pd->in_flags & ~PR_POLL_READ, &out_flags_write);
}
if ((0 != (in_flags_read & out_flags_read))
|| (0 != (in_flags_write & out_flags_write)))
{
/* this one's ready right now */
if (0 == ready)
{
while(bottom->lower != 0)
/*
* We will have to return without calling the
* system poll/select function. So zero the
* out_flags fields of all the poll descriptors
* before this one.
*/
PRPollDesc *prev;
for (prev = pds; prev < pd; prev++)
{
bottom = bottom->lower;
prev->out_flags = 0;
}
osfd = bottom->secret->md.osfd;
if (FD_ISSET(osfd, &rd))
{
pd->out_flags |= PR_POLL_READ;
selected++;
}
if (FD_ISSET(osfd, &wr))
{
pd->out_flags |= PR_POLL_WRITE;
selected++;
}
if(selected > 0)
{
rc++;
/*
* check if it is a pending connect
*/
PR_Lock( _connectLock );
for( i = 0; i < connectCount; i++ )
{
if(connectList[i].osfd == osfd)
{
int connectError;
int connectResult;
connectResult = connect(connectList[i].osfd,
&connectList[i].addr,
connectList[i].addrlen);
connectError = errno;
if(connectResult < 0 )
{
if(connectError == EINTR || connectError == EWOULDBLOCK
|| connectError == EINPROGRESS || connectError == EALREADY)
{
break;
}
}
if(i == (connectCount - 1))
{
connectList[i].osfd = -1;
} else {
for(j = i; j < connectCount; j++ )
{
memcpy( &connectList[j], &connectList[j+1],
sizeof(connectList[j]));
}
}
connectCount--;
bottom->secret->md.connectReturnValue = connectResult;
bottom->secret->md.connectReturnError = connectError;
bottom->secret->md.connectValueValid = PR_TRUE;
break;
}
}
PR_Unlock( _connectLock );
}
} else {
pd->out_flags = 0;
continue;
}
ready += 1;
pd->out_flags = out_flags_read | out_flags_write;
}
else
{
pd->out_flags = 0; /* pre-condition */
/* make sure this is an NSPR supported stack */
bottom = PR_GetIdentitiesLayer(pd->fd, PR_NSPR_IO_LAYER);
PR_ASSERT(NULL != bottom); /* what to do about that? */
if ((NULL != bottom)
&& (_PR_FILEDESC_OPEN == bottom->secret->state))
{
if (0 == ready)
{
PRInt32 osfd = bottom->secret->md.osfd;
if (osfd > maxfd) maxfd = osfd;
if (in_flags_read & PR_POLL_READ)
{
pd->out_flags |= _PR_POLL_READ_SYS_READ;
FD_SET(osfd, &rd);
}
if (in_flags_read & PR_POLL_WRITE)
{
pd->out_flags |= _PR_POLL_READ_SYS_WRITE;
FD_SET(osfd, &wt);
}
if (in_flags_write & PR_POLL_READ)
{
pd->out_flags |= _PR_POLL_WRITE_SYS_READ;
FD_SET(osfd, &rd);
}
if (in_flags_write & PR_POLL_WRITE)
{
pd->out_flags |= _PR_POLL_WRITE_SYS_WRITE;
FD_SET(osfd, &wt);
}
if (pd->in_flags & PR_POLL_EXCEPT) FD_SET(osfd, &ex);
}
}
else
{
if (0 == ready)
{
PRPollDesc *prev;
for (prev = pds; prev < pd; prev++)
{
prev->out_flags = 0;
}
}
ready += 1; /* this will cause an abrupt return */
pd->out_flags = PR_POLL_NVAL; /* bogii */
}
}
} else if (n < 0) {
/* hit error that's not EINTR. */
rc = -1;
}
}
/*printf("POLL: exiting _MD_pr_poll with %d\n", rc);*/
return rc;
}
if (0 != ready) return ready; /* no need to block */
remaining = timeout;
start = PR_IntervalNow();
retry:
if (timeout != PR_INTERVAL_NO_TIMEOUT)
{
PRInt32 ticksPerSecond = PR_TicksPerSecond();
tv.tv_sec = remaining / ticksPerSecond;
tv.tv_usec = remaining - (ticksPerSecond * tv.tv_sec);
tv.tv_usec = (PR_USEC_PER_SEC * tv.tv_usec) / ticksPerSecond;
tvp = &tv;
}
ready = _MD_SELECT(maxfd + 1, &rd, &wt, &ex, tvp);
if (ready == -1 && errno == EINTR)
{
if (timeout == PR_INTERVAL_NO_TIMEOUT) goto retry;
else
{
elapsed = (PRIntervalTime) (PR_IntervalNow() - start);
if (elapsed > timeout) ready = 0; /* timed out */
else
{
remaining = timeout - elapsed;
goto retry;
}
}
}
/*
** Now to unravel the select sets back into the client's poll
** descriptor list. Is this possibly an area for pissing away
** a few cycles or what?
*/
if (ready > 0)
{
ready = 0;
for (pd = pds, epd = pd + npds; pd < epd; pd++)
{
PRInt16 out_flags = 0;
if ((NULL != pd->fd) && (0 != pd->in_flags))
{
PRInt32 osfd;
bottom = PR_GetIdentitiesLayer(pd->fd, PR_NSPR_IO_LAYER);
PR_ASSERT(NULL != bottom);
osfd = bottom->secret->md.osfd;
if (FD_ISSET(osfd, &rd))
{
if (pd->out_flags & _PR_POLL_READ_SYS_READ)
out_flags |= PR_POLL_READ;
if (pd->out_flags & _PR_POLL_WRITE_SYS_READ)
out_flags |= PR_POLL_WRITE;
}
if (FD_ISSET(osfd, &wt))
{
if (pd->out_flags & _PR_POLL_READ_SYS_WRITE)
out_flags |= PR_POLL_READ;
if (pd->out_flags & _PR_POLL_WRITE_SYS_WRITE)
out_flags |= PR_POLL_WRITE;
}
if (FD_ISSET(osfd, &ex)) out_flags |= PR_POLL_EXCEPT;
}
pd->out_flags = out_flags;
if (out_flags) ready++;
}
PR_ASSERT(ready > 0);
}
else if (ready < 0)
{
err = _MD_ERRNO();
if (err == EBADF)
{
/* Find the bad fds */
ready = 0;
for (pd = pds, epd = pd + npds; pd < epd; pd++)
{
pd->out_flags = 0;
if ((NULL != pd->fd) && (0 != pd->in_flags))
{
bottom = PR_GetIdentitiesLayer(pd->fd, PR_NSPR_IO_LAYER);
if (fcntl(bottom->secret->md.osfd, F_GETFL, 0) == -1)
{
pd->out_flags = PR_POLL_NVAL;
ready++;
}
}
}
PR_ASSERT(ready > 0);
}
else _PR_MD_MAP_SELECT_ERROR(err);
}
return ready;
} /* _MD_pr_poll */
/*
* File locking.

View File

@ -49,6 +49,7 @@
*/
#define _PRSockLen_t int
/*
** Global lock variable used to bracket calls into rusty libraries that
** aren't thread safe (like libc, libX, etc).
@ -56,134 +57,146 @@
static PRLock *_pr_rename_lock = NULL;
static PRMonitor *_pr_Xfe_mon = NULL;
#define READ_FD 1
#define WRITE_FD 2
/*
** This is a support routine to handle "deferred" i/o on sockets.
** It uses "select", so it is subject to all of the BeOS limitations
** (only READ notification, only sockets)
*/
#define READ_FD 1
#define WRITE_FD 2
/*
* socket_io_wait --
*
* wait for socket i/o, periodically checking for interrupt
*
*/
static PRInt32 socket_io_wait(PRInt32 osfd, PRInt32 fd_type,
PRIntervalTime timeout)
{
PRInt32 rv = -1;
struct timeval tv, *tvp;
PRThread *me = _PR_MD_CURRENT_THREAD();
PRIntervalTime epoch, now, elapsed, remaining;
PRInt32 syserror;
fd_set rd_wr;
PRInt32 rv = -1;
struct timeval tv;
PRThread *me = _PR_MD_CURRENT_THREAD();
PRIntervalTime epoch, now, elapsed, remaining;
PRInt32 syserror;
fd_set rd_wr;
switch (timeout) {
case PR_INTERVAL_NO_WAIT:
switch (timeout) {
case PR_INTERVAL_NO_WAIT:
PR_SetError(PR_IO_TIMEOUT_ERROR, 0);
break;
case PR_INTERVAL_NO_TIMEOUT:
/*
* This is a special case of the 'default' case below.
* Please see the comments there.
*/
tv.tv_sec = _PR_INTERRUPT_CHECK_INTERVAL_SECS;
tv.tv_usec = 0;
FD_ZERO(&rd_wr);
do {
FD_SET(osfd, &rd_wr);
if (fd_type == READ_FD)
rv = _MD_SELECT(osfd + 1, &rd_wr, NULL, NULL, &tv);
else
rv = _MD_SELECT(osfd + 1, NULL, &rd_wr, NULL, &tv);
if (rv == -1 && (syserror = _MD_ERRNO()) != EINTR) {
#ifdef BONE_VERSION
_PR_MD_MAP_SELECT_ERROR(syserror);
#else
if (syserror == EBADF) {
PR_SetError(PR_BAD_DESCRIPTOR_ERROR, EBADF);
} else {
PR_SetError(PR_UNKNOWN_ERROR, syserror);
}
#endif
break;
}
if (_PR_PENDING_INTERRUPT(me)) {
me->flags &= ~_PR_INTERRUPT;
PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0);
rv = -1;
break;
}
} while (rv == 0 || (rv == -1 && syserror == EINTR));
break;
default:
now = epoch = PR_IntervalNow();
remaining = timeout;
FD_ZERO(&rd_wr);
do {
/*
* We block in _MD_SELECT for at most
* _PR_INTERRUPT_CHECK_INTERVAL_SECS seconds,
* so that there is an upper limit on the delay
* before the interrupt bit is checked.
*/
tv.tv_sec = PR_IntervalToSeconds(remaining);
if (tv.tv_sec > _PR_INTERRUPT_CHECK_INTERVAL_SECS) {
tv.tv_sec = _PR_INTERRUPT_CHECK_INTERVAL_SECS;
tv.tv_usec = 0;
} else {
tv.tv_usec = PR_IntervalToMicroseconds(
remaining -
PR_SecondsToInterval(tv.tv_sec));
}
FD_SET(osfd, &rd_wr);
if (fd_type == READ_FD)
rv = _MD_SELECT(osfd + 1, &rd_wr, NULL, NULL, &tv);
else
rv = _MD_SELECT(osfd + 1, NULL, &rd_wr, NULL, &tv);
/*
* we don't consider EINTR a real error
*/
if (rv == -1 && (syserror = _MD_ERRNO()) != EINTR) {
#ifdef BONE_VERSION
_PR_MD_MAP_SELECT_ERROR(syserror);
#else
if (syserror == EBADF) {
PR_SetError(PR_BAD_DESCRIPTOR_ERROR, EBADF);
} else {
PR_SetError(PR_UNKNOWN_ERROR, syserror);
}
#endif
break;
}
if (_PR_PENDING_INTERRUPT(me)) {
me->flags &= ~_PR_INTERRUPT;
PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0);
rv = -1;
break;
}
/*
* We loop again if _MD_SELECT timed out or got interrupted
* by a signal, and the timeout deadline has not passed yet.
*/
if (rv == 0 || (rv == -1 && syserror == EINTR)) {
/*
* If _MD_SELECT timed out, we know how much time
* we spent in blocking, so we can avoid a
* PR_IntervalNow() call.
*/
if (rv == 0) {
now += PR_SecondsToInterval(tv.tv_sec)
+ PR_MicrosecondsToInterval(tv.tv_usec);
} else {
now = PR_IntervalNow();
}
elapsed = (PRIntervalTime) (now - epoch);
if (elapsed >= timeout) {
PR_SetError(PR_IO_TIMEOUT_ERROR, 0);
rv = -1;
break;
case PR_INTERVAL_NO_TIMEOUT:
/*
* This is a special case of the 'default' case below.
* Please see the comments there.
*/
tv.tv_sec = _PR_INTERRUPT_CHECK_INTERVAL_SECS;
tv.tv_usec = 0;
tvp = &tv;
FD_ZERO(&rd_wr);
do {
FD_SET(osfd, &rd_wr);
if (fd_type == READ_FD)
rv = _MD_SELECT(osfd + 1, &rd_wr, NULL, NULL, tvp);
else
rv = _MD_SELECT(osfd + 1, NULL, &rd_wr, NULL, tvp);
if (rv == -1 && (syserror = _MD_ERRNO()) != EINTR) {
if (syserror == EBADF) {
PR_SetError(PR_BAD_DESCRIPTOR_ERROR, EBADF);
} else {
PR_SetError(PR_UNKNOWN_ERROR, syserror);
}
if( _PR_PENDING_INTERRUPT(me)) {
me->flags &= ~_PR_INTERRUPT;
PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0);
rv = -1;
break;
}
break;
}
} while (rv == 0 || (rv == -1 && syserror == EINTR));
break;
default:
now = epoch = PR_IntervalNow();
remaining = timeout;
tvp = &tv;
FD_ZERO(&rd_wr);
do {
/*
* We block in _MD_SELECT for at most
* _PR_INTERRUPT_CHECK_INTERVAL_SECS seconds,
* so that there is an upper limit on the delay
* before the interrupt bit is checked.
*/
tv.tv_sec = PR_IntervalToSeconds(remaining);
if (tv.tv_sec > _PR_INTERRUPT_CHECK_INTERVAL_SECS) {
tv.tv_sec = _PR_INTERRUPT_CHECK_INTERVAL_SECS;
tv.tv_usec = 0;
} else {
tv.tv_usec = PR_IntervalToMicroseconds(
remaining -
PR_SecondsToInterval(tv.tv_sec));
}
FD_SET(osfd, &rd_wr);
if (fd_type == READ_FD)
rv = _MD_SELECT(osfd + 1, &rd_wr, NULL, NULL, tvp);
else
rv = _MD_SELECT(osfd + 1, NULL, &rd_wr, NULL, tvp);
/*
* we don't consider EINTR a real error
*/
if (rv == -1 && (syserror = _MD_ERRNO()) != EINTR) {
if (syserror == EBADF) {
PR_SetError(PR_BAD_DESCRIPTOR_ERROR, EBADF);
} else {
PR_SetError(PR_UNKNOWN_ERROR, syserror);
}
break;
}
if (_PR_PENDING_INTERRUPT(me)) {
me->flags &= ~_PR_INTERRUPT;
PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0);
rv = -1;
break;
}
/*
* We loop again if _MD_SELECT timed out or got interrupted
* by a signal, and the timeout deadline has not passed yet.
*/
if (rv == 0 || (rv == -1 && syserror == EINTR)) {
/*
* If _MD_SELECT timed out, we know how much time
* we spent in blocking, so we can avoid a
* PR_IntervalNow() call.
*/
if (rv == 0) {
now += PR_SecondsToInterval(tv.tv_sec)
+ PR_MicrosecondsToInterval(tv.tv_usec);
} else {
now = PR_IntervalNow();
}
elapsed = (PRIntervalTime) (now - epoch);
if (elapsed >= timeout) {
PR_SetError(PR_IO_TIMEOUT_ERROR, 0);
rv = -1;
break;
} else {
remaining = timeout - elapsed;
}
}
} while (rv == 0 || (rv == -1 && syserror == EINTR));
break;
}
return(rv);
}
} else {
remaining = timeout - elapsed;
}
}
} while (rv == 0 || (rv == -1 && syserror == EINTR));
break;
}
return(rv);
}
PRInt32
_MD_recv (PRFileDesc *fd, void *buf, PRInt32 amount, PRInt32 flags,
@ -193,10 +206,22 @@ _MD_recv (PRFileDesc *fd, void *buf, PRInt32 amount, PRInt32 flags,
PRInt32 rv, err;
PRThread *me = _PR_MD_CURRENT_THREAD();
#ifndef BONE_VERSION
if (fd->secret->md.sock_state & BE_SOCK_SHUTDOWN_READ) {
_PR_MD_MAP_RECV_ERROR(EPIPE);
return -1;
}
#endif
#ifdef BONE_VERSION
/*
** Gah, stupid hack. If reading a zero amount, instantly return success.
** BONE beta 6 returns EINVAL for reads of zero bytes, which parts of
** mozilla use to check for socket availability.
*/
if( 0 == amount ) return(0);
#endif
while ((rv = recv(osfd, buf, amount, flags)) == -1) {
err = _MD_ERRNO();
@ -213,9 +238,8 @@ _MD_recv (PRFileDesc *fd, void *buf, PRInt32 amount, PRInt32 flags,
} else if ((err == EINTR) && (!_PR_PENDING_INTERRUPT(me))){
continue;
} else {
} else
break;
}
}
if (rv < 0) {
@ -271,11 +295,13 @@ _MD_send (PRFileDesc *fd, const void *buf, PRInt32 amount, PRInt32 flags,
PRInt32 rv, err;
PRThread *me = _PR_MD_CURRENT_THREAD();
#ifndef BONE_VERSION
if (fd->secret->md.sock_state & BE_SOCK_SHUTDOWN_WRITE)
{
_PR_MD_MAP_SEND_ERROR(EPIPE);
return -1;
}
#endif
while ((rv = send(osfd, buf, amount, flags)) == -1) {
err = _MD_ERRNO();
@ -285,6 +311,7 @@ _MD_send (PRFileDesc *fd, const void *buf, PRInt32 amount, PRInt32 flags,
break;
}
#ifndef BONE_VERSION
if( _PR_PENDING_INTERRUPT(me)) {
me->flags &= ~_PR_INTERRUPT;
@ -298,6 +325,10 @@ _MD_send (PRFileDesc *fd, const void *buf, PRInt32 amount, PRInt32 flags,
*/
snooze( 10000L );
continue;
#else /* BONE_VERSION */
if ((rv = socket_io_wait(osfd, WRITE_FD, timeout))< 0)
goto done;
#endif
} else if ((err == EINTR) && (!_PR_PENDING_INTERRUPT(me))) {
continue;
@ -311,6 +342,9 @@ _MD_send (PRFileDesc *fd, const void *buf, PRInt32 amount, PRInt32 flags,
_PR_MD_MAP_SEND_ERROR(err);
}
#ifdef BONE_VERSION
done:
#endif
return(rv);
}
@ -331,7 +365,10 @@ _MD_sendto (PRFileDesc *fd, const void *buf, PRInt32 amount, PRIntn flags,
break;
}
printf( "This should be a blocking sendto call!!!\n" );
#ifdef BONE_VERSION
if ((rv = socket_io_wait(osfd, WRITE_FD, timeout))< 0)
goto done;
#endif
} else if ((err == EINTR) && (!_PR_PENDING_INTERRUPT(me))) {
continue;
@ -344,9 +381,61 @@ _MD_sendto (PRFileDesc *fd, const void *buf, PRInt32 amount, PRIntn flags,
_PR_MD_MAP_SENDTO_ERROR(err);
}
#ifdef BONE_VERSION
done:
#endif
return(rv);
}
#ifdef BONE_VERSION
PRInt32 _MD_writev(
PRFileDesc *fd, const PRIOVec *iov,
PRInt32 iov_size, PRIntervalTime timeout)
{
PRInt32 rv, err;
PRThread *me = _PR_MD_CURRENT_THREAD();
PRInt32 index, amount = 0;
PRInt32 osfd = fd->secret->md.osfd;
/*
* Calculate the total number of bytes to be sent; needed for
* optimization later.
* We could avoid this if this number was passed in; but it is
* probably not a big deal because iov_size is usually small (less than
* 3)
*/
if (!fd->secret->nonblocking) {
for (index=0; index<iov_size; index++) {
amount += iov[index].iov_len;
}
}
while ((rv = writev(osfd, (const struct iovec*)iov, iov_size)) == -1) {
err = _MD_ERRNO();
if ((err == EAGAIN) || (err == EWOULDBLOCK)) {
if (fd->secret->nonblocking) {
break;
}
if ((rv = socket_io_wait(osfd, WRITE_FD, timeout))<0)
goto done;
} else if ((err == EINTR) && (!_PR_PENDING_INTERRUPT(me))){
continue;
} else {
break;
}
}
if (rv < 0) {
_PR_MD_MAP_WRITEV_ERROR(err);
}
done:
return(rv);
}
#endif /* BONE_VERSION */
PRInt32
_MD_accept (PRFileDesc *fd, PRNetAddr *addr, PRUint32 *addrlen,
PRIntervalTime timeout)
@ -363,11 +452,13 @@ _MD_accept (PRFileDesc *fd, PRNetAddr *addr, PRUint32 *addrlen,
if (fd->secret->nonblocking) {
break;
}
#ifndef BONE_VERSION
/* If it's SUPPOSED to be a blocking thread, wait
* a while to see if the triggering condition gets
* satisfied.
*/
/* Assume that we're always using a native thread */
#endif
if ((rv = socket_io_wait(osfd, READ_FD, timeout)) < 0)
goto done;
} else if ((err == EINTR) && (!_PR_PENDING_INTERRUPT(me))) {
@ -377,12 +468,15 @@ _MD_accept (PRFileDesc *fd, PRNetAddr *addr, PRUint32 *addrlen,
}
}
#ifndef BONE_VERSION
if (addr) addr->raw.family = AF_INET;
#endif
if (rv < 0) {
_PR_MD_MAP_ACCEPT_ERROR(err);
}
done:
#ifndef BONE_VERSION
#ifdef _PR_HAVE_SOCKADDR_LEN
if (rv != -1) {
/* Mask off the first byte of struct sockaddr (the length field) */
@ -394,6 +488,7 @@ done:
}
}
#endif /* _PR_HAVE_SOCKADDR_LEN */
#endif /* !BONE_VERSION */
return(rv);
}
@ -405,15 +500,18 @@ _MD_connect (PRFileDesc *fd, const PRNetAddr *addr, PRUint32 addrlen,
PRInt32 rv, err;
PRThread *me = _PR_MD_CURRENT_THREAD();
#ifndef BONE_VERSION
fd->secret->md.connectValueValid = PR_FALSE;
#endif
retry:
if ((rv = connect(osfd, (struct sockaddr *)addr, addrlen)) == -1) {
err = _MD_ERRNO();
#ifndef BONE_VERSION
fd->secret->md.connectReturnValue = rv;
fd->secret->md.connectReturnError = err;
fd->secret->md.connectValueValid = PR_TRUE;
#endif
if( err == EINTR ) {
if( _PR_PENDING_INTERRUPT(me)) {
@ -422,10 +520,13 @@ retry:
PR_SetError( PR_PENDING_INTERRUPT_ERROR, 0);
return -1;
}
#ifndef BONE_VERSION
snooze( 100000L );
#endif
goto retry;
}
#ifndef BONE_VERSION
if(!fd->secret->nonblocking && ((err == EINPROGRESS) || (err==EAGAIN) || (err==EALREADY))) {
/*
@ -455,6 +556,28 @@ retry:
_PR_MD_MAP_CONNECT_ERROR(err);
return rv;
}
#else /* BONE_VERSION */
if(!fd->secret->nonblocking && (err == EINPROGRESS)) {
rv = socket_io_wait(osfd, WRITE_FD, timeout);
if (rv == -1) {
return -1;
}
PR_ASSERT(rv == 1);
if (_PR_PENDING_INTERRUPT(me)) {
me->flags &= ~_PR_INTERRUPT;
PR_SetError( PR_PENDING_INTERRUPT_ERROR, 0);
return -1;
}
err = _MD_beos_get_nonblocking_connect_error(osfd);
if (err != 0) {
_PR_MD_MAP_CONNECT_ERROR(err);
return -1;
}
return 0;
}
#endif
_PR_MD_MAP_CONNECT_ERROR(err);
}
@ -482,11 +605,13 @@ _MD_listen (PRFileDesc *fd, PRIntn backlog)
{
PRInt32 rv, err;
#ifndef BONE_VERSION
/* Bug workaround! Setting listen to 0 on Be accepts no connections.
** On most UN*Xes this sets the default.
*/
if( backlog == 0 ) backlog = 5;
#endif
rv = listen(fd->secret->md.osfd, backlog);
if (rv < 0) {
@ -502,6 +627,7 @@ _MD_shutdown (PRFileDesc *fd, PRIntn how)
{
PRInt32 rv, err;
#ifndef BONE_VERSION
if (how == PR_SHUTDOWN_SEND)
fd->secret->md.sock_state = BE_SOCK_SHUTDOWN_WRITE;
else if (how == PR_SHUTDOWN_RCV)
@ -511,6 +637,14 @@ _MD_shutdown (PRFileDesc *fd, PRIntn how)
}
return 0;
#else /* BONE_VERSION */
rv = shutdown(fd->secret->md.osfd, how);
if (rv < 0) {
err = _MD_ERRNO();
_PR_MD_MAP_SHUTDOWN_ERROR(err);
}
return(rv);
#endif
}
PRInt32
@ -522,7 +656,11 @@ _MD_socketpair (int af, int type, int flags, PRInt32 *osfd)
PRInt32
_MD_close_socket (PRInt32 osfd)
{
#ifdef BONE_VERSION
close( osfd );
#else
closesocket( osfd );
#endif
}
PRStatus
@ -560,9 +698,9 @@ PRStatus
_MD_getsockopt (PRFileDesc *fd, PRInt32 level,
PRInt32 optname, char* optval, PRInt32* optlen)
{
#ifndef BONE_VERSON
return PR_NOT_IMPLEMENTED_ERROR;
#if 0
#else
PRInt32 rv, err;
rv = getsockopt(fd->secret->md.osfd, level, optname,
@ -597,6 +735,7 @@ _MD_accept_read (PRFileDesc *sd, PRInt32 *newSock, PRNetAddr **raddr,
return PR_NOT_IMPLEMENTED_ERROR;
}
#ifndef BONE_VERSION
PRInt32
_MD_socket (int af, int type, int flags)
{
@ -612,11 +751,37 @@ _MD_socket (int af, int type, int flags)
return( osfd );
}
#else
PRInt32
_MD_socket(PRInt32 domain, PRInt32 type, PRInt32 proto)
{
PRInt32 osfd, err;
osfd = socket(domain, type, proto);
if (osfd == -1) {
err = _MD_ERRNO();
_PR_MD_MAP_SOCKET_ERROR(err);
}
return(osfd);
}
#endif
PRInt32
_MD_socketavailable (PRFileDesc *fd)
{
#ifdef BONE_VERSION
PRInt32 result;
if (ioctl(fd->secret->md.osfd, FIONREAD, &result) < 0) {
_PR_MD_MAP_SOCKETAVAILABLE_ERROR(_MD_ERRNO());
return -1;
}
return result;
#else
return PR_NOT_IMPLEMENTED_ERROR;
#endif
}
PRInt32
@ -640,6 +805,7 @@ PRInt32 rv, err;
return PR_SUCCESS;
}
#ifndef BONE_VERSION
PRInt32
_MD_beos_get_nonblocking_connect_error(PRFileDesc *fd)
{
@ -661,3 +827,16 @@ _MD_beos_get_nonblocking_connect_error(PRFileDesc *fd)
}
return 0; /* no error */
}
#else
PRInt32
_MD_beos_get_nonblocking_connect_error(int osfd)
{
int err;
_PRSockLen_t optlen = sizeof(err);
if (getsockopt(osfd, SOL_SOCKET, SO_ERROR, (char *) &err, &optlen) == -1) {
return errno;
} else {
return err;
}
}
#endif /* BONE_VERSION */

View File

@ -83,6 +83,12 @@ PRLock *_pr_dnsLock = NULL;
* Some return a pointer to struct protoent, others return
* an int.
*/
#if defined(XP_BEOS) && defined(BONE_VERSION)
#include <arpa/inet.h> /* pick up define for inet_addr */
#include <sys/socket.h>
#define _PR_HAVE_GETPROTO_R
#define _PR_HAVE_GETPROTO_R_POINTER
#endif
#if defined(SOLARIS) || (defined(BSDI) && defined(_REENTRANT)) \
|| (defined(LINUX) && defined(_REENTRANT) \

View File

@ -40,6 +40,7 @@
#include <stdlib.h>
#include <string.h>
#ifndef XP_BEOS
/*
* Test PR_GetThreadAffinityMask
@ -109,3 +110,12 @@ int main(int argc, char **argv)
return 0;
}
#else /* !XP_BEOS */
int main()
{
printf( "This test is not supported on the BeOS\n" );
return 0;
}
#endif /* !XP_BEOS */