Skip to content

Commit d940054

Browse files
author
Andrew MacIntyre
committed
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
1 parent c487439 commit d940054

4 files changed

Lines changed: 140 additions & 3 deletions

File tree

Python/dynload_shlib.c

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,10 @@
1818

1919
#ifdef HAVE_DLFCN_H
2020
#include <dlfcn.h>
21+
#else
22+
#if defined(PYOS_OS2) && defined(PYCC_GCC)
23+
#include "dlfcn.h"
24+
#endif
2125
#endif
2226

2327
#if (defined(__OpenBSD__) || defined(__NetBSD__)) && !defined(__ELF__)
@@ -31,9 +35,14 @@ const struct filedescr _PyImport_DynLoadFiletab[] = {
3135
#ifdef __CYGWIN__
3236
{".dll", "rb", C_EXTENSION},
3337
{"module.dll", "rb", C_EXTENSION},
38+
#else
39+
#if defined(PYOS_OS2) && defined(PYCC_GCC)
40+
{".pyd", "rb", C_EXTENSION},
41+
{".dll", "rb", C_EXTENSION},
3442
#else
3543
{".so", "rb", C_EXTENSION},
3644
{"module.so", "rb", C_EXTENSION},
45+
#endif
3746
#endif
3847
{0, 0}
3948
};
@@ -82,7 +91,9 @@ dl_funcptr _PyImport_GetDynLoadFunc(const char *fqname, const char *shortname,
8291
}
8392
}
8493

94+
#if !(defined(PYOS_OS2) && defined(PYCC_GCC))
8595
dlopenflags = PyThreadState_Get()->interp->dlopenflags;
96+
#endif
8697

8798
if (Py_VerboseFlag)
8899
printf("dlopen(\"%s\", %x);\n", pathname, dlopenflags);

Python/import.c

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -900,6 +900,11 @@ find_module(char *realname, PyObject *path, char *buf, size_t buflen,
900900
static struct filedescr fd_builtin = {"", "", C_BUILTIN};
901901
static struct filedescr fd_package = {"", "", PKG_DIRECTORY};
902902
char name[MAXPATHLEN+1];
903+
#if defined(PYOS_OS2)
904+
size_t saved_len;
905+
size_t saved_namelen;
906+
char *saved_buf = NULL;
907+
#endif
903908

904909
if (strlen(realname) > MAXPATHLEN) {
905910
PyErr_SetString(PyExc_OverflowError,
@@ -1026,7 +1031,38 @@ find_module(char *realname, PyObject *path, char *buf, size_t buflen,
10261031
fdp = PyMac_FindModuleExtension(buf, &len, name);
10271032
if (fdp) {
10281033
#else
1034+
#if defined(PYOS_OS2)
1035+
/* take a snapshot of the module spec for restoration
1036+
* after the 8 character DLL hackery
1037+
*/
1038+
saved_buf = strdup(buf);
1039+
saved_len = len;
1040+
saved_namelen = namelen;
1041+
#endif /* PYOS_OS2 */
10291042
for (fdp = _PyImport_Filetab; fdp->suffix != NULL; fdp++) {
1043+
#if defined(PYOS_OS2)
1044+
/* OS/2 limits DLLs to 8 character names (w/o extension)
1045+
* so if the name is longer than that and its a
1046+
* dynamically loaded module we're going to try,
1047+
* truncate the name before trying
1048+
*/
1049+
if (strlen(realname) > 8) {
1050+
/* is this an attempt to load a C extension? */
1051+
const struct filedescr *scan = _PyImport_DynLoadFiletab;
1052+
while (scan->suffix != NULL) {
1053+
if (strcmp(scan->suffix, fdp->suffix) == 0)
1054+
break;
1055+
else
1056+
scan++;
1057+
}
1058+
if (scan->suffix != NULL) {
1059+
/* yes, so truncate the name */
1060+
namelen = 8;
1061+
len -= strlen(realname) - namelen;
1062+
buf[len] = '\0';
1063+
}
1064+
}
1065+
#endif /* PYOS_OS2 */
10301066
strcpy(buf+len, fdp->suffix);
10311067
if (Py_VerboseFlag > 1)
10321068
PySys_WriteStderr("# trying %s\n", buf);
@@ -1040,7 +1076,21 @@ find_module(char *realname, PyObject *path, char *buf, size_t buflen,
10401076
fp = NULL;
10411077
}
10421078
}
1079+
#if defined(PYOS_OS2)
1080+
/* restore the saved snapshot */
1081+
strcpy(buf, saved_buf);
1082+
len = saved_len;
1083+
namelen = saved_namelen;
1084+
#endif
1085+
}
1086+
#if defined(PYOS_OS2)
1087+
/* don't need/want the module name snapshot anymore */
1088+
if (saved_buf)
1089+
{
1090+
free(saved_buf);
1091+
saved_buf = NULL;
10431092
}
1093+
#endif
10441094
if (fp != NULL)
10451095
break;
10461096
}
@@ -1099,6 +1149,12 @@ find_module(char *realname, PyObject *path, char *buf, size_t buflen,
10991149
#include <sys/types.h>
11001150
#include <dirent.h>
11011151

1152+
#elif defined(PYOS_OS2)
1153+
#define INCL_DOS
1154+
#define INCL_DOSERRORS
1155+
#define INCL_NOPMAPI
1156+
#include <os2.h>
1157+
11021158
#elif defined(RISCOS)
11031159
#include "oslib/osfscontrol.h"
11041160
#endif
@@ -1255,6 +1311,26 @@ case_ok(char *buf, int len, int namelen, char *name)
12551311

12561312
return 0;
12571313

1314+
/* OS/2 */
1315+
#elif defined(PYOS_OS2)
1316+
HDIR hdir = 1;
1317+
ULONG srchcnt = 1;
1318+
FILEFINDBUF3 ffbuf;
1319+
APIRET rc;
1320+
1321+
if (getenv("PYTHONCASEOK") != NULL)
1322+
return 1;
1323+
1324+
rc = DosFindFirst(buf,
1325+
&hdir,
1326+
FILE_READONLY | FILE_HIDDEN | FILE_SYSTEM | FILE_DIRECTORY,
1327+
&ffbuf, sizeof(ffbuf),
1328+
&srchcnt,
1329+
FIL_STANDARD);
1330+
if (rc != NO_ERROR)
1331+
return 0;
1332+
return strncmp(ffbuf.achName, name, namelen) == 0;
1333+
12581334
/* assuming it's a case-sensitive filesystem, so there's nothing to do! */
12591335
#else
12601336
return 1;

Python/importdl.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ extern PyObject *_PyImport_LoadDynamicModule(char *name, char *pathname,
3737
#include <windows.h>
3838
typedef FARPROC dl_funcptr;
3939
#else
40-
#ifdef PYOS_OS2
40+
#if defined(PYOS_OS2) && !defined(PYCC_GCC)
4141
#include <os2def.h>
4242
typedef int (* APIENTRY dl_funcptr)();
4343
#else

Python/thread_os2.h

Lines changed: 52 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,12 @@
77

88
#include "process.h"
99

10+
#if defined(PYCC_GCC)
11+
#include <sys/builtin.h>
12+
#include <sys/fmutex.h>
13+
#else
1014
long PyThread_get_thread_ident(void);
11-
15+
#endif
1216

1317
/*
1418
* Initialization of the C package, should not be needed.
@@ -41,14 +45,20 @@ PyThread_start_new_thread(void (*func)(void *), void *arg)
4145
long
4246
PyThread_get_thread_ident(void)
4347
{
48+
#if !defined(PYCC_GCC)
4449
PPIB pib;
4550
PTIB tib;
51+
#endif
4652

4753
if (!initialized)
4854
PyThread_init_thread();
4955

56+
#if defined(PYCC_GCC)
57+
return _gettid();
58+
#else
5059
DosGetInfoBlocks(&tib,&pib);
5160
return tib->tib_ptib2->tib2_ultid;
61+
#endif
5262
}
5363

5464
static void
@@ -103,7 +113,7 @@ PyThread__exit_prog(int status)
103113
/*
104114
* Lock support. This is implemented with an event semaphore and critical
105115
* sections to make it behave more like a posix mutex than its OS/2
106-
# counterparts.
116+
* counterparts.
107117
*/
108118

109119
typedef struct os2_lock_t {
@@ -114,6 +124,19 @@ typedef struct os2_lock_t {
114124
PyThread_type_lock
115125
PyThread_allocate_lock(void)
116126
{
127+
#if defined(PYCC_GCC)
128+
_fmutex *sem = malloc(sizeof(_fmutex));
129+
if (!initialized)
130+
PyThread_init_thread();
131+
dprintf(("%ld: PyThread_allocate_lock() -> %lx\n",
132+
PyThread_get_thread_ident(),
133+
(long)sem));
134+
if (_fmutex_create(sem, 0)) {
135+
free(sem);
136+
sem = NULL;
137+
}
138+
return (PyThread_type_lock) sem;
139+
#else
117140
APIRET rc;
118141
type_os2_lock lock = (type_os2_lock)malloc(sizeof(struct os2_lock_t));
119142

@@ -130,16 +153,27 @@ PyThread_allocate_lock(void)
130153
lock->changed));
131154

132155
return (PyThread_type_lock) lock;
156+
#endif
133157
}
134158

135159
void
136160
PyThread_free_lock(PyThread_type_lock aLock)
137161
{
162+
#if !defined(PYCC_GCC)
138163
type_os2_lock lock = (type_os2_lock)aLock;
164+
#endif
165+
139166
dprintf(("%ld: PyThread_free_lock(%p) called\n", PyThread_get_thread_ident(),aLock));
140167

168+
#if defined(PYCC_GCC)
169+
if (aLock) {
170+
_fmutex_close((_fmutex *)aLock);
171+
free((_fmutex *)aLock);
172+
}
173+
#else
141174
DosCloseEventSem(lock->changed);
142175
free(aLock);
176+
#endif
143177
}
144178

145179
/*
@@ -150,15 +184,22 @@ PyThread_free_lock(PyThread_type_lock aLock)
150184
int
151185
PyThread_acquire_lock(PyThread_type_lock aLock, int waitflag)
152186
{
187+
#if !defined(PYCC_GCC)
153188
int done = 0;
154189
ULONG count;
155190
PID pid = 0;
156191
TID tid = 0;
157192
type_os2_lock lock = (type_os2_lock)aLock;
193+
#endif
158194

159195
dprintf(("%ld: PyThread_acquire_lock(%p, %d) called\n", PyThread_get_thread_ident(),
160196
aLock, waitflag));
161197

198+
#if defined(PYCC_GCC)
199+
/* always successful if the lock doesn't exist */
200+
if (aLock && _fmutex_request((_fmutex *)aLock, waitflag ? 0 : _FMR_NOWAIT))
201+
return 0;
202+
#else
162203
while (!done) {
163204
/* if the lock is currently set, we have to wait for the state to change */
164205
if (lock->is_set) {
@@ -182,15 +223,23 @@ PyThread_acquire_lock(PyThread_type_lock aLock, int waitflag)
182223

183224
DosExitCritSec();
184225
}
226+
#endif
185227

186228
return 1;
187229
}
188230

189231
void PyThread_release_lock(PyThread_type_lock aLock)
190232
{
233+
#if defined(PYCC_GCC)
191234
type_os2_lock lock = (type_os2_lock)aLock;
235+
#endif
236+
192237
dprintf(("%ld: PyThread_release_lock(%p) called\n", PyThread_get_thread_ident(),aLock));
193238

239+
#if defined(PYCC_GCC)
240+
if (aLock)
241+
_fmutex_release((_fmutex *)aLock);
242+
#else
194243
if (!lock->is_set) {
195244
dprintf(("%ld: Could not PyThread_release_lock(%p) error: %l\n",
196245
PyThread_get_thread_ident(), aLock, GetLastError()));
@@ -208,4 +257,5 @@ void PyThread_release_lock(PyThread_type_lock aLock)
208257
DosPostEventSem(lock->changed);
209258

210259
DosExitCritSec();
260+
#endif
211261
}

0 commit comments

Comments
 (0)