diff options
author | wtc%google.com <devnull@localhost> | 2008-08-23 17:04:34 +0000 |
---|---|---|
committer | wtc%google.com <devnull@localhost> | 2008-08-23 17:04:34 +0000 |
commit | 7fbfd273b0d77e76e7d8296ce4b4dff1736201a7 (patch) | |
tree | 25210d97f9588b1564f319d0d530ac9e8584f606 | |
parent | 221518e6e353b98dad64d02ee2402123c882347d (diff) | |
download | nspr-hg-7fbfd273b0d77e76e7d8296ce4b4dff1736201a7.tar.gz |
Bug 432430: Added the HAVE_NETINET_TCP_H configuration macro for platforms
that have the <netinet/tcp.h> header. Ported ptio.c to Symbian OS. The
patch is contributed by Harry Li <harry.li@pagefreedom.org>. r=wtc.
Modified files: _beos.h _os2.h _unixos.h prmapopt.c unix_errors.c ptio.c
-rw-r--r-- | pr/include/md/_beos.h | 1 | ||||
-rw-r--r-- | pr/include/md/_os2.h | 1 | ||||
-rw-r--r-- | pr/include/md/_unixos.h | 4 | ||||
-rw-r--r-- | pr/src/io/prmapopt.c | 3 | ||||
-rw-r--r-- | pr/src/md/unix/unix_errors.c | 3 | ||||
-rw-r--r-- | pr/src/pthreads/ptio.c | 117 |
6 files changed, 119 insertions, 10 deletions
diff --git a/pr/include/md/_beos.h b/pr/include/md/_beos.h index 38dd5fb8..3acfa4d1 100644 --- a/pr/include/md/_beos.h +++ b/pr/include/md/_beos.h @@ -56,6 +56,7 @@ #ifdef BONE_VERSION #define _PR_HAVE_SOCKADDR_LEN +#define HAVE_NETINET_TCP_H #endif #define PR_LINKER_ARCH "beos" diff --git a/pr/include/md/_os2.h b/pr/include/md/_os2.h index 016254b2..c47fc041 100644 --- a/pr/include/md/_os2.h +++ b/pr/include/md/_os2.h @@ -66,6 +66,7 @@ #undef HAVE_THREAD_AFFINITY #define _PR_HAVE_THREADSAFE_GETHOST #define _PR_HAVE_ATOMIC_OPS +#define HAVE_NETINET_TCP_H #define HANDLE unsigned long #define HINSTANCE HMODULE diff --git a/pr/include/md/_unixos.h b/pr/include/md/_unixos.h index 96c9fc9e..0b7d4f72 100644 --- a/pr/include/md/_unixos.h +++ b/pr/include/md/_unixos.h @@ -82,6 +82,10 @@ #include <sys/select.h> #endif +#ifndef SYMBIAN +#define HAVE_NETINET_TCP_H +#endif + #define _PR_HAVE_O_APPEND #define PR_DIRECTORY_SEPARATOR '/' diff --git a/pr/src/io/prmapopt.c b/pr/src/io/prmapopt.c index 72dd42a5..8379b23a 100644 --- a/pr/src/io/prmapopt.c +++ b/pr/src/io/prmapopt.c @@ -70,8 +70,7 @@ #include <netinet/in_systm.h> /* n_short, n_long, n_time */ #endif -#if (defined(XP_UNIX) && !defined(SYMBIAN)) \ - || defined(OS2) || (defined(XP_BEOS) && defined(BONE_VERSION)) +#ifdef HAVE_NETINET_TCP_H #include <netinet/tcp.h> /* TCP_NODELAY, TCP_MAXSEG */ #endif diff --git a/pr/src/md/unix/unix_errors.c b/pr/src/md/unix/unix_errors.c index 90ebe7de..a1b88dc0 100644 --- a/pr/src/md/unix/unix_errors.c +++ b/pr/src/md/unix/unix_errors.c @@ -194,6 +194,9 @@ void _MD_unix_map_default_error(int err) prError = PR_INSUFFICIENT_RESOURCES_ERROR; break; #endif + case ENOSYS: + prError = PR_NOT_IMPLEMENTED_ERROR; + break; case ENOTCONN: prError = PR_NOT_CONNECTED_ERROR; break; diff --git a/pr/src/pthreads/ptio.c b/pr/src/pthreads/ptio.c index 715f0314..bd38d670 100644 --- a/pr/src/pthreads/ptio.c +++ b/pr/src/pthreads/ptio.c @@ -187,7 +187,10 @@ static ssize_t (*pt_aix_sendfile_fptr)() = NULL; #include "primpl.h" +#ifdef HAVE_NETINET_TCP_H #include <netinet/tcp.h> /* TCP_NODELAY, TCP_MAXSEG */ +#endif + #ifdef LINUX /* TCP_CORK is not defined in <netinet/tcp.h> on Red Hat Linux 6.0 */ #ifndef TCP_CORK @@ -209,7 +212,7 @@ static PRBool _pr_ipv6_v6only_on_by_default; || defined(LINUX) || defined(__GNU__) || defined(__GLIBC__) \ || defined(FREEBSD) || defined(NETBSD) || defined(OPENBSD) \ || defined(BSDI) || defined(VMS) || defined(NTO) || defined(DARWIN) \ - || defined(UNIXWARE) || defined(RISCOS) + || defined(UNIXWARE) || defined(RISCOS) || defined(SYMBIAN) #define _PRSelectFdSetArg_t fd_set * #else #error "Cannot determine architecture" @@ -1656,9 +1659,18 @@ static PRFileDesc* pt_Accept( PRFileDesc *newfd = NULL; PRIntn syserrno, osfd = -1; pt_SockLen addr_len = sizeof(PRNetAddr); +#ifdef SYMBIAN + PRNetAddr dummy_addr; +#endif if (pt_TestAbort()) return newfd; +#ifdef SYMBIAN + /* On Symbian OS, accept crashes if addr is NULL. */ + if (!addr) + addr = &dummy_addr; +#endif + #ifdef _PR_STRICT_ADDR_LEN if (addr) { @@ -1826,7 +1838,15 @@ static PRInt32 pt_Recv( if (0 == flags) osflags = 0; else if (PR_MSG_PEEK == flags) + { +#ifdef SYMBIAN + /* MSG_PEEK doesn't work as expected. */ + PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0); + return bytes; +#else osflags = MSG_PEEK; +#endif + } else { PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0); @@ -3251,7 +3271,8 @@ static PRIOMethods _pr_socketpollfd_methods = { || defined(LINUX) || defined(__GNU__) || defined(__GLIBC__) \ || defined(AIX) || defined(FREEBSD) || defined(NETBSD) \ || defined(OPENBSD) || defined(BSDI) || defined(VMS) || defined(NTO) \ - || defined(DARWIN) || defined(UNIXWARE) || defined(RISCOS) + || defined(DARWIN) || defined(UNIXWARE) || defined(RISCOS) \ + || defined(SYMBIAN) #define _PR_FCNTL_FLAGS O_NONBLOCK #else #error "Can't determine architecture" @@ -4354,6 +4375,84 @@ PR_IMPLEMENT(PRFileDesc*) PR_OpenTCPSocket(PRIntn af) PR_IMPLEMENT(PRStatus) PR_NewTCPSocketPair(PRFileDesc *fds[2]) { +#ifdef SYMBIAN + /* + * For the platforms that don't have socketpair. + * + * Copied from prsocket.c, with the parameter f[] renamed fds[] and the + * _PR_CONNECT_DOES_NOT_BIND code removed. + */ + PRFileDesc *listenSock; + PRNetAddr selfAddr, peerAddr; + PRUint16 port; + + fds[0] = fds[1] = NULL; + listenSock = PR_NewTCPSocket(); + if (listenSock == NULL) { + goto failed; + } + PR_InitializeNetAddr(PR_IpAddrLoopback, 0, &selfAddr); /* BugZilla: 35408 */ + if (PR_Bind(listenSock, &selfAddr) == PR_FAILURE) { + goto failed; + } + if (PR_GetSockName(listenSock, &selfAddr) == PR_FAILURE) { + goto failed; + } + port = ntohs(selfAddr.inet.port); + if (PR_Listen(listenSock, 5) == PR_FAILURE) { + goto failed; + } + fds[0] = PR_NewTCPSocket(); + if (fds[0] == NULL) { + goto failed; + } + PR_InitializeNetAddr(PR_IpAddrLoopback, port, &selfAddr); + + /* + * Only a thread is used to do the connect and accept. + * I am relying on the fact that PR_Connect returns + * successfully as soon as the connect request is put + * into the listen queue (but before PR_Accept is called). + * This is the behavior of the BSD socket code. If + * connect does not return until accept is called, we + * will need to create another thread to call connect. + */ + if (PR_Connect(fds[0], &selfAddr, PR_INTERVAL_NO_TIMEOUT) + == PR_FAILURE) { + goto failed; + } + /* + * A malicious local process may connect to the listening + * socket, so we need to verify that the accepted connection + * is made from our own socket fds[0]. + */ + if (PR_GetSockName(fds[0], &selfAddr) == PR_FAILURE) { + goto failed; + } + fds[1] = PR_Accept(listenSock, &peerAddr, PR_INTERVAL_NO_TIMEOUT); + if (fds[1] == NULL) { + goto failed; + } + if (peerAddr.inet.port != selfAddr.inet.port) { + /* the connection we accepted is not from fds[0] */ + PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, 0); + goto failed; + } + PR_Close(listenSock); + return PR_SUCCESS; + +failed: + if (listenSock) { + PR_Close(listenSock); + } + if (fds[0]) { + PR_Close(fds[0]); + } + if (fds[1]) { + PR_Close(fds[1]); + } + return PR_FAILURE; +#else PRInt32 osfd[2]; if (pt_TestAbort()) return PR_FAILURE; @@ -4376,6 +4475,7 @@ PR_IMPLEMENT(PRStatus) PR_NewTCPSocketPair(PRFileDesc *fds[2]) return PR_FAILURE; } return PR_SUCCESS; +#endif } /* PR_NewTCPSocketPair */ PR_IMPLEMENT(PRStatus) PR_CreatePipe( @@ -4431,6 +4531,7 @@ PR_IMPLEMENT(PRStatus) PR_SetFDInheritable( if (fcntl(fd->secret->md.osfd, F_SETFD, inheritable ? 0 : FD_CLOEXEC) == -1) { + _PR_MD_MAP_DEFAULT_ERROR(errno); return PR_FAILURE; } fd->secret->inheritable = (_PRTriStateBool) inheritable; @@ -4603,21 +4704,23 @@ PR_IMPLEMENT(PRStatus) PR_UnlockFile(PRFileDesc *fd) PR_IMPLEMENT(PRInt32) PR_GetSysfdTableMax(void) { -#if defined(XP_UNIX) && !defined(AIX) && !defined(VMS) +#if defined(AIX) || defined(VMS) || defined(SYMBIAN) + return sysconf(_SC_OPEN_MAX); +#else struct rlimit rlim; if ( getrlimit(RLIMIT_NOFILE, &rlim) < 0) return -1; return rlim.rlim_max; -#elif defined(AIX) || defined(VMS) - return sysconf(_SC_OPEN_MAX); #endif } PR_IMPLEMENT(PRInt32) PR_SetSysfdTableSize(PRIntn table_size) { -#if defined(XP_UNIX) && !defined(AIX) && !defined(VMS) +#if defined(AIX) || defined(VMS) || defined(SYMBIAN) + return -1; +#else struct rlimit rlim; PRInt32 tableMax = PR_GetSysfdTableMax(); @@ -4634,8 +4737,6 @@ PR_IMPLEMENT(PRInt32) PR_SetSysfdTableSize(PRIntn table_size) return -1; return rlim.rlim_cur; -#elif defined(AIX) || defined(VMS) - return -1; #endif } |