| Ilya Zakharevich on Wed, 7 Mar 2001 19:19:12 -0500 |
[Date Prev] [Date Next] [Thread Prev] [Thread Next] [Date Index] [Thread Index]
| [PATCH] OS/2 dynalinking |
This patch brings three new files into the distribution, dl_os2.c, dlfcn.h,
and pari.def.base. Tentatively, I put them into src/systems/os2/.
I can't update Configure to support gp-dyn and install() on OS/2 now.
Please wait. This version of dlopen() supports NULL as the name of the DLL
only partially: it will substitute the name of the DLL this dlopen was
compiled into.
Enjoy,
Ilya
--- ./src/systems/os2/dl_os2.c-pre Wed Mar 7 18:56:52 2001
+++ ./src/systems/os2/dl_os2.c Tue Mar 6 23:55:44 2001
@@ -0,0 +1,150 @@
+#include "dlfcn.h"
+
+#define INCL_BASE
+#include <os2.h>
+#include <float.h>
+
+static ULONG retcode;
+static char fail[300];
+
+static ULONG dllHandle;
+static char dllname[80];
+static int handle_found;
+static int handle_loaded;
+
+#ifdef DLOPEN_INITTERM
+unsigned long _DLL_InitTerm(unsigned long modHandle, unsigned long flag)
+{
+ switch (flag) {
+ case 0: /* INIT */
+ /* Save handle */
+ dllHandle = modHandle;
+ handle_found = 1;
+ return TRUE;
+
+ case 1: /* TERM */
+ handle_found = 0;
+ dllHandle = (unsigned long)NULLHANDLE;
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+#endif
+
+void *
+dlopen(char *path, int mode)
+{
+ HMODULE handle;
+ char tmp[260], *beg, *dot;
+ ULONG rc;
+ unsigned fpflag = _control87(0,0);
+
+ fail[0] = 0;
+ if (!path) { /* Our own handle. */
+ if (handle_found) {
+ if (handle_loaded)
+ return (void*)dllHandle;
+ rc = DosQueryModuleName(dllHandle, sizeof(dllname), dllname);
+ if (rc) {
+ strcpy(fail, "can't find my DLL name by the handle");
+ return 0;
+ }
+ rc = DosLoadModule(fail, sizeof fail, dllname, &handle);
+ if (rc) {
+ strcpy(fail, "can't load my own DLL");
+ return 0;
+ }
+ handle_loaded = 1;
+ goto ret;
+ }
+ strcpy(fail, "can't load from myself: compiled without -DDLOPEN_INITTERM");
+ return 0;
+ }
+ if ((rc = DosLoadModule(fail, sizeof fail, path, &handle)) == 0)
+ goto ret;
+
+ retcode = rc;
+
+ /* Not found. Check for non-FAT name and try truncated name. */
+ /* Don't know if this helps though... */
+ for (beg = dot = path + strlen(path);
+ beg > path && !strchr(":/\\", *(beg-1));
+ beg--)
+ if (*beg == '.')
+ dot = beg;
+ if (dot - beg > 8) {
+ int n = beg+8-path;
+ memmove(tmp, path, n);
+ memmove(tmp+n, dot, strlen(dot)+1);
+ if (DosLoadModule(fail, sizeof fail, tmp, &handle) == 0)
+ goto ret;
+ }
+ handle = 0;
+
+ ret:
+ _control87(fpflag, MCW_EM); /* Some modules reset FP flags on load */
+ return (void *)handle;
+}
+
+void *
+dlsym(void *handle, char *symbol)
+{
+ ULONG rc, type;
+ PFN addr;
+
+ fail[0] = 0;
+ rc = DosQueryProcAddr((HMODULE)handle, 0, symbol, &addr);
+ if (rc == 0) {
+ rc = DosQueryProcType((HMODULE)handle, 0, symbol, &type);
+ if (rc == 0 && type == PT_32BIT)
+ return (void *)addr;
+ rc = ERROR_CALL_NOT_IMPLEMENTED;
+ }
+ retcode = rc;
+ return NULL;
+}
+
+char *
+dlerror(void)
+{
+ static char buf[700];
+ ULONG len;
+
+ if (retcode == 0)
+ return NULL;
+ if (DosGetMessage(NULL, 0, buf, sizeof buf - 1, retcode,
+ "OSO001.MSG", &len)) {
+ if (fail[0])
+ sprintf(buf,
+"OS/2 system error code %d, possible problematic module: '%s'",
+ retcode, fail);
+ else
+ sprintf(buf, "OS/2 system error code %d", retcode);
+ } else {
+ buf[len] = '\0';
+ if (len && buf[len - 1] == '\n')
+ buf[--len] = 0;
+ if (len && buf[len - 1] == '\r')
+ buf[--len] = 0;
+ if (len && buf[len - 1] == '.')
+ buf[--len] = 0;
+ if (fail[0] && len < 300)
+ sprintf(buf + len, ", possible problematic module: '%s'",
+ fail);
+ }
+ retcode = 0;
+ return buf;
+}
+
+int
+dlclose(void *handle)
+{
+ ULONG rc;
+
+ if ((rc = DosFreeModule((HMODULE)handle)) == 0) return 0;
+
+ retcode = rc;
+ return 2;
+}
--- ./src/systems/os2/dlfcn.h-pre Wed Mar 7 18:56:52 2001
+++ ./src/systems/os2/dlfcn.h Tue Mar 6 22:30:06 2001
@@ -0,0 +1,5 @@
+#define RTLD_LAZY 1
+void *dlopen(char *path, int mode);
+void *dlsym(void *handle, char *symbol);
+char *dlerror(void);
+int dlclose(void *handle);
--- ./src/systems/os2/pari.def.base-pre Wed Mar 7 18:56:52 2001
+++ ./src/systems/os2/pari.def.base Wed Mar 7 17:57:08 2001
@@ -0,0 +1,6 @@
+LIBRARY 'pari' INITINSTANCE TERMINSTANCE
+; Can't put http://www.parigp-home.de/, since it is split on :
+DESCRIPTION '@#www.parigp-home.de/:@VERSION@#@GP/PARI compiled with @CFLAGS@
+CODE LOADONCALL
+DATA LOADONCALL NONSHARED MULTIPLE
+EXPORTS