]> granicus.if.org Git - python/commitdiff
Patch #1516912: improve Modules support for OpenVMS.
authorNeal Norwitz <nnorwitz@gmail.com>
Mon, 10 Jul 2006 01:18:57 +0000 (01:18 +0000)
committerNeal Norwitz <nnorwitz@gmail.com>
Mon, 10 Jul 2006 01:18:57 +0000 (01:18 +0000)
Misc/NEWS
Modules/bz2module.c
Modules/cryptmodule.c
Modules/dlmodule.c
Modules/fpectlmodule.c
Modules/getpath.c
Modules/posixmodule.c
Modules/selectmodule.c
Modules/socketmodule.c

index 33ca2b6db35baeab150a9c84fcb9c5499ddb9201..a3f2b723f0f72fb4d9cd2e356660ba0f817e69b8 100644 (file)
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -108,6 +108,8 @@ Extension Modules
 - Bug #1296433: parsing XML with a non-default encoding and
   a CharacterDataHandler could crash the interpreter in pyexpat.
 
+- Patch #1516912: improve Modules support for OpenVMS.
+
 Build
 -----
 
index 8f4e1d88f7fdcb4184190caeba183950c18e9da8..5800bff86e92f591d3387847784b5988d13b06bb 100644 (file)
@@ -1311,7 +1311,11 @@ BZ2File_init(BZ2FileObject *self, PyObject *args, PyObject *kwargs)
                                break;
 
                        case 'U':
+#ifdef __VMS
+                               self->f_univ_newline = 0;
+#else
                                self->f_univ_newline = 1;
+#endif
                                break;
 
                        default:
index 050a356912224b62daca8d4eead354ab8edb2be0..6377f8430beadc58972ddffea92b0829b05ce394 100644 (file)
@@ -5,6 +5,9 @@
 
 #include <sys/types.h>
 
+#ifdef __VMS
+#include <openssl/des.h>
+#endif
 
 /* Module crypt */
 
@@ -12,7 +15,9 @@
 static PyObject *crypt_crypt(PyObject *self, PyObject *args)
 {
        char *word, *salt; 
+#ifndef __VMS
        extern char * crypt(const char *, const char *);
+#endif
 
        if (!PyArg_ParseTuple(args, "ss:crypt", &word, &salt)) {
                return NULL;
index 899ad866cfc94762008744146cb8a0107e072d2b..5622ed9e738c0d683cabe9f775c0d1ae9c88725d 100644 (file)
@@ -5,6 +5,10 @@
 
 #include <dlfcn.h>
 
+#ifdef __VMS
+#include <unistd.h>
+#endif
+
 #ifndef RTLD_LAZY
 #define RTLD_LAZY 1
 #endif
@@ -186,6 +190,24 @@ dl_open(PyObject *self, PyObject *args)
                PyErr_SetString(Dlerror, dlerror());
                return NULL;
        }
+#ifdef __VMS
+       /*   Under OpenVMS dlopen doesn't do any check, just save the name
+        * for later use, so we have to check if the file is readable,
+        * the name can be a logical or a file from SYS$SHARE.
+        */
+       if (access(name, R_OK)) {
+               char fname[strlen(name) + 20];
+               strcpy(fname, "SYS$SHARE:");
+               strcat(fname, name);
+               strcat(fname, ".EXE");
+               if (access(fname, R_OK)) {
+                       dlclose(handle);
+                       PyErr_SetString(Dlerror,
+                               "File not found or protection violation");
+                       return NULL;
+               }
+       }
+#endif
        return newdlobject(handle);
 }
 
index c6d4f77c2312566b76f06d417b8da60ebf99f36d..74354bac52d64e126a97aba05ef744d7552f04fa 100644 (file)
@@ -70,6 +70,10 @@ extern "C" {
 
 #if defined(__FreeBSD__)
 #  include <ieeefp.h>
+#elif defined(__VMS)
+#define __NEW_STARLET
+#include <starlet.h>
+#include <ieeedef.h>
 #endif
 
 #ifndef WANT_SIGFPE_HANDLER
@@ -190,6 +194,19 @@ static void fpe_reset(Sigfunc *handler)
 
 /*-- DEC ALPHA VMS --------------------------------------------------------*/
 #elif defined(__ALPHA) && defined(__VMS)
+       IEEE clrmsk;
+       IEEE setmsk;
+       clrmsk.ieee$q_flags =
+               IEEE$M_TRAP_ENABLE_UNF |  IEEE$M_TRAP_ENABLE_INE |
+                IEEE$M_MAP_UMZ;
+       setmsk.ieee$q_flags =
+               IEEE$M_TRAP_ENABLE_INV | IEEE$M_TRAP_ENABLE_DZE |
+               IEEE$M_TRAP_ENABLE_OVF;
+       sys$ieee_set_fp_control(&clrmsk, &setmsk, 0);
+       PyOS_setsig(SIGFPE, handler);
+
+/*-- HP IA64 VMS --------------------------------------------------------*/
+#elif defined(__ia64) && defined(__VMS)
     PyOS_setsig(SIGFPE, handler);
 
 /*-- Cray Unicos ----------------------------------------------------------*/
@@ -244,6 +261,14 @@ static PyObject *turnoff_sigfpe(PyObject *self,PyObject *args)
 #ifdef __FreeBSD__
     fpresetsticky(fpgetsticky());
     fpsetmask(0);
+#elif defined(__VMS)
+       IEEE clrmsk;
+        clrmsk.ieee$q_flags =
+               IEEE$M_TRAP_ENABLE_UNF |  IEEE$M_TRAP_ENABLE_INE |
+               IEEE$M_MAP_UMZ | IEEE$M_TRAP_ENABLE_INV |
+               IEEE$M_TRAP_ENABLE_DZE | IEEE$M_TRAP_ENABLE_OVF |
+               IEEE$M_INHERIT;
+       sys$ieee_set_fp_control(&clrmsk, 0, 0);
 #else
     fputs("Operation not implemented\n", stderr);
 #endif
index 8eba730ccfef82145635c32ba88a76c17630f5d9..78bfaf97658716704b258faa16f306791614c963 100644 (file)
 
 
 #ifndef VERSION
-#if defined(__VMS)
-#define VERSION "2_1"
-#else
 #define VERSION "2.1"
 #endif
-#endif
 
 #ifndef VPATH
 #define VPATH "."
 #endif
 
 #ifndef PREFIX
-#define PREFIX "/usr/local"
+#  ifdef __VMS
+#    define PREFIX ""
+#  else
+#    define PREFIX "/usr/local"
+#  endif
 #endif
 
 #ifndef EXEC_PREFIX
index d8cf40ed7c0621160400651a0a7ebd26b240459b..e1182378eebec0367fe9c99150ccbd2b7d78719b 100644 (file)
@@ -7882,6 +7882,42 @@ win32_urandom(PyObject *self, PyObject *args)
 }
 #endif
 
+#ifdef __VMS
+/* Use openssl random routine */
+#include <openssl/rand.h>
+PyDoc_STRVAR(vms_urandom__doc__,
+"urandom(n) -> str\n\n\
+Return a string of n random bytes suitable for cryptographic use.");
+
+static PyObject*
+vms_urandom(PyObject *self, PyObject *args)
+{
+       int howMany;
+       PyObject* result;
+
+       /* Read arguments */
+       if (! PyArg_ParseTuple(args, "i:urandom", &howMany))
+               return NULL;
+       if (howMany < 0)
+               return PyErr_Format(PyExc_ValueError,
+                                   "negative argument not allowed");
+
+       /* Allocate bytes */
+       result = PyString_FromStringAndSize(NULL, howMany);
+       if (result != NULL) {
+               /* Get random data */
+               if (RAND_pseudo_bytes((unsigned char*)
+                                     PyString_AS_STRING(result),
+                                     howMany) < 0) {
+                       Py_DECREF(result);
+                       return PyErr_Format(PyExc_ValueError,
+                                           "RAND_pseudo_bytes");
+               }
+       }
+       return result;
+}
+#endif
+
 static PyMethodDef posix_methods[] = {
        {"access",      posix_access, METH_VARARGS, posix_access__doc__},
 #ifdef HAVE_TTYNAME
@@ -8174,6 +8210,9 @@ static PyMethodDef posix_methods[] = {
 #endif
  #ifdef MS_WINDOWS
        {"urandom", win32_urandom, METH_VARARGS, win32_urandom__doc__},
+ #endif
+ #ifdef __VMS
+       {"urandom", vms_urandom, METH_VARARGS, vms_urandom__doc__},
  #endif
        {NULL,          NULL}            /* Sentinel */
 };
index ef67888122268453392a1dd750ea344eb67d6872..9eaae8488c962081ba62c47705dbd3fa38435148 100644 (file)
@@ -46,14 +46,14 @@ extern void bzero(void *, int);
 #endif
 
 #ifdef MS_WINDOWS
-#include <winsock.h>
+#  include <winsock.h>
 #else
-#ifdef __BEOS__
-#include <net/socket.h>
-#define SOCKET int
-#else
-#define SOCKET int
-#endif
+#  define SOCKET int
+#  ifdef __BEOS__
+#    include <net/socket.h>
+#  elif defined(__VMS)
+#    include <socket.h>
+#  endif
 #endif
 
 
@@ -668,7 +668,7 @@ arguments; each contains the subset of the corresponding file descriptors\n\
 that are ready.\n\
 \n\
 *** IMPORTANT NOTICE ***\n\
-On Windows, only sockets are supported; on Unix, all file descriptors.");
+On Windows and OpenVMS, only sockets are supported; on Unix, all file descriptors.");
 
 static PyMethodDef select_methods[] = {
     {"select", select_select, METH_VARARGS, select_doc},
@@ -682,7 +682,7 @@ PyDoc_STRVAR(module_doc,
 "This module supports asynchronous I/O on multiple file descriptors.\n\
 \n\
 *** IMPORTANT NOTICE ***\n\
-On Windows, only sockets are supported; on Unix, all file descriptors.");
+On Windows and OpenVMS, only sockets are supported; on Unix, all file descriptors.");
 
 PyMODINIT_FUNC
 initselect(void)
index 2d3fc564c564bee88e37055c2ff271000a02a012..11b184ed0a5fab023dbaac2c9584dedaec3b0c98 100644 (file)
@@ -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;