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