mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-26 14:22:01 +00:00
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:
parent
28d27d47f8
commit
7fd9ab2b4e
84
nsprpub/configure
vendored
84
nsprpub/configure
vendored
@ -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
|
||||
|
||||
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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.
|
||||
|
@ -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 */
|
||||
|
@ -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) \
|
||||
|
@ -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 */
|
||||
|
Loading…
Reference in New Issue
Block a user