diff options
author | Guido van Rossum <guido@python.org> | 1997-11-22 21:53:48 (GMT) |
---|---|---|
committer | Guido van Rossum <guido@python.org> | 1997-11-22 21:53:48 (GMT) |
commit | 8e9ebfd337f18f7b707853a3f2f49cc6245c0596 (patch) | |
tree | fe6a0f373d376dede8ad635c250ab83c19965a3f /Modules | |
parent | c0b93191e6e12fb391461545031808f74a8ae956 (diff) | |
download | cpython-8e9ebfd337f18f7b707853a3f2f49cc6245c0596.zip cpython-8e9ebfd337f18f7b707853a3f2f49cc6245c0596.tar.gz cpython-8e9ebfd337f18f7b707853a3f2f49cc6245c0596.tar.bz2 |
os2 patch by Jeff Rush
Diffstat (limited to 'Modules')
-rw-r--r-- | Modules/posixmodule.c | 257 | ||||
-rw-r--r-- | Modules/selectmodule.c | 5 | ||||
-rw-r--r-- | Modules/signalmodule.c | 5 | ||||
-rw-r--r-- | Modules/socketmodule.c | 131 | ||||
-rw-r--r-- | Modules/timemodule.c | 22 |
5 files changed, 399 insertions, 21 deletions
diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c index 58111ef..8679e09 100644 --- a/Modules/posixmodule.c +++ b/Modules/posixmodule.c @@ -46,10 +46,16 @@ standardized by the C Standard and the POSIX standard (a thinly\n\ disguised Unix interface). Refer to the library manual and\n\ corresponding Unix manual entries for more information on calls."; - - #include "Python.h" +#if defined(PYOS_OS2) +#define INCL_DOS +#define INCL_DOSERRORS +#define INCL_DOSPROCESS +#define INCL_NOPMAPI +#include <os2.h> +#endif + #include <sys/types.h> #include <sys/stat.h> #ifdef HAVE_SYS_WAIT_H @@ -68,6 +74,24 @@ corresponding Unix manual entries for more information on calls."; /* Various compilers have only certain posix functions */ /* XXX Gosh I wish these were all moved into config.h */ +#if defined(PYCC_VACPP) && defined(PYOS_OS2) + #define HAVE_EXECV 1 + #define HAVE_GETCWD 1 + #define HAVE_SYSTEM 1 + #define HAVE_WAIT 1 + #define HAVE_KILL 1 + #define HAVE_PIPE 1 + #define HAVE_POPEN 1 + +// #define HAVE_FORK 1 +// #define HAVE_GETEGID 1 +// #define HAVE_GETEUID 1 +// #define HAVE_GETGID 1 +// #define HAVE_GETPPID 1 +// #define HAVE_GETUID 1 +// #define HAVE_OPENDIR 1 +#include <process.h> +#else #ifdef __WATCOMC__ /* Watcom compiler */ #define HAVE_GETCWD 1 #define HAVE_OPENDIR 1 @@ -121,6 +145,7 @@ corresponding Unix manual entries for more information on calls."; #endif /* _MSC_VER */ #endif /* __BORLANDC__ */ #endif /* ! __WATCOMC__ */ +#endif /* ! __IBMC__ */ #ifndef _MSC_VER @@ -143,13 +168,22 @@ extern int pclose(); extern int lstat(); extern int symlink(); #else /* !HAVE_UNISTD_H */ +#if defined(PYCC_VACPP) +extern int mkdir Py_PROTO((char *)); +#else #if defined(__WATCOMC__) || defined(_MSC_VER) extern int mkdir Py_PROTO((const char *)); #else extern int mkdir Py_PROTO((const char *, mode_t)); #endif +#endif +#if defined(__IBMC__) || defined(__IBMCPP__) +extern int chdir Py_PROTO((char *)); +extern int rmdir Py_PROTO((char *)); +#else extern int chdir Py_PROTO((const char *)); extern int rmdir Py_PROTO((const char *)); +#endif extern int chmod Py_PROTO((const char *, mode_t)); extern int chown Py_PROTO((const char *, uid_t, gid_t)); extern char *getcwd Py_PROTO((char *, int)); @@ -310,7 +344,7 @@ posix_2str(args, func) Py_BEGIN_ALLOW_THREADS res = (*func)(path1, path2); Py_END_ALLOW_THREADS - if (res < 0) + if (res != 0) return posix_error(); Py_INCREF(Py_None); return Py_None; @@ -480,7 +514,7 @@ posix_listdir(self, args) PyObject *self; PyObject *args; { - /* XXX Should redo this putting the three versions of opendir + /* XXX Should redo this putting the (now four) versions of opendir in separate files instead of having them all here... */ #if defined(MS_WIN32) && !defined(HAVE_OPENDIR) @@ -601,6 +635,78 @@ posix_listdir(self, args) return d; #else +#if defined(PYOS_OS2) + +#ifndef MAX_PATH +#define MAX_PATH CCHMAXPATH +#endif + char *name, *pt; + int len; + PyObject *d, *v; + char namebuf[MAX_PATH+5]; + HDIR hdir = 1; + ULONG srchcnt = 1; + FILEFINDBUF3 ep; + APIRET rc; + + if (!PyArg_Parse(args, "s#", &name, &len)) + return NULL; + if (len >= MAX_PATH) { + PyErr_SetString(PyExc_ValueError, "path too long"); + return NULL; + } + strcpy(namebuf, name); + for (pt = namebuf; *pt; pt++) + if (*pt == '/') + *pt = '\\'; + if (namebuf[len-1] != '\\') + namebuf[len++] = '\\'; + strcpy(namebuf + len, "*.*"); + + if ((d = PyList_New(0)) == NULL) + return NULL; + + rc = DosFindFirst(namebuf, // Wildcard Pattern to Match + &hdir, // Handle to Use While Search Directory + FILE_READONLY | FILE_HIDDEN | FILE_SYSTEM | FILE_DIRECTORY, + &ep, sizeof(ep), // Structure to Receive Directory Entry + &srchcnt, // Max and Actual Count of Entries Per Iteration + FIL_STANDARD); // Format of Entry (EAs or Not) + + if (rc != NO_ERROR) { + errno = ENOENT; + return posix_error(); + } + + if (srchcnt > 0) { // If Directory is NOT Totally Empty, + do { + if (ep.achName[0] == '.' + && (ep.achName[1] == '\0' || ep.achName[1] == '.' && ep.achName[2] == '\0')) + continue; // Skip Over "." and ".." Names + + strcpy(namebuf, ep.achName); + + // Leave Case of Name Alone -- In Native Form + // (Removed Forced Lowercasing Code) + + v = PyString_FromString(namebuf); + if (v == NULL) { + Py_DECREF(d); + d = NULL; + break; + } + if (PyList_Append(d, v) != 0) { + Py_DECREF(v); + Py_DECREF(d); + d = NULL; + break; + } + Py_DECREF(v); + } while (DosFindNext(hdir, &ep, sizeof(ep), &srchcnt) == NO_ERROR && srchcnt > 0); + } + + return d; +#else char *name; PyObject *d, *v; @@ -642,6 +748,7 @@ posix_listdir(self, args) return d; +#endif /* !PYOS_OS2 */ #endif /* !_MSC_VER */ #endif /* !MS_WIN32 */ } @@ -661,7 +768,7 @@ posix_mkdir(self, args) if (!PyArg_ParseTuple(args, "s|i", &path, &mode)) return NULL; Py_BEGIN_ALLOW_THREADS -#if defined(__WATCOMC__) || defined(_MSC_VER) +#if defined(__WATCOMC__) || defined(_MSC_VER) || defined(PYCC_VACPP) res = mkdir(path); #else res = mkdir(path, mode); @@ -1246,8 +1353,23 @@ posix_kill(self, args) int pid, sig; if (!PyArg_Parse(args, "(ii)", &pid, &sig)) return NULL; +#if defined(__TOS_OS2__) + if (sig == XCPT_SIGNAL_INTR || sig == XCPT_SIGNAL_BREAK) { + APIRET rc; + if ((rc = DosSendSignalException(pid, sig)) != NO_ERROR) + return posix_error(); + + } else if (sig == XCPT_SIGNAL_KILLPROC) { + APIRET rc; + if ((rc = DosKillProcess(DKP_PROCESS, pid)) != NO_ERROR) + return posix_error(); + + } else + return NULL; // Unrecognized Signal Requested +#else if (kill(pid, sig) == -1) return posix_error(); +#endif Py_INCREF(Py_None); return Py_None; } @@ -1284,6 +1406,108 @@ static char posix_popen__doc__[] = "popen(command [, mode='r' [, bufsize]]) -> pipe\n\ Open a pipe to/from a command returning a file object."; +#if defined(PYOS_OS2) +int +async_system(const char *command) +{ + char *p, errormsg[256], args[1024]; + RESULTCODES rcodes; + APIRET rc; + char *shell = getenv("COMSPEC"); + if (!shell) + shell = "cmd"; + + strcpy(args, shell); + p = &args[ strlen(args)+1 ]; + strcpy(p, "/c "); + strcat(p, command); + p += strlen(p) + 1; + *p = '\0'; + + rc = DosExecPgm(errormsg, sizeof(errormsg), + EXEC_ASYNC, // Execute Async w/o Wait for Results + args, + NULL, // Inherit Parent's Environment + &rcodes, shell); + return rc; +} + +FILE * +popen(const char *command, const char *mode, int pipesize) +{ + HFILE rhan, whan; + FILE *retfd = NULL; + APIRET rc = DosCreatePipe(&rhan, &whan, pipesize); + + if (rc != NO_ERROR) + return NULL; // ERROR - Unable to Create Anon Pipe + + if (strchr(mode, 'r') != NULL) { // Treat Command as a Data Source + int oldfd = dup(1); // Save STDOUT Handle in Another Handle + + DosEnterCritSec(); // Stop Other Threads While Changing Handles + close(1); // Make STDOUT Available for Reallocation + + if (dup2(whan, 1) == 0) { // Connect STDOUT to Pipe Write Side + DosClose(whan); // Close Now-Unused Pipe Write Handle + + if (async_system(command) == NO_ERROR) + retfd = fdopen(rhan, "rb"); // And Return Pipe Read Handle + } + + dup2(oldfd, 1); // Reconnect STDOUT to Original Handle + DosExitCritSec(); // Now Allow Other Threads to Run + + close(oldfd); // And Close Saved STDOUT Handle + return retfd; // Return fd of Pipe or NULL if Error + + } else if (strchr(mode, 'w')) { // Treat Command as a Data Sink + int oldfd = dup(0); // Save STDIN Handle in Another Handle + + DosEnterCritSec(); // Stop Other Threads While Changing Handles + close(0); // Make STDIN Available for Reallocation + + if (dup2(rhan, 0) == 0) { // Connect STDIN to Pipe Read Side + DosClose(rhan); // Close Now-Unused Pipe Read Handle + + if (async_system(command) == NO_ERROR) + retfd = fdopen(whan, "wb"); // And Return Pipe Write Handle + } + + dup2(oldfd, 0); // Reconnect STDIN to Original Handle + DosExitCritSec(); // Now Allow Other Threads to Run + + close(oldfd); // And Close Saved STDIN Handle + return retfd; // Return fd of Pipe or NULL if Error + + } else + return NULL; // ERROR - Invalid Mode (Neither Read nor Write) +} + +static PyObject * +posix_popen(self, args) + PyObject *self; + PyObject *args; +{ + char *name; + char *mode = "r"; + int bufsize = -1; + FILE *fp; + PyObject *f; + if (!PyArg_ParseTuple(args, "s|si", &name, &mode, &bufsize)) + return NULL; + Py_BEGIN_ALLOW_THREADS + fp = popen(name, mode, (bufsize > 0) ? bufsize : 4096); + Py_END_ALLOW_THREADS + if (fp == NULL) + return posix_error(); + f = PyFile_FromFile(fp, name, mode, fclose); + if (f != NULL) + PyFile_SetBufSize(f, bufsize); + return f; +} + +#else static PyObject * posix_popen(self, args) PyObject *self; @@ -1306,6 +1530,8 @@ posix_popen(self, args) PyFile_SetBufSize(f, bufsize); return f; } +#endif + #endif /* HAVE_POPEN */ @@ -1840,6 +2066,21 @@ posix_pipe(self, args) PyObject *self; PyObject *args; { +#if defined(PYOS_OS2) + HFILE read, write; + APIRET rc; + + if (!PyArg_Parse(args, "")) + return NULL; + + Py_BEGIN_ALLOW_THREADS + rc = DosCreatePipe( &read, &write, 4096); + Py_END_ALLOW_THREADS + if (rc != NO_ERROR) + return posix_error(); + + return Py_BuildValue("(ii)", read, write); +#else #if !defined(MS_WIN32) int fds[2]; int res; @@ -1863,6 +2104,7 @@ posix_pipe(self, args) return posix_error(); return Py_BuildValue("(ii)", read, write); #endif /* MS_WIN32 */ +#endif } #endif /* HAVE_PIPE */ @@ -2259,9 +2501,14 @@ all_ins(d) #define INITFUNC initnt #define MODNAME "nt" #else +#if defined(PYOS_OS2) +#define INITFUNC initos2 +#define MODNAME "os2" +#else #define INITFUNC initposix #define MODNAME "posix" #endif +#endif void INITFUNC() diff --git a/Modules/selectmodule.c b/Modules/selectmodule.c index 7655c3c..be0c604 100644 --- a/Modules/selectmodule.c +++ b/Modules/selectmodule.c @@ -48,6 +48,11 @@ extern void bzero(); #include <sys/types.h> +#if defined(PYOS_OS2) +#include <sys/time.h> +#include <utils.h> +#endif + #ifdef MS_WINDOWS #include <winsock.h> #else diff --git a/Modules/signalmodule.c b/Modules/signalmodule.c index e91c3cb..175f6eb 100644 --- a/Modules/signalmodule.c +++ b/Modules/signalmodule.c @@ -50,6 +50,11 @@ PERFORMANCE OF THIS SOFTWARE. #define SIG_ERR ((RETSIGTYPE (*)())-1) #endif +#if defined(PYOS_OS2) +#define NSIG 12 +#include <process.h> +#endif + #ifndef NSIG #ifdef _SIGMAX #define NSIG (_SIGMAX + 1) /* For QNX */ diff --git a/Modules/socketmodule.c b/Modules/socketmodule.c index 5819346..4de1301 100644 --- a/Modules/socketmodule.c +++ b/Modules/socketmodule.c @@ -91,10 +91,25 @@ Socket methods: #include <unistd.h> #endif -#ifndef MS_WINDOWS +#if !defined(MS_WINDOWS) && !defined(PYOS_OS2) extern int gethostname(); /* For Solaris, at least */ #endif +#if defined(PYCC_VACPP) +#include <types.h> +#include <io.h> +#include <sys/ioctl.h> +#include <utils.h> +#include <ctype.h> +#endif + +#if defined(PYOS_OS2) +#define INCL_DOS +#define INCL_DOSERRORS +#define INCL_NOPMAPI +#include <os2.h> +#endif + #include <sys/types.h> #include "mytime.h" @@ -136,6 +151,12 @@ extern int gethostname(); /* For Solaris, at least */ #define FORCE_ANSI_FUNC_DEFS #endif +#if defined(PYOS_OS2) +#define close soclose +#define NO_DUP /* Sockets are Not Actual File Handles under OS/2 */ +#define FORCE_ANSI_FUNC_DEFS +#endif + #ifdef FORCE_ANSI_FUNC_DEFS #define BUILD_FUNC_DEF_1( fnname, arg1type, arg1name ) \ fnname( arg1type arg1name ) @@ -198,6 +219,36 @@ PySocket_Err() } else #endif + +#if defined(PYOS_OS2) + if (sock_errno() != NO_ERROR) { + APIRET rc; + ULONG msglen; + char outbuf[100]; + int myerrorcode = sock_errno(); + + /* Retrieve Socket-Related Error Message from MPTN.MSG File */ + rc = DosGetMessage(NULL, 0, outbuf, sizeof(outbuf), + myerrorcode - SOCBASEERR + 26, "mptn.msg", &msglen); + if (rc == NO_ERROR) { + PyObject *v; + + outbuf[msglen] = '\0'; /* OS/2 Doesn't Guarantee a Terminator */ + if (strlen(outbuf) > 0) { /* If Non-Empty Msg, Trim CRLF */ + char *lastc = &outbuf[ strlen(outbuf)-1 ]; + while (lastc > outbuf && isspace(*lastc)) + *lastc-- = '\0'; /* Trim Trailing Whitespace (CRLF) */ + } + v = Py_BuildValue("(is)", myerrorcode, outbuf); + if (v != NULL) { + PyErr_SetObject(PySocket_Error, v); + Py_DECREF(v); + } + return NULL; + } + } +#endif + return PyErr_SetFromErrno(PySocket_Error); } @@ -527,16 +578,21 @@ BUILD_FUNC_DEF_2(PySocketSock_setblocking,PySocketSockObject*,s,PyObject*,args) return NULL; Py_BEGIN_ALLOW_THREADS #ifndef MS_WINDOWS +#ifdef PYOS_OS2 + block = !block; + ioctl(s->sock_fd, FIONBIO, (caddr_t)&block, sizeof(block)); +#else /* !PYOS_OS2 */ delay_flag = fcntl (s->sock_fd, F_GETFL, 0); if (block) delay_flag &= (~O_NDELAY); else delay_flag |= O_NDELAY; fcntl (s->sock_fd, F_SETFL, delay_flag); -#else +#endif /* !PYOS_OS2 */ +#else /* MS_WINDOWS */ block = !block; ioctlsocket(s->sock_fd, FIONBIO, (u_long*)&block); -#endif +#endif /* MS_WINDOWS */ Py_END_ALLOW_THREADS Py_INCREF(Py_None); @@ -883,7 +939,11 @@ BUILD_FUNC_DEF_2(PySocketSock_recvfrom,PySocketSockObject *,s, PyObject *,args) Py_BEGIN_ALLOW_THREADS n = recvfrom(s->sock_fd, PyString_AsString(buf), len, flags, #ifndef MS_WINDOWS + #if defined(PYOS_OS2) + (struct sockaddr *)addrbuf, &addrlen + #else (ANY *)addrbuf, &addrlen + #endif #else (struct sockaddr *)addrbuf, &addrlen #endif @@ -1388,22 +1448,57 @@ NTinit() #endif /* MS_WINDOWS */ +#if defined(PYOS_OS2) + +/* Additional initialization and cleanup for OS/2 */ + +static void +OS2cleanup() +{ + /* No cleanup is necessary for OS/2 Sockets */ +} + +static int +OS2init() +{ + char reason[64]; + int rc = sock_init(); + + if (rc == 0) { + atexit(OS2cleanup); + return 1; // Indicate Success + } + + sprintf(reason, "OS/2 TCP/IP Error# %d", sock_errno()); + PyErr_SetString(PyExc_ImportError, reason); + + return 0; // Indicate Failure +} + +#endif /* PYOS_OS2 */ + /* Initialize this module. - This is called when the first 'import socket' is done, - via a table in config.c, if config.c is compiled with USE_SOCKET - defined. - - For MS_WINDOWS (which means any Windows variant), this module - is actually called "_socket", and there's a wrapper "socket.py" - which implements some missing functionality (such as makefile(), - dup() and fromfd()). The import of "_socket" may fail with an - ImportError exception if initialization of WINSOCK fails. When - WINSOCK is initialized succesfully, a call to WSACleanup() is - scheduled to be made at exit time. */ + * This is called when the first 'import socket' is done, + * via a table in config.c, if config.c is compiled with USE_SOCKET + * defined. + * + * For MS_WINDOWS (which means any Windows variant), this module + * is actually called "_socket", and there's a wrapper "socket.py" + * which implements some missing functionality (such as makefile(), + * dup() and fromfd()). The import of "_socket" may fail with an + * ImportError exception if initialization of WINSOCK fails. When + * WINSOCK is initialized succesfully, a call to WSACleanup() is + * scheduled to be made at exit time. + * + * For OS/2, this module is also called "_socket" and uses a wrapper + * "socket.py" which implements that functionality that is missing + * when PC operating systems don't put socket descriptors in the + * operating system's filesystem layer. + */ void -#ifdef MS_WINDOWS +#if defined(MS_WINDOWS) || defined(PYOS_OS2) init_socket() #else initsocket() @@ -1415,7 +1510,13 @@ initsocket() return; m = Py_InitModule("_socket", PySocket_methods); #else + #if defined(__TOS_OS2__) + if (!OS2init()) + return; + m = Py_InitModule("_socket", PySocket_methods); + #else m = Py_InitModule("socket", PySocket_methods); + #endif #endif d = PyModule_GetDict(m); PySocket_Error = PyErr_NewException("socket.error", NULL, NULL); diff --git a/Modules/timemodule.c b/Modules/timemodule.c index e8de0ac..6390c40 100644 --- a/Modules/timemodule.c +++ b/Modules/timemodule.c @@ -59,7 +59,7 @@ PERFORMANCE OF THIS SOFTWARE. #ifdef HAVE_FTIME #include <sys/timeb.h> -#ifndef MS_WINDOWS +#if !defined(MS_WINDOWS) && !defined(PYOS_OS2) extern int ftime(); #endif /* MS_WINDOWS */ #endif /* HAVE_FTIME */ @@ -85,6 +85,18 @@ extern int ftime(); #undef HAVE_CLOCK /* We have our own version down below */ #endif /* MS_WIN32 */ +#if defined(PYOS_OS2) +#define INCL_DOS +#define INCL_DOSERRORS +#define INCL_NOPMAPI +#include <os2.h> +#endif + +#if defined(PYCC_VACPP) +#include <time.h> +#define timezone _timezone +#endif + /* Forward declarations */ static int floatsleep Py_PROTO((double)); static double floattime Py_PROTO(()); @@ -588,10 +600,18 @@ floatsleep(double secs) Sleep((int)(secs*1000)); Py_END_ALLOW_THREADS #else /* !MS_WIN32 */ +#ifdef PYOS_OS2 + /* This Sleep *IS* Interruptable by Exceptions */ + if (DosSleep(secs * 1000) != NO_ERROR) { + PyErr_SetFromErrno(PyExc_IOError); + return -1; + } +#else /* !PYOS_OS2 */ /* XXX Can't interrupt this sleep */ Py_BEGIN_ALLOW_THREADS sleep((int)secs); Py_END_ALLOW_THREADS +#endif /* !PYOS_OS2 */ #endif /* !MS_WIN32 */ #endif /* !MSDOS */ #endif /* !__WATCOMC__ */ |