OS/2 EMX port changes (Python part of patch #450267):

Python/
    dynload_shlib.c  // EMX port emulates dlopen() etc. for DL extensions
    import.c         // changes to support 8.3 DLL name limit (VACPP+EMX)
                     //  and case sensitive import semantics
    importdl.h
    thread_os2.h
This commit is contained in:
Andrew MacIntyre 2002-02-26 11:41:34 +00:00
parent c487439aa7
commit d940054ad4
4 changed files with 140 additions and 3 deletions

View File

@ -18,6 +18,10 @@
#ifdef HAVE_DLFCN_H
#include <dlfcn.h>
#else
#if defined(PYOS_OS2) && defined(PYCC_GCC)
#include "dlfcn.h"
#endif
#endif
#if (defined(__OpenBSD__) || defined(__NetBSD__)) && !defined(__ELF__)
@ -31,9 +35,14 @@ const struct filedescr _PyImport_DynLoadFiletab[] = {
#ifdef __CYGWIN__
{".dll", "rb", C_EXTENSION},
{"module.dll", "rb", C_EXTENSION},
#else
#if defined(PYOS_OS2) && defined(PYCC_GCC)
{".pyd", "rb", C_EXTENSION},
{".dll", "rb", C_EXTENSION},
#else
{".so", "rb", C_EXTENSION},
{"module.so", "rb", C_EXTENSION},
#endif
#endif
{0, 0}
};
@ -82,7 +91,9 @@ dl_funcptr _PyImport_GetDynLoadFunc(const char *fqname, const char *shortname,
}
}
#if !(defined(PYOS_OS2) && defined(PYCC_GCC))
dlopenflags = PyThreadState_Get()->interp->dlopenflags;
#endif
if (Py_VerboseFlag)
printf("dlopen(\"%s\", %x);\n", pathname, dlopenflags);

View File

@ -900,6 +900,11 @@ find_module(char *realname, PyObject *path, char *buf, size_t buflen,
static struct filedescr fd_builtin = {"", "", C_BUILTIN};
static struct filedescr fd_package = {"", "", PKG_DIRECTORY};
char name[MAXPATHLEN+1];
#if defined(PYOS_OS2)
size_t saved_len;
size_t saved_namelen;
char *saved_buf = NULL;
#endif
if (strlen(realname) > MAXPATHLEN) {
PyErr_SetString(PyExc_OverflowError,
@ -1026,7 +1031,38 @@ find_module(char *realname, PyObject *path, char *buf, size_t buflen,
fdp = PyMac_FindModuleExtension(buf, &len, name);
if (fdp) {
#else
#if defined(PYOS_OS2)
/* take a snapshot of the module spec for restoration
* after the 8 character DLL hackery
*/
saved_buf = strdup(buf);
saved_len = len;
saved_namelen = namelen;
#endif /* PYOS_OS2 */
for (fdp = _PyImport_Filetab; fdp->suffix != NULL; fdp++) {
#if defined(PYOS_OS2)
/* OS/2 limits DLLs to 8 character names (w/o extension)
* so if the name is longer than that and its a
* dynamically loaded module we're going to try,
* truncate the name before trying
*/
if (strlen(realname) > 8) {
/* is this an attempt to load a C extension? */
const struct filedescr *scan = _PyImport_DynLoadFiletab;
while (scan->suffix != NULL) {
if (strcmp(scan->suffix, fdp->suffix) == 0)
break;
else
scan++;
}
if (scan->suffix != NULL) {
/* yes, so truncate the name */
namelen = 8;
len -= strlen(realname) - namelen;
buf[len] = '\0';
}
}
#endif /* PYOS_OS2 */
strcpy(buf+len, fdp->suffix);
if (Py_VerboseFlag > 1)
PySys_WriteStderr("# trying %s\n", buf);
@ -1040,7 +1076,21 @@ find_module(char *realname, PyObject *path, char *buf, size_t buflen,
fp = NULL;
}
}
#if defined(PYOS_OS2)
/* restore the saved snapshot */
strcpy(buf, saved_buf);
len = saved_len;
namelen = saved_namelen;
#endif
}
#if defined(PYOS_OS2)
/* don't need/want the module name snapshot anymore */
if (saved_buf)
{
free(saved_buf);
saved_buf = NULL;
}
#endif
if (fp != NULL)
break;
}
@ -1099,6 +1149,12 @@ find_module(char *realname, PyObject *path, char *buf, size_t buflen,
#include <sys/types.h>
#include <dirent.h>
#elif defined(PYOS_OS2)
#define INCL_DOS
#define INCL_DOSERRORS
#define INCL_NOPMAPI
#include <os2.h>
#elif defined(RISCOS)
#include "oslib/osfscontrol.h"
#endif
@ -1255,6 +1311,26 @@ case_ok(char *buf, int len, int namelen, char *name)
return 0;
/* OS/2 */
#elif defined(PYOS_OS2)
HDIR hdir = 1;
ULONG srchcnt = 1;
FILEFINDBUF3 ffbuf;
APIRET rc;
if (getenv("PYTHONCASEOK") != NULL)
return 1;
rc = DosFindFirst(buf,
&hdir,
FILE_READONLY | FILE_HIDDEN | FILE_SYSTEM | FILE_DIRECTORY,
&ffbuf, sizeof(ffbuf),
&srchcnt,
FIL_STANDARD);
if (rc != NO_ERROR)
return 0;
return strncmp(ffbuf.achName, name, namelen) == 0;
/* assuming it's a case-sensitive filesystem, so there's nothing to do! */
#else
return 1;

View File

@ -37,7 +37,7 @@ extern PyObject *_PyImport_LoadDynamicModule(char *name, char *pathname,
#include <windows.h>
typedef FARPROC dl_funcptr;
#else
#ifdef PYOS_OS2
#if defined(PYOS_OS2) && !defined(PYCC_GCC)
#include <os2def.h>
typedef int (* APIENTRY dl_funcptr)();
#else

View File

@ -7,8 +7,12 @@
#include "process.h"
#if defined(PYCC_GCC)
#include <sys/builtin.h>
#include <sys/fmutex.h>
#else
long PyThread_get_thread_ident(void);
#endif
/*
* Initialization of the C package, should not be needed.
@ -41,14 +45,20 @@ PyThread_start_new_thread(void (*func)(void *), void *arg)
long
PyThread_get_thread_ident(void)
{
#if !defined(PYCC_GCC)
PPIB pib;
PTIB tib;
#endif
if (!initialized)
PyThread_init_thread();
#if defined(PYCC_GCC)
return _gettid();
#else
DosGetInfoBlocks(&tib,&pib);
return tib->tib_ptib2->tib2_ultid;
#endif
}
static void
@ -103,7 +113,7 @@ PyThread__exit_prog(int status)
/*
* Lock support. This is implemented with an event semaphore and critical
* sections to make it behave more like a posix mutex than its OS/2
# counterparts.
* counterparts.
*/
typedef struct os2_lock_t {
@ -114,6 +124,19 @@ typedef struct os2_lock_t {
PyThread_type_lock
PyThread_allocate_lock(void)
{
#if defined(PYCC_GCC)
_fmutex *sem = malloc(sizeof(_fmutex));
if (!initialized)
PyThread_init_thread();
dprintf(("%ld: PyThread_allocate_lock() -> %lx\n",
PyThread_get_thread_ident(),
(long)sem));
if (_fmutex_create(sem, 0)) {
free(sem);
sem = NULL;
}
return (PyThread_type_lock) sem;
#else
APIRET rc;
type_os2_lock lock = (type_os2_lock)malloc(sizeof(struct os2_lock_t));
@ -130,16 +153,27 @@ PyThread_allocate_lock(void)
lock->changed));
return (PyThread_type_lock) lock;
#endif
}
void
PyThread_free_lock(PyThread_type_lock aLock)
{
#if !defined(PYCC_GCC)
type_os2_lock lock = (type_os2_lock)aLock;
#endif
dprintf(("%ld: PyThread_free_lock(%p) called\n", PyThread_get_thread_ident(),aLock));
#if defined(PYCC_GCC)
if (aLock) {
_fmutex_close((_fmutex *)aLock);
free((_fmutex *)aLock);
}
#else
DosCloseEventSem(lock->changed);
free(aLock);
#endif
}
/*
@ -150,15 +184,22 @@ PyThread_free_lock(PyThread_type_lock aLock)
int
PyThread_acquire_lock(PyThread_type_lock aLock, int waitflag)
{
#if !defined(PYCC_GCC)
int done = 0;
ULONG count;
PID pid = 0;
TID tid = 0;
type_os2_lock lock = (type_os2_lock)aLock;
#endif
dprintf(("%ld: PyThread_acquire_lock(%p, %d) called\n", PyThread_get_thread_ident(),
aLock, waitflag));
#if defined(PYCC_GCC)
/* always successful if the lock doesn't exist */
if (aLock && _fmutex_request((_fmutex *)aLock, waitflag ? 0 : _FMR_NOWAIT))
return 0;
#else
while (!done) {
/* if the lock is currently set, we have to wait for the state to change */
if (lock->is_set) {
@ -182,15 +223,23 @@ PyThread_acquire_lock(PyThread_type_lock aLock, int waitflag)
DosExitCritSec();
}
#endif
return 1;
}
void PyThread_release_lock(PyThread_type_lock aLock)
{
#if defined(PYCC_GCC)
type_os2_lock lock = (type_os2_lock)aLock;
#endif
dprintf(("%ld: PyThread_release_lock(%p) called\n", PyThread_get_thread_ident(),aLock));
#if defined(PYCC_GCC)
if (aLock)
_fmutex_release((_fmutex *)aLock);
#else
if (!lock->is_set) {
dprintf(("%ld: Could not PyThread_release_lock(%p) error: %l\n",
PyThread_get_thread_ident(), aLock, GetLastError()));
@ -208,4 +257,5 @@ void PyThread_release_lock(PyThread_type_lock aLock)
DosPostEventSem(lock->changed);
DosExitCritSec();
#endif
}