xref: /openbsd-src/gnu/usr.bin/perl/os2/dl_os2.c (revision 47911bd667ac77dc523b8a13ef40b012dbffa741)
1 #include "dlfcn.h"
2 #include "string.h"
3 #include "stdio.h"
4 
5 #define INCL_BASE
6 #include <os2.h>
7 
8 static ULONG retcode;
9 static char fail[300];
10 
11 char *os2error(int rc);
12 
13 void *
14 dlopen(const char *path, int mode)
15 {
16 	HMODULE handle;
17 	char tmp[260], *beg, *dot;
18 	ULONG rc;
19 
20 	fail[0] = 0;
21 	if ((rc = DosLoadModule(fail, sizeof fail, (char*)path, &handle)) == 0)
22 		return (void *)handle;
23 
24 	retcode = rc;
25 
26 	if (strlen(path) >= sizeof(tmp))
27 	    return NULL;
28 
29 	/* Not found. Check for non-FAT name and try truncated name. */
30 	/* Don't know if this helps though... */
31 	for (beg = dot = path + strlen(path);
32 	     beg > path && !strchr(":/\\", *(beg-1));
33 	     beg--)
34 		if (*beg == '.')
35 			dot = beg;
36 	if (dot - beg > 8) {
37 		int n = beg+8-path;
38 
39 		memmove(tmp, path, n);
40 		memmove(tmp+n, dot, strlen(dot)+1);
41 		if (DosLoadModule(fail, sizeof fail, tmp, &handle) == 0)
42 			return (void *)handle;
43 	}
44 
45 	return NULL;
46 }
47 
48 void *
49 dlsym(void *handle, const char *symbol)
50 {
51 	ULONG rc, type;
52 	PFN addr;
53 
54 	fail[0] = 0;
55 	rc = DosQueryProcAddr((HMODULE)handle, 0, symbol, &addr);
56 	if (rc == 0) {
57 		rc = DosQueryProcType((HMODULE)handle, 0, symbol, &type);
58 		if (rc == 0 && type == PT_32BIT)
59 			return (void *)addr;
60 		rc = ERROR_CALL_NOT_IMPLEMENTED;
61 	}
62 	retcode = rc;
63 	return NULL;
64 }
65 
66 char *
67 dlerror(void)
68 {
69 	static char buf[700];
70 	ULONG len;
71 	char *err;
72 
73 	if (retcode == 0)
74 		return NULL;
75 	err = os2error(retcode);
76 	len = strlen(err);
77 	if (len > sizeof(buf) - 1)
78 	    len = sizeof(buf) - 1;
79 	strncpy(buf, err, len+1);
80 	if (fail[0] && len < 300)
81 	    sprintf(buf + len, ", possible problematic module: '%s'", fail);
82 	retcode = 0;
83 	return buf;
84 }
85 
86 int
87 dlclose(void *handle)
88 {
89 	ULONG rc;
90 
91 	if ((rc = DosFreeModule((HMODULE)handle)) == 0) return 0;
92 
93 	retcode = rc;
94 	return 2;
95 }
96