diff Modules/socketmodule.c @ 39043:c67b23397f30 legacy-trunk

Patch #1516912: improve Modules support for OpenVMS.
author Neal Norwitz <nnorwitz@gmail.com>
date Mon, 10 Jul 2006 01:18:57 +0000
parents 42808526511c
children 52a8738f5ab4
line wrap: on
line diff
--- a/Modules/socketmodule.c	Mon Jul 10 00:23:17 2006 +0000
+++ b/Modules/socketmodule.c	Mon Jul 10 01:18:57 2006 +0000
@@ -161,7 +161,8 @@
    (this includes the getaddrinfo emulation) protect access with a lock. */
 #if defined(WITH_THREAD) && (defined(__APPLE__) || \
     (defined(__FreeBSD__) && __FreeBSD_version+0 < 503000) || \
-    defined(__OpenBSD__) || defined(__NetBSD__) || !defined(HAVE_GETADDRINFO))
+    defined(__OpenBSD__) || defined(__NetBSD__) || \
+    defined(__VMS) || !defined(HAVE_GETADDRINFO))
 #define USE_GETADDRINFO_LOCK
 #endif
 
@@ -186,15 +187,8 @@
 #endif
 
 #if defined(__VMS)
-#if ! defined(_SOCKADDR_LEN)
-#   ifdef getaddrinfo
-#      undef getaddrinfo
-#   endif
-#  include "TCPIP_IOCTL_ROUTINE"
-#else
 #  include <ioctl.h>
 #endif
-#endif
 
 #if defined(PYOS_OS2)
 # define  INCL_DOS
@@ -363,11 +357,6 @@
 #define SOCKETCLOSE close
 #endif
 
-#ifdef __VMS
-/* TCP/IP Services for VMS uses a maximum send/revc buffer length of 65535 */
-#define SEGMENT_SIZE 65535
-#endif
-
 #if defined(HAVE_BLUETOOTH_H) || defined(HAVE_BLUETOOTH_BLUETOOTH_H)
 #define USE_BLUETOOTH 1
 #if defined(__FreeBSD__)
@@ -386,6 +375,11 @@
 #endif
 #endif
 
+#ifdef __VMS
+/* TCP/IP Services for VMS uses a maximum send/recv buffer length */
+#define SEGMENT_SIZE (32 * 1024 -1)
+#endif
+
 /*
  * Constants for getnameinfo()
  */
@@ -620,6 +614,30 @@
 	return NULL;
 }
 
+#ifdef __VMS
+/* Function to send in segments */
+static int
+sendsegmented(int sock_fd, char *buf, int len, int flags)
+{
+	int n = 0;
+	int remaining = len;
+
+	while (remaining > 0) {
+		unsigned int segment;
+
+		segment = (remaining >= SEGMENT_SIZE ? SEGMENT_SIZE : remaining);
+		n = send(sock_fd, buf, segment, flags);
+		if (n < 0) {
+			return n;
+		}
+		remaining -= segment;
+		buf += segment;
+	} /* end while */
+
+	return len;
+}
+#endif
+
 /* Function to perform the setting of socket blocking mode
    internally. block = (1 | 0). */
 static int
@@ -644,8 +662,8 @@
 	ioctl(s->sock_fd, FIONBIO, (caddr_t)&block, sizeof(block));
 #elif defined(__VMS)
 	block = !block;
-	ioctl(s->sock_fd, FIONBIO, (char *)&block);
-#else  /* !PYOS_OS2 && !_VMS */
+	ioctl(s->sock_fd, FIONBIO, (unsigned int *)&block);
+#else  /* !PYOS_OS2 && !__VMS */
 	delay_flag = fcntl(s->sock_fd, F_GETFL, 0);
 	if (block)
 		delay_flag &= (~O_NONBLOCK);
@@ -1725,6 +1743,8 @@
 		return PyInt_FromLong(flag);
 	}
 #ifdef __VMS
+	/* socklen_t is unsigned so no negative test is needed,
+	   test buflen == 0 is previously done */
 	if (buflen > 1024) {
 #else
 	if (buflen <= 0 || buflen > 1024) {
@@ -2498,9 +2518,6 @@
 {
 	char *buf;
 	int len, n = 0, flags = 0, timeout;
-#ifdef __VMS
-	int send_length;
-#endif
 
 	if (!PyArg_ParseTuple(args, "s#|i:send", &buf, &len, &flags))
 		return NULL;
@@ -2508,11 +2525,14 @@
 	if (!IS_SELECTABLE(s))
 		return select_error();
 
-#ifndef __VMS
 	Py_BEGIN_ALLOW_THREADS
 	timeout = internal_select(s, 1);
 	if (!timeout)
+#ifdef __VMS
+		n = sendsegmented(s->sock_fd, buf, len, flags);
+#else
 		n = send(s->sock_fd, buf, len, flags);
+#endif
 	Py_END_ALLOW_THREADS
 
 	if (timeout) {
@@ -2521,36 +2541,6 @@
 	}
 	if (n < 0)
 		return s->errorhandler();
-#else
-	/* Divide packet into smaller segments for	*/
-	/*  TCP/IP Services for OpenVMS			*/
-	send_length = len;
-	while (send_length != 0) {
-		unsigned int segment;
-
-		segment = send_length / SEGMENT_SIZE;
-		if (segment != 0) {
-			segment = SEGMENT_SIZE;
-		}
-		else {
-			segment = send_length;
-		}
-		Py_BEGIN_ALLOW_THREADS
-		timeout = internal_select(s, 1);
-		if (!timeout)
-			n = send(s->sock_fd, buf, segment, flags);
-		Py_END_ALLOW_THREADS
-		if (timeout) {
-			PyErr_SetString(socket_timeout, "timed out");
-			return NULL;
-		}
-		if (n < 0) {
-			return s->errorhandler();
-		}
-		send_length -= segment;
-		buf += segment;
-	} /* end while */
-#endif /* !__VMS */
 	return PyInt_FromLong((long)n);
 }
 
@@ -2581,7 +2571,11 @@
 		timeout = internal_select(s, 1);
 		if (timeout)
 			break;
+#ifdef __VMS
+		n = sendsegmented(s->sock_fd, buf, len, flags);
+#else
 		n = send(s->sock_fd, buf, len, flags);
+#endif
 		if (n < 0)
 			break;
 		buf += n;