summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorwtc%google.com <devnull@localhost>2008-08-23 17:04:34 +0000
committerwtc%google.com <devnull@localhost>2008-08-23 17:04:34 +0000
commit7fbfd273b0d77e76e7d8296ce4b4dff1736201a7 (patch)
tree25210d97f9588b1564f319d0d530ac9e8584f606
parent221518e6e353b98dad64d02ee2402123c882347d (diff)
downloadnspr-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.h1
-rw-r--r--pr/include/md/_os2.h1
-rw-r--r--pr/include/md/_unixos.h4
-rw-r--r--pr/src/io/prmapopt.c3
-rw-r--r--pr/src/md/unix/unix_errors.c3
-rw-r--r--pr/src/pthreads/ptio.c117
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
}