Commit a7d0f82e authored by Martin v. Löwis's avatar Martin v. Löwis

Patch #614055: Support OpenVMS.

parent 41920530
......@@ -62,6 +62,9 @@ PyAPI_DATA(PyObject *) PyExc_ZeroDivisionError;
#ifdef MS_WINDOWS
PyAPI_DATA(PyObject *) PyExc_WindowsError;
#endif
#ifdef __VMS
extern DL_IMPORT(PyObject *) PyExc_VMSError;
#endif
PyAPI_DATA(PyObject *) PyExc_MemoryErrorInst;
......
......@@ -405,6 +405,7 @@ Geoff Philbrick
Adrian Phillips
Christopher J. Phoenix
Neale Pickett
Jean-Franois Pironne
Dan Pierson
Martijn Pieters
Franois Pinard
......
......@@ -826,6 +826,8 @@ C API
New platforms
-------------
- OpenVMS is now supported.
- AtheOS is now supported.
- the EMX runtime environment on OS/2 is now supported.
......
......@@ -947,7 +947,8 @@ calibrate(void)
}
#endif
}
#if defined(MS_WINDOWS) || defined(macintosh) || defined(PYOS_OS2)
#if defined(MS_WINDOWS) || defined(macintosh) || defined(PYOS_OS2) || \
defined(__VMS)
rusage_diff = -1;
#else
{
......
......@@ -28,12 +28,70 @@
#define BUILD 0
#endif
#ifdef __VMS
# ifdef __DECC
# pragma extern_model save
# pragma extern_model strict_refdef
extern long ctl$gl_imghdrbf;
# pragma extern_model restore
# endif
# ifdef __ALPHA
# define EIHD$L_IMGIDOFF 24
# define EIHI$Q_LINKTIME 8
# define _IMGIDOFF EIHD$L_IMGIDOFF
# define _LINKTIME EIHI$Q_LINKTIME
# else
# define IHD$W_IMGIDOFF 6
# define IHI$Q_LINKTIME 56
# define _IMGIDOFF IHD$W_IMGIDOFF
# define _LINKTIME IHI$Q_LINKTIME
# endif /* __VMS */
long*
vms__get_linktime (void)
{
long* al_imghdrbf;
unsigned short* aw_imgidoff;
unsigned short w_imgidoff;
long* aq_linktime;
unsigned char* ab_ihi;
al_imghdrbf = &ctl$gl_imghdrbf;
al_imghdrbf = (long *)*al_imghdrbf;
al_imghdrbf = (long *)*al_imghdrbf;
aw_imgidoff = (unsigned short *)
((unsigned char *)al_imghdrbf + _IMGIDOFF);
w_imgidoff = *aw_imgidoff;
ab_ihi = (unsigned char *)al_imghdrbf + w_imgidoff;
aq_linktime = (long *) (ab_ihi + _LINKTIME);
return aq_linktime;
} /* vms__get_linktime (void) */
extern void vms__cvt_v2u_time (long * aq_vmstime, time_t * al_unixtime);
/* input , output */
#endif /* __VMS */
const char *
Py_GetBuildInfo(void)
{
static char buildinfo[50];
#ifdef __VMS
time_t l_unixtime;
vms__cvt_v2u_time(vms__get_linktime (), &l_unixtime );
memset(buildinfo, 0, 40);
sprintf(buildinfo, "#%d, %.24s", BUILD, ctime (&l_unixtime));
#else
PyOS_snprintf(buildinfo, sizeof(buildinfo),
"#%d, %.20s, %.9s", BUILD, DATE, TIME);
#endif
return buildinfo;
}
......@@ -92,8 +92,12 @@
*/
#ifndef VERSION
#if defined(__VMS)
#define VERSION "2_1"
#else
#define VERSION "2.1"
#endif
#endif
#ifndef VPATH
#define VPATH "."
......
......@@ -4,6 +4,11 @@
#include "osdefs.h"
#include "compile.h" /* For CO_FUTURE_DIVISION */
#ifdef __VMS
extern int PyVMS_init(int* pvi_argc, char*** pvi_argv);
extern PyObject* pyvms_gr_empty_string;
#endif
#if defined(MS_WINDOWS) || defined(__CYGWIN__)
#include <fcntl.h>
#endif
......@@ -98,7 +103,18 @@ usage(int exitcode, char* program)
fprintf(f, usage_3);
fprintf(f, usage_4, DELIM, DELIM, PYTHONHOMEHELP);
}
#if defined(__VMS)
if (exitcode == 0) {
/* suppress 'error' message */
exit(1);
}
else {
/* STS$M_INHIB_MSG + SS$_ABORT */
exit(0x1000002c);
}
#else
exit(exitcode);
#endif
/*NOTREACHED*/
}
......@@ -145,7 +161,12 @@ Py_Main(int argc, char **argv)
if ((fp = fopen(filename, "r")) == NULL) {
fprintf(stderr, "%s: can't open file '%s'\n",
argv[0], filename);
#if defined(__VMS)
/* STS$M_INHIB_MSG + SS$_ABORT */
exit(0x1000002c);
#else
exit(2);
#endif
}
}
/* Skip option-processing if we are an applet */
......@@ -338,14 +359,50 @@ Py_Main(int argc, char **argv)
#endif /* !MS_WINDOWS */
/* Leave stderr alone - it should be unbuffered anyway. */
}
#ifdef __VMS
else {
setvbuf (stdout, (char *)NULL, _IOLBF, BUFSIZ);
}
#endif /* __VMS */
Py_SetProgramName(argv[0]);
#ifdef __VMS
PyVMS_init(&argc, &argv);
#endif
Py_Initialize();
#ifdef __VMS
/* create an empty string object */
pyvms_gr_empty_string = Py_BuildValue("s#", Py_None, (unsigned int)0);
#endif
if (Py_VerboseFlag ||
(command == NULL && filename == NULL && stdin_is_interactive))
#ifndef __VMS
fprintf(stderr, "Python %s on %s\n%s\n",
Py_GetVersion(), Py_GetPlatform(), COPYRIGHT);
#else
fprintf(stderr, "Python %s on %s %s (%s_float)\n%s\n",
Py_GetVersion(), Py_GetPlatform(),
# ifdef __ALPHA
"Alpha",
# else
"VAX",
# endif
# if __IEEE_FLOAT
"T",
# else
# if __D_FLOAT
"D",
# else
# if __G_FLOAT
"G",
# endif /* __G_FLOAT */
# endif /* __D_FLOAT */
# endif /* __IEEE_FLOAT */
COPYRIGHT); /* << @@ defined above in this file */
/* Py_GetCopyright()); */
#endif /* __VMS */
if (command != NULL) {
/* Backup _PyOS_optind and force sys.argv[0] = '-c' */
......
This diff is collapsed.
......@@ -67,10 +67,18 @@ mkpwent(struct passwd *p)
#define SETS(i,val) sets(v, i, val)
SETS(setIndex++, p->pw_name);
#ifdef __VMS
SETS(setIndex++, "");
#else
SETS(setIndex++, p->pw_passwd);
#endif
SETI(setIndex++, p->pw_uid);
SETI(setIndex++, p->pw_gid);
#ifdef __VMS
SETS(setIndex++, "");
#else
SETS(setIndex++, p->pw_gecos);
#endif
SETS(setIndex++, p->pw_dir);
SETS(setIndex++, p->pw_shell);
......
......@@ -148,6 +148,15 @@ shutdown(how) -- shut down traffic in one or both directions\n\
# include <ctype.h>
#endif
#if defined(__VMS) && ! defined(_SOCKADDR_LEN)
# ifdef getaddrinfo
# undef getaddrinfo
# endif
# include "TCPIP_IOCTL_ROUTINE"
#else
# include <ioctl.h>
#endif
#if defined(PYOS_OS2)
# define INCL_DOS
# define INCL_DOSERRORS
......@@ -270,6 +279,11 @@ 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
/* XXX There's a problem here: *static* functions are not supposed to have
a Py prefix (or use CapitalizedWords). Later... */
......@@ -485,7 +499,10 @@ internal_setblocking(PySocketSockObject *s, int block)
#if defined(PYOS_OS2) && !defined(PYCC_GCC)
block = !block;
ioctl(s->sock_fd, FIONBIO, (caddr_t)&block, sizeof(block));
#else /* !PYOS_OS2 */
#elif defined(__VMS)
block = !block;
ioctl(s->sock_fd, FIONBIO, (char *)&block);
#else /* !PYOS_OS2 && !_VMS */
delay_flag = fcntl(s->sock_fd, F_GETFL, 0);
if (block)
delay_flag &= (~O_NONBLOCK);
......@@ -1223,7 +1240,11 @@ sock_getsockopt(PySocketSockObject *s, PyObject *args)
return s->errorhandler();
return PyInt_FromLong(flag);
}
#ifdef __VMS
if (buflen > 1024) {
#else
if (buflen <= 0 || buflen > 1024) {
#endif
PyErr_SetString(socket_error,
"getsockopt buflen out of range");
return NULL;
......@@ -1560,9 +1581,23 @@ sock_makefile(PySocketSockObject *s, PyObject *args)
#endif
FILE *fp;
PyObject *f;
#ifdef __VMS
char *mode_r = "r";
char *mode_w = "w";
#endif
if (!PyArg_ParseTuple(args, "|si:makefile", &mode, &bufsize))
return NULL;
#ifdef __VMS
if (strcmp(mode,"rb") == 0) {
mode = mode_r;
}
else {
if (strcmp(mode,"wb") == 0) {
mode = mode_w;
}
}
#endif
#ifdef MS_WIN32
if (((fd = _open_osfhandle(s->sock_fd, _O_BINARY)) < 0) ||
((fd = dup(fd)) < 0) || ((fp = fdopen(fd, mode)) == NULL))
......@@ -1601,6 +1636,10 @@ sock_recv(PySocketSockObject *s, PyObject *args)
{
int len, n, flags = 0;
PyObject *buf;
#ifdef __VMS
int read_length;
char *read_buf;
#endif
if (!PyArg_ParseTuple(args, "i|i:recv", &len, &flags))
return NULL;
......@@ -1615,6 +1654,7 @@ sock_recv(PySocketSockObject *s, PyObject *args)
if (buf == NULL)
return NULL;
#ifndef __VMS
Py_BEGIN_ALLOW_THREADS
internal_select(s, 0);
n = recv(s->sock_fd, PyString_AS_STRING(buf), len, flags);
......@@ -1626,6 +1666,42 @@ sock_recv(PySocketSockObject *s, PyObject *args)
}
if (n != len)
_PyString_Resize(&buf, n);
#else
read_buf = PyString_AsString(buf);
read_length = len;
while (read_length != 0) {
unsigned int segment;
segment = read_length /SEGMENT_SIZE;
if (segment != 0) {
segment = SEGMENT_SIZE;
}
else {
segment = read_length;
}
Py_BEGIN_ALLOW_THREADS
internal_select(s, 0);
n = recv(s->sock_fd, read_buf, segment, flags);
Py_END_ALLOW_THREADS
if (n < 0) {
Py_DECREF(buf);
return s->errorhandler();
}
if (n != read_length) {
read_buf += n;
break;
}
read_length -= segment;
read_buf += segment;
}
if (_PyString_Resize(&buf, (read_buf - PyString_AsString(buf))) < 0)
{
return NULL;
}
#endif /* !__VMS */
return buf;
}
......@@ -1707,10 +1783,14 @@ sock_send(PySocketSockObject *s, PyObject *args)
{
char *buf;
int len, n, flags = 0;
#ifdef __VMS
int send_length;
#endif
if (!PyArg_ParseTuple(args, "s#|i:send", &buf, &len, &flags))
return NULL;
#ifndef __VMS
Py_BEGIN_ALLOW_THREADS
internal_select(s, 1);
n = send(s->sock_fd, buf, len, flags);
......@@ -1718,6 +1798,31 @@ 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
internal_select(s, 1);
n = send(s->sock_fd, buf, segment, flags);
Py_END_ALLOW_THREADS
if (n < 0) {
return s->errorhandler();
}
send_length -= segment;
buf += segment;
} /* end while */
#endif /* !__VMS */
return PyInt_FromLong((long)n);
}
......
......@@ -765,7 +765,11 @@ string_print(PyStringObject *op, FILE *fp, int flags)
return ret;
}
if (flags & Py_PRINT_RAW) {
fwrite(op->ob_sval, 1, (int) op->ob_size, fp);
#ifdef __VMS
if (op->ob_size) fwrite(op->ob_sval, (int) op->ob_size, 1, fp);
#else
fwrite(op->ob_sval, 1, (int) op->ob_size, fp);
#endif
return 0;
}
......
......@@ -67,6 +67,7 @@ Exception\n\
| | +-- OSError\n\
| | |\n\
| | +-- WindowsError\n\
| | +-- VMSError\n\
| |\n\
| +-- EOFError\n\
| +-- RuntimeError\n\
......@@ -643,6 +644,11 @@ PyDoc_STRVAR(OSError__doc__, "OS system call failed.");
PyDoc_STRVAR(WindowsError__doc__, "MS-Windows OS system call failed.");
#endif /* MS_WINDOWS */
#ifdef __VMS
static char
VMSError__doc__[] = "OpenVMS OS system call failed.";
#endif
PyDoc_STRVAR(EOFError__doc__, "Read beyond end of file.");
PyDoc_STRVAR(RuntimeError__doc__, "Unspecified run-time error.");
......@@ -1599,6 +1605,9 @@ PyObject *PyExc_ZeroDivisionError;
#ifdef MS_WINDOWS
PyObject *PyExc_WindowsError;
#endif
#ifdef __VMS
PyObject *PyExc_VMSError;
#endif
/* Pre-computed MemoryError instance. Best to create this as early as
* possibly and not wait until a MemoryError is actually raised!
......@@ -1650,6 +1659,10 @@ static struct {
{"WindowsError", &PyExc_WindowsError, &PyExc_OSError,
WindowsError__doc__},
#endif /* MS_WINDOWS */
#ifdef __VMS
{"VMSError", &PyExc_VMSError, &PyExc_OSError,
VMSError__doc__},
#endif
{"EOFError", &PyExc_EOFError, 0, EOFError__doc__},
{"RuntimeError", &PyExc_RuntimeError, 0, RuntimeError__doc__},
{"NotImplementedError", &PyExc_NotImplementedError,
......
......@@ -693,8 +693,11 @@ open_exclusive(char *filename)
#ifdef O_BINARY
|O_BINARY /* necessary for Windows */
#endif
, 0666);
#ifdef __VMS
, 0666, "ctxt=bin", "shr=nil");
#else
, 0666);
#endif
if (fd < 0)
return NULL;
return fdopen(fd, "wb");
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment