This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
Integrate mainline
[perl5.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 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 }