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