diff options
Diffstat (limited to 'Modules/socketmodule.c')
-rw-r--r-- | Modules/socketmodule.c | 92 |
1 files changed, 43 insertions, 49 deletions
diff --git a/Modules/socketmodule.c b/Modules/socketmodule.c index 2d3fc564c5..11b184ed0a 100644 --- a/Modules/socketmodule.c +++ b/Modules/socketmodule.c @@ -161,7 +161,8 @@ shutdown(how) -- shut down traffic in one or both directions\n\ (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 @@ shutdown(how) -- shut down traffic in one or both directions\n\ #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 @@ const char *inet_ntop(int af, const void *src, char *dst, socklen_t size); #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 @@ const char *inet_ntop(int af, const void *src, char *dst, socklen_t size); #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 @@ set_gaierror(int error) 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 @@ internal_setblocking(PySocketSockObject *s, int block) 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 @@ sock_getsockopt(PySocketSockObject *s, PyObject *args) 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 @@ sock_send(PySocketSockObject *s, PyObject *args) { 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 @@ sock_send(PySocketSockObject *s, PyObject *args) 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 @@ sock_send(PySocketSockObject *s, PyObject *args) } 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 @@ sock_sendall(PySocketSockObject *s, PyObject *args) 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; |