Merged with HEAD from 8/18 or so. unlabeled-3.24.12
authorcls%seawood.org
Fri, 20 Aug 1999 16:21:45 +0000
branchunlabeled-3.24.12
changeset 779 6b4b91bed392
parent 625 08cb1aef81b0
push idunknown
push userunknown
push dateunknown
Merged with HEAD from 8/18 or so.
pr/src/md/unix/unix.c
--- a/pr/src/md/unix/unix.c
+++ b/pr/src/md/unix/unix.c
@@ -33,31 +33,35 @@
 #endif
 
 /* To get FIONREAD */
 #if defined(NCR) || defined(UNIXWARE) || defined(NEC) || defined(SNI) \
         || defined(SONY)
 #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.
  */
 #if defined(HAVE_SOCKLEN_T)
 #define _PRSockLen_t socklen_t
 #elif defined(IRIX) || defined(HPUX) || defined(OSF1) || defined(SOLARIS) \
     || defined(AIX4_1) || defined(LINUX) || defined(SONY) \
     || defined(BSDI) || defined(SCO) || defined(NEC) || defined(SNI) \
     || defined(SUNOS4) || defined(NCR) || defined(RHAPSODY) \
     || defined(NEXTSTEP) || defined(QNX)
 #define _PRSockLen_t int
 #elif (defined(AIX) && !defined(AIX4_1)) || defined(FREEBSD) \
     || defined(NETBSD) || defined(OPENBSD) || defined(UNIXWARE) \
-    || defined(DGUX) || defined(VMS)
+    || defined(DGUX) || defined(VMS) || defined(NTO)
 #define _PRSockLen_t size_t
 #else
 #error "Cannot determine architecture"
 #endif
 
 /*
 ** Global lock variable used to bracket calls into rusty libraries that
 ** aren't thread safe (like libc, libX, etc).
@@ -3353,17 +3357,81 @@ void _PR_Unblock_IO_Wait(PRThread *thr)
  * succeeded or failed, and if it failed, what the error code is.
  *
  * The function returns the error code.  An error code of 0 means
  * that the nonblocking connect succeeded.
  */
 
 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.
      */
 
     int rv;
     int flags = 0;
     rv = getmsg(osfd, NULL, NULL, &flags);
     PR_ASSERT(-1 == rv || 0 == rv);
@@ -3415,17 +3483,61 @@ void PR_XNotify(void)
     PR_Notify(_pr_Xfe_mon);
 }
 
 void PR_XNotifyAll(void)
 {
     PR_NotifyAll(_pr_Xfe_mon);
 }
 
-#ifdef HAVE_BSD_FLOCK
+#if defined(HAVE_FCNTL_FILE_LOCKING)
+
+PR_IMPLEMENT(PRStatus)
+_MD_LockFile(PRInt32 f)
+{
+    PRInt32 rv;
+    struct flock arg;
+
+    arg.l_type = F_WRLCK;
+    rv = fcntl(f, F_SETLKW, &arg);
+    if (rv == 0)
+        return PR_SUCCESS;
+    _PR_MD_MAP_FLOCK_ERROR(_MD_ERRNO());
+    return PR_FAILURE;
+}
+
+PR_IMPLEMENT(PRStatus)
+_MD_TLockFile(PRInt32 f)
+{
+    PRInt32 rv;
+    struct flock arg;
+
+    arg.l_type = F_WRLCK;
+    rv = fcntl(f, F_SETLK, &arg);
+    if (rv == 0)
+        return PR_SUCCESS;
+    _PR_MD_MAP_FLOCK_ERROR(_MD_ERRNO());
+    return PR_FAILURE;
+}
+
+PR_IMPLEMENT(PRStatus)
+_MD_UnlockFile(PRInt32 f)
+{
+    PRInt32 rv;
+    struct flock arg;
+
+    arg.l_type = F_UNLCK;
+    rv = fcntl(f, F_SETLK, &arg);
+    if (rv == 0)
+        return PR_SUCCESS;
+    _PR_MD_MAP_FLOCK_ERROR(_MD_ERRNO());
+    return PR_FAILURE;
+}
+
+#elif defined(HAVE_BSD_FLOCK)
 
 #include <sys/file.h>
 
 PR_IMPLEMENT(PRStatus)
 _MD_LockFile(PRInt32 f)
 {
     PRInt32 rv;
     rv = flock(f, LOCK_EX);