diff options
author | wtc%netscape.com <devnull@localhost> | 1999-07-19 22:23:43 +0000 |
---|---|---|
committer | wtc%netscape.com <devnull@localhost> | 1999-07-19 22:23:43 +0000 |
commit | 966f70e81cafafba6216c248b1b670ba7f471ce3 (patch) | |
tree | 93d01ef366ee68e111edeeef0b406215f7ab77ae | |
parent | 266047facf61f0be79d9dfdb85c67f7496392bd0 (diff) | |
download | nspr-hg-966f70e81cafafba6216c248b1b670ba7f471ce3.tar.gz |
A hack to get _MD_unix_get_nonblocking_connect_error to work for Neutrino.
This patch is contributed by Jerry L. Kirk <Jerry.Kirk@Nexwarecorp.com>.
-rw-r--r-- | pr/src/md/unix/unix.c | 70 |
1 files changed, 69 insertions, 1 deletions
diff --git a/pr/src/md/unix/unix.c b/pr/src/md/unix/unix.c index a4d17425..4eb75d1b 100644 --- a/pr/src/md/unix/unix.c +++ b/pr/src/md/unix/unix.c @@ -38,6 +38,10 @@ #include <sys/filio.h> #endif +#if defined(NTO) +#include <sys/statvfs.h> +#endif + /* * Make sure _PRSockLen_t is 32-bit, because we will cast a PRUint32* or * PRInt32* pointer to a _PRSockLen_t* pointer. @@ -3358,7 +3362,71 @@ void _PR_Unblock_IO_Wait(PRThread *thr) int _MD_unix_get_nonblocking_connect_error(int osfd) { -#if defined(NCR) || defined(UNIXWARE) || defined(SNI) || defined(NEC) +#if defined(NTO) + /* Neutrino does not support the SO_ERROR socket option */ + PRInt32 rv; + PRNetAddr addr; + _PRSockLen_t addrlen = sizeof(addr); + + /* Test to see if we are using the Tiny TCP/IP Stack or the Full one. */ + struct statvfs superblock; + rv = fstatvfs(osfd, &superblock); + if (rv == 0) { + if (strcmp(superblock.f_basetype, "ttcpip") == 0) { + /* Using the Tiny Stack! */ + rv = getpeername(osfd, (struct sockaddr *) &addr, + (_PRSockLen_t *) &addrlen); + if (rv == -1) { + int errno_copy = errno; /* make a copy so I don't + * accidentally reset */ + + if (errno_copy == ENOTCONN) { + struct stat StatInfo; + rv = fstat(osfd, &StatInfo); + if (rv == 0) { + time_t current_time = time(NULL); + + /* + * this is a real hack, can't explain why it + * works it just does + */ + if (abs(current_time - StatInfo.st_atime) < 5) { + return ECONNREFUSED; + } else { + return ETIMEDOUT; + } + } else { + return ECONNREFUSED; + } + } else { + return errno_copy; + } + } else { + /* No Error */ + return 0; + } + } else { + /* Have the FULL Stack which supports SO_ERROR */ + /* Hasn't been written yet, never been tested! */ + /* Jerry.Kirk@Nexwarecorp.com */ + + int err; + _PRSockLen_t optlen = sizeof(err); + + printf("_MD_unix_get_nonblocking_connect_error: " + "Assuming Large TCP/IP Stack -REVISIT- Never Tested!\n"); + + if (getsockopt(osfd, SOL_SOCKET, SO_ERROR, + (char *) &err, &optlen) == -1) { + return errno; + } else { + return err; + } + } + } else { + return ECONNREFUSED; + } +#elif defined(NCR) || defined(UNIXWARE) || defined(SNI) || defined(NEC) /* * getsockopt() fails with EPIPE, so use getmsg() instead. */ |