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