Patch #1516912: improve Modules support for OpenVMS.

This commit is contained in:
Neal Norwitz 2006-07-10 01:18:57 +00:00
parent 4a5fbda66d
commit 2a30cd0ef0
9 changed files with 154 additions and 63 deletions

View File

@ -108,6 +108,8 @@ Extension Modules
- Bug #1296433: parsing XML with a non-default encoding and - Bug #1296433: parsing XML with a non-default encoding and
a CharacterDataHandler could crash the interpreter in pyexpat. a CharacterDataHandler could crash the interpreter in pyexpat.
- Patch #1516912: improve Modules support for OpenVMS.
Build Build
----- -----

View File

@ -1311,7 +1311,11 @@ BZ2File_init(BZ2FileObject *self, PyObject *args, PyObject *kwargs)
break; break;
case 'U': case 'U':
#ifdef __VMS
self->f_univ_newline = 0;
#else
self->f_univ_newline = 1; self->f_univ_newline = 1;
#endif
break; break;
default: default:

View File

@ -5,6 +5,9 @@
#include <sys/types.h> #include <sys/types.h>
#ifdef __VMS
#include <openssl/des.h>
#endif
/* Module crypt */ /* Module crypt */
@ -12,7 +15,9 @@
static PyObject *crypt_crypt(PyObject *self, PyObject *args) static PyObject *crypt_crypt(PyObject *self, PyObject *args)
{ {
char *word, *salt; char *word, *salt;
#ifndef __VMS
extern char * crypt(const char *, const char *); extern char * crypt(const char *, const char *);
#endif
if (!PyArg_ParseTuple(args, "ss:crypt", &word, &salt)) { if (!PyArg_ParseTuple(args, "ss:crypt", &word, &salt)) {
return NULL; return NULL;

View File

@ -5,6 +5,10 @@
#include <dlfcn.h> #include <dlfcn.h>
#ifdef __VMS
#include <unistd.h>
#endif
#ifndef RTLD_LAZY #ifndef RTLD_LAZY
#define RTLD_LAZY 1 #define RTLD_LAZY 1
#endif #endif
@ -186,6 +190,24 @@ dl_open(PyObject *self, PyObject *args)
PyErr_SetString(Dlerror, dlerror()); PyErr_SetString(Dlerror, dlerror());
return NULL; 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); return newdlobject(handle);
} }

View File

@ -70,6 +70,10 @@ extern "C" {
#if defined(__FreeBSD__) #if defined(__FreeBSD__)
# include <ieeefp.h> # include <ieeefp.h>
#elif defined(__VMS)
#define __NEW_STARLET
#include <starlet.h>
#include <ieeedef.h>
#endif #endif
#ifndef WANT_SIGFPE_HANDLER #ifndef WANT_SIGFPE_HANDLER
@ -190,6 +194,19 @@ static void fpe_reset(Sigfunc *handler)
/*-- DEC ALPHA VMS --------------------------------------------------------*/ /*-- DEC ALPHA VMS --------------------------------------------------------*/
#elif defined(__ALPHA) && defined(__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); PyOS_setsig(SIGFPE, handler);
/*-- Cray Unicos ----------------------------------------------------------*/ /*-- Cray Unicos ----------------------------------------------------------*/
@ -244,6 +261,14 @@ static PyObject *turnoff_sigfpe(PyObject *self,PyObject *args)
#ifdef __FreeBSD__ #ifdef __FreeBSD__
fpresetsticky(fpgetsticky()); fpresetsticky(fpgetsticky());
fpsetmask(0); 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 #else
fputs("Operation not implemented\n", stderr); fputs("Operation not implemented\n", stderr);
#endif #endif

View File

@ -97,19 +97,19 @@
#ifndef VERSION #ifndef VERSION
#if defined(__VMS)
#define VERSION "2_1"
#else
#define VERSION "2.1" #define VERSION "2.1"
#endif #endif
#endif
#ifndef VPATH #ifndef VPATH
#define VPATH "." #define VPATH "."
#endif #endif
#ifndef PREFIX #ifndef PREFIX
#define PREFIX "/usr/local" # ifdef __VMS
# define PREFIX ""
# else
# define PREFIX "/usr/local"
# endif
#endif #endif
#ifndef EXEC_PREFIX #ifndef EXEC_PREFIX

View File

@ -7882,6 +7882,42 @@ win32_urandom(PyObject *self, PyObject *args)
} }
#endif #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[] = { static PyMethodDef posix_methods[] = {
{"access", posix_access, METH_VARARGS, posix_access__doc__}, {"access", posix_access, METH_VARARGS, posix_access__doc__},
#ifdef HAVE_TTYNAME #ifdef HAVE_TTYNAME
@ -8174,6 +8210,9 @@ static PyMethodDef posix_methods[] = {
#endif #endif
#ifdef MS_WINDOWS #ifdef MS_WINDOWS
{"urandom", win32_urandom, METH_VARARGS, win32_urandom__doc__}, {"urandom", win32_urandom, METH_VARARGS, win32_urandom__doc__},
#endif
#ifdef __VMS
{"urandom", vms_urandom, METH_VARARGS, vms_urandom__doc__},
#endif #endif
{NULL, NULL} /* Sentinel */ {NULL, NULL} /* Sentinel */
}; };

View File

@ -46,14 +46,14 @@ extern void bzero(void *, int);
#endif #endif
#ifdef MS_WINDOWS #ifdef MS_WINDOWS
#include <winsock.h> # include <winsock.h>
#else #else
#ifdef __BEOS__ # define SOCKET int
#include <net/socket.h> # ifdef __BEOS__
#define SOCKET int # include <net/socket.h>
#else # elif defined(__VMS)
#define SOCKET int # include <socket.h>
#endif # endif
#endif #endif
@ -668,7 +668,7 @@ arguments; each contains the subset of the corresponding file descriptors\n\
that are ready.\n\ that are ready.\n\
\n\ \n\
*** IMPORTANT NOTICE ***\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[] = { static PyMethodDef select_methods[] = {
{"select", select_select, METH_VARARGS, select_doc}, {"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\ "This module supports asynchronous I/O on multiple file descriptors.\n\
\n\ \n\
*** IMPORTANT NOTICE ***\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 PyMODINIT_FUNC
initselect(void) initselect(void)

View 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. */ (this includes the getaddrinfo emulation) protect access with a lock. */
#if defined(WITH_THREAD) && (defined(__APPLE__) || \ #if defined(WITH_THREAD) && (defined(__APPLE__) || \
(defined(__FreeBSD__) && __FreeBSD_version+0 < 503000) || \ (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 #define USE_GETADDRINFO_LOCK
#endif #endif
@ -186,15 +187,8 @@ shutdown(how) -- shut down traffic in one or both directions\n\
#endif #endif
#if defined(__VMS) #if defined(__VMS)
#if ! defined(_SOCKADDR_LEN)
# ifdef getaddrinfo
# undef getaddrinfo
# endif
# include "TCPIP_IOCTL_ROUTINE"
#else
# include <ioctl.h> # include <ioctl.h>
#endif #endif
#endif
#if defined(PYOS_OS2) #if defined(PYOS_OS2)
# define INCL_DOS # define INCL_DOS
@ -363,11 +357,6 @@ const char *inet_ntop(int af, const void *src, char *dst, socklen_t size);
#define SOCKETCLOSE close #define SOCKETCLOSE close
#endif #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) #if defined(HAVE_BLUETOOTH_H) || defined(HAVE_BLUETOOTH_BLUETOOTH_H)
#define USE_BLUETOOTH 1 #define USE_BLUETOOTH 1
#if defined(__FreeBSD__) #if defined(__FreeBSD__)
@ -386,6 +375,11 @@ const char *inet_ntop(int af, const void *src, char *dst, socklen_t size);
#endif #endif
#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() * Constants for getnameinfo()
*/ */
@ -620,6 +614,30 @@ set_gaierror(int error)
return NULL; 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 /* Function to perform the setting of socket blocking mode
internally. block = (1 | 0). */ internally. block = (1 | 0). */
static int static int
@ -644,8 +662,8 @@ internal_setblocking(PySocketSockObject *s, int block)
ioctl(s->sock_fd, FIONBIO, (caddr_t)&block, sizeof(block)); ioctl(s->sock_fd, FIONBIO, (caddr_t)&block, sizeof(block));
#elif defined(__VMS) #elif defined(__VMS)
block = !block; block = !block;
ioctl(s->sock_fd, FIONBIO, (char *)&block); ioctl(s->sock_fd, FIONBIO, (unsigned int *)&block);
#else /* !PYOS_OS2 && !_VMS */ #else /* !PYOS_OS2 && !__VMS */
delay_flag = fcntl(s->sock_fd, F_GETFL, 0); delay_flag = fcntl(s->sock_fd, F_GETFL, 0);
if (block) if (block)
delay_flag &= (~O_NONBLOCK); delay_flag &= (~O_NONBLOCK);
@ -1725,6 +1743,8 @@ sock_getsockopt(PySocketSockObject *s, PyObject *args)
return PyInt_FromLong(flag); return PyInt_FromLong(flag);
} }
#ifdef __VMS #ifdef __VMS
/* socklen_t is unsigned so no negative test is needed,
test buflen == 0 is previously done */
if (buflen > 1024) { if (buflen > 1024) {
#else #else
if (buflen <= 0 || buflen > 1024) { if (buflen <= 0 || buflen > 1024) {
@ -2498,9 +2518,6 @@ sock_send(PySocketSockObject *s, PyObject *args)
{ {
char *buf; char *buf;
int len, n = 0, flags = 0, timeout; int len, n = 0, flags = 0, timeout;
#ifdef __VMS
int send_length;
#endif
if (!PyArg_ParseTuple(args, "s#|i:send", &buf, &len, &flags)) if (!PyArg_ParseTuple(args, "s#|i:send", &buf, &len, &flags))
return NULL; return NULL;
@ -2508,11 +2525,14 @@ sock_send(PySocketSockObject *s, PyObject *args)
if (!IS_SELECTABLE(s)) if (!IS_SELECTABLE(s))
return select_error(); return select_error();
#ifndef __VMS
Py_BEGIN_ALLOW_THREADS Py_BEGIN_ALLOW_THREADS
timeout = internal_select(s, 1); timeout = internal_select(s, 1);
if (!timeout) if (!timeout)
#ifdef __VMS
n = sendsegmented(s->sock_fd, buf, len, flags);
#else
n = send(s->sock_fd, buf, len, flags); n = send(s->sock_fd, buf, len, flags);
#endif
Py_END_ALLOW_THREADS Py_END_ALLOW_THREADS
if (timeout) { if (timeout) {
@ -2521,36 +2541,6 @@ sock_send(PySocketSockObject *s, PyObject *args)
} }
if (n < 0) if (n < 0)
return s->errorhandler(); 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); return PyInt_FromLong((long)n);
} }
@ -2581,7 +2571,11 @@ sock_sendall(PySocketSockObject *s, PyObject *args)
timeout = internal_select(s, 1); timeout = internal_select(s, 1);
if (timeout) if (timeout)
break; break;
#ifdef __VMS
n = sendsegmented(s->sock_fd, buf, len, flags);
#else
n = send(s->sock_fd, buf, len, flags); n = send(s->sock_fd, buf, len, flags);
#endif
if (n < 0) if (n < 0)
break; break;
buf += n; buf += n;