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