| Ilya Zakharevich on Fri, 3 May 2002 22:06:18 -0400 |
[Date Prev] [Date Next] [Thread Prev] [Thread Next] [Date Index] [Thread Index]
| Re: [PATCH] OS/2 dynalinking |
[Continuing an old discussion]
On Tue, Mar 13, 2001 at 08:25:49PM +0100, Karim.Belabas wrote:
> but it's annoying to rename things once they have been taught to cvs. So I'd
> like to discuss a few things first. So far, for system specific stuff, PARI has
>
> 1) #define in the middle of general code [NOT a good thing, to be eliminated]
>
> 2) generic trivial wrappers: os_read, os_signal, os_getenv, ... in
> src/language/es.c, which fail automatically on some architectures (e.g
> WinCE). [Better, but not uniform]
>
> 3) Odos/pariCE.c which is only linked in the CE binary and contains a number
> of needed standard routines, trivially implemented, or in terms of the
> Windows API.
>
> Would a directory src/systems, containing e.g.
>
> os2.c unix.c winCE.c
> os2.h unix.h winCE.h
>
> each system being represented by only 2 files, be acceptable ?
I do not think this is practical if done exactly like this. E.g., the
patch in question contains dlfcn.h. Merging it in pari_os2.h would
not solve anything: one would need to surround existing `#include
<dlfcn.h>' by *additional* check for #ifndef DLFCN_ALREADY_INCLUDED or
somesuch.
And anyway, os2.h would need to duplicate (or include) unix.h.
However, the idea with os2.c is viable, so I redid the patch.
Since I did not update build tools: to use this patch *now* one needs
to manually define USE_DLOPEN, add ../src/systems/os2 to the include
path, and add os2$(_O) to the list of dependencies. Moreover, the
install() from the PARI itself works only if PARI library is in a DLL.
Enjoy,
Ilya
--- ./src/systems/os2.c.orig Fri May 3 17:22:26 2002
+++ ./src/systems/os2.c Fri May 3 17:59:36 2002
@@ -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'",
+ (int)retcode, fail);
+ else
+ sprintf(buf, "OS/2 system error code %d", (int)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.orig Fri May 3 17:22:42 2002
+++ ./src/systems/os2/dlfcn.h Fri May 3 17:22:42 2002
@@ -0,0 +1,5 @@
+#define RTLD_LAZY 1
+#define RTLD_GLOBAL 1
+void *dlopen(char *path, int mode);
+void *dlsym(void *handle, char *symbol);
+char *dlerror(void);
--- ./src/systems/os2/pari.def.base.orig Fri May 3 17:22:42 2002
+++ ./src/systems/os2/pari.def.base Fri May 3 17:22:42 2002
@@ -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