summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorseawood%netscape.com <devnull@localhost>2002-01-10 09:49:59 +0000
committerseawood%netscape.com <devnull@localhost>2002-01-10 09:49:59 +0000
commit0739db4546bdcecf9ec07556d657e8a19baee924 (patch)
tree485adcc2de6ea41cd268b6c88731940d7e904233
parent6e43d749d1d1df0b690a4e820c27a8ad0ba4394d (diff)
downloadnspr-hg-0739db4546bdcecf9ec07556d657e8a19baee924.tar.gz
Landing BeOS BONE support.
Thanks to Matthew Zahorik <maz@albany.net> & Paul Ashford <arougthopher@lizardland.net> for the patch. Bug #71697 r=wtc/cls
-rwxr-xr-xconfigure84
-rw-r--r--configure.in1
-rw-r--r--pr/include/md/_beos.h10
-rw-r--r--pr/src/io/prfile.c10
-rw-r--r--pr/src/io/prmapopt.c6
-rw-r--r--pr/src/md/beos/bfile.c344
-rw-r--r--pr/src/md/beos/bnet.c425
-rw-r--r--pr/src/misc/prnetdb.c6
-rw-r--r--pr/tests/affinity.c10
9 files changed, 591 insertions, 305 deletions
diff --git a/configure b/configure
index 70697295..c3d0706e 100755
--- a/configure
+++ b/configure
@@ -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' ' '`
rm -f conftest.defs
diff --git a/configure.in b/configure.in
index 1a922d3d..32da0f4c 100644
--- a/configure.in
+++ b/configure.in
@@ -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
diff --git a/pr/include/md/_beos.h b/pr/include/md/_beos.h
index 232fea3c..391c9720 100644
--- a/pr/include/md/_beos.h
+++ b/pr/include/md/_beos.h
@@ -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);
diff --git a/pr/src/io/prfile.c b/pr/src/io/prfile.c
index c6da38a0..adb2ea55 100644
--- a/pr/src/io/prfile.c
+++ b/pr/src/io/prfile.c
@@ -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
diff --git a/pr/src/io/prmapopt.c b/pr/src/io/prmapopt.c
index f017c36a..5828bf9e 100644
--- a/pr/src/io/prmapopt.c
+++ b/pr/src/io/prmapopt.c
@@ -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);
diff --git a/pr/src/md/beos/bfile.c b/pr/src/md/beos/bfile.c
index e80181cc..e42c63db 100644
--- a/pr/src/md/beos/bfile.c
+++ b/pr/src/md/beos/bfile.c
@@ -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;
+
+ if (_PR_PENDING_INTERRUPT(me))
+ {
+ me->flags &= ~_PR_INTERRUPT;
+ PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0);
+ return -1;
+ }
+
+ if (0 == npds) {
+ PR_Sleep(timeout);
+ return rv;
+ }
- FD_ZERO(&rd);
- FD_ZERO(&wr);
+ FD_ZERO(&rd);
+ FD_ZERO(&wt);
+ FD_ZERO(&ex);
- /*
- * first, sort out the new connects, the reads, and the writes
- */
- epd = pds + npds;
- for(pd = pds; pd < epd; pd++)
+ ready = 0;
+ for (pd = pds, epd = pd + npds; pd < epd; pd++)
{
- in_flags = pd->in_flags;
- bottom = pd->fd;
+ PRInt16 in_flags_read = 0, in_flags_write = 0;
+ PRInt16 out_flags_read = 0, out_flags_write = 0;
- if(bottom != 0 && in_flags != 0)
+ if ((NULL != pd->fd) && (0 != pd->in_flags))
{
- while(bottom->lower != 0)
+ if (pd->in_flags & PR_POLL_READ)
{
- bottom = bottom->lower;
+ in_flags_read = (pd->fd->methods->poll)(pd->fd, pd->in_flags & ~PR_POLL_WRITE, &out_flags_read);
}
- osfd = bottom->secret->md.osfd;
-
- if(in_flags & PR_POLL_WRITE || in_flags & PR_POLL_EXCEPT)
+ if (pd->in_flags & PR_POLL_WRITE)
{
- /*printf("POLL: adding to write\n");*/
- FD_SET(osfd, &wr);
- if( osfd > maxfd ) maxfd = osfd;
+ in_flags_write = (pd->fd->methods->poll)(pd->fd, pd->in_flags & ~PR_POLL_READ, &out_flags_write);
}
- if(in_flags & PR_POLL_READ || in_flags & PR_POLL_EXCEPT)
+ if ((0 != (in_flags_read & out_flags_read))
+ || (0 != (in_flags_write & out_flags_write)))
{
- /*printf("POLL: adding to read\n");*/
- FD_SET(osfd, &rd);
- if( osfd > maxfd ) maxfd = osfd;
+ /* this one's ready right now */
+ if (0 == ready)
+ {
+ /*
+ * 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++)
+ {
+ prev->out_flags = 0;
+ }
+ }
+ 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 */
+ }
}
}
-
-
- }
+ }
+
+ if (0 != ready) return ready; /* no need to block */
+
+ remaining = timeout;
+ start = PR_IntervalNow();
- if(maxfd >= 0)
+ 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)
{
- PRInt32 n;
- do {
- PRIntervalTime start = PR_IntervalNow();
- if (timeout != PR_INTERVAL_NO_TIMEOUT)
+ if (timeout == PR_INTERVAL_NO_TIMEOUT) goto retry;
+ else
+ {
+ elapsed = (PRIntervalTime) (PR_IntervalNow() - start);
+ if (elapsed > timeout) ready = 0; /* timed out */
+ else
{
- /*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;
+ remaining = timeout - elapsed;
+ goto retry;
}
+ }
+ }
-
- 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))
+ /*
+ ** 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))
{
- if (timeout != PR_INTERVAL_NO_TIMEOUT)
- {
- timeout -= PR_IntervalNow() - start;
- if(timeout <= 0)
+ 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))
{
- /* timed out */
- n = 0;
+ 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;
}
-
- } while(n < 0 && errno == EINTR);
-
- if(n > 0)
+ pd->out_flags = out_flags;
+ if (out_flags) ready++;
+ }
+ PR_ASSERT(ready > 0);
+ }
+ else if (ready < 0)
+ {
+ err = _MD_ERRNO();
+ if (err == EBADF)
{
- epd = pds + npds;
- for(pd = pds; pd < epd; pd++)
+ /* Find the bad fds */
+ ready = 0;
+ for (pd = pds, epd = pd + npds; pd < epd; pd++)
{
- int selected;
- in_flags = pd->in_flags;
- bottom = pd->fd;
- selected = 0;
-
- if(bottom != 0 && in_flags != 0)
+ pd->out_flags = 0;
+ if ((NULL != pd->fd) && (0 != pd->in_flags))
{
- while(bottom->lower != 0)
+ bottom = PR_GetIdentitiesLayer(pd->fd, PR_NSPR_IO_LAYER);
+ if (fcntl(bottom->secret->md.osfd, F_GETFL, 0) == -1)
{
- bottom = bottom->lower;
+ pd->out_flags = PR_POLL_NVAL;
+ ready++;
}
- 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;
}
-
}
- } else if (n < 0) {
- /* hit error that's not EINTR. */
- rc = -1;
+ PR_ASSERT(ready > 0);
}
+ else _PR_MD_MAP_SELECT_ERROR(err);
}
-
- /*printf("POLL: exiting _MD_pr_poll with %d\n", rc);*/
- return rc;
-}
+
+ return ready;
+} /* _MD_pr_poll */
/*
* File locking.
diff --git a/pr/src/md/beos/bnet.c b/pr/src/md/beos/bnet.c
index 86943b3b..c15a2beb 100644
--- a/pr/src/md/beos/bnet.c
+++ b/pr/src/md/beos/bnet.c
@@ -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;
-
- switch (timeout) {
- case PR_INTERVAL_NO_WAIT:
+ 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:
+ 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 */
diff --git a/pr/src/misc/prnetdb.c b/pr/src/misc/prnetdb.c
index c8d33900..ce0ba119 100644
--- a/pr/src/misc/prnetdb.c
+++ b/pr/src/misc/prnetdb.c
@@ -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) \
diff --git a/pr/tests/affinity.c b/pr/tests/affinity.c
index 513775f7..ee78434a 100644
--- a/pr/tests/affinity.c
+++ b/pr/tests/affinity.c
@@ -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 */