This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
[perl #22127] get(av|cv|hv|sv) added to Devel::PPPort
[perl5.git] / os2 / dl_os2.c
CommitLineData
c692d670 1#include "dlfcn.h"
2d766320
IZ
2#include "string.h"
3#include "stdio.h"
c692d670 4
5#define INCL_BASE
6#include <os2.h>
7
8static ULONG retcode;
ed344e4f 9static char fail[300];
c692d670 10
5c728af0
IZ
11#ifdef PERL_CORE
12
13#include "EXTERN.h"
14#include "perl.h"
15
16#else
17
9fed8b87
IZ
18char *os2error(int rc);
19
5c728af0
IZ
20#endif
21
c692d670 22void *
35bc1fdc 23dlopen(const char *path, int mode)
c692d670 24{
25 HMODULE handle;
5c728af0
IZ
26 char tmp[260];
27 const char *beg, *dot;
c692d670 28 ULONG rc;
29
ed344e4f 30 fail[0] = 0;
35bc1fdc 31 if ((rc = DosLoadModule(fail, sizeof fail, (char*)path, &handle)) == 0)
c692d670 32 return (void *)handle;
33
34 retcode = rc;
35
35bc1fdc
IZ
36 if (strlen(path) >= sizeof(tmp))
37 return NULL;
38
c692d670 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;
35bc1fdc 48
c692d670 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
58void *
35bc1fdc 59dlsym(void *handle, const char *symbol)
c692d670 60{
61 ULONG rc, type;
62 PFN addr;
63
ed344e4f 64 fail[0] = 0;
c692d670 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
76char *
77dlerror(void)
78{
ed344e4f 79 static char buf[700];
c692d670 80 ULONG len;
9fed8b87 81 char *err;
c692d670 82
83 if (retcode == 0)
84 return NULL;
9fed8b87
IZ
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);
c692d670 92 retcode = 0;
93 return buf;
94}
95
403d6f8e
GS
96int
97dlclose(void *handle)
98{
99 ULONG rc;
100
101 if ((rc = DosFreeModule((HMODULE)handle)) == 0) return 0;
102
103 retcode = rc;
104 return 2;
105}