blob: acf0197c3855fa463260f258ad5259509f6d02ea [file] [log] [blame]
Andrew MacIntyre41d97d62002-02-17 05:23:30 +00001/* -*- C -*- ***********************************************
2Copyright 1991-1995 by Stichting Mathematisch Centrum, Amsterdam,
3The Netherlands.
4
5 All Rights Reserved
6
7Permission to use, copy, modify, and distribute this software and its
8documentation for any purpose and without fee is hereby granted,
9provided that the above copyright notice appear in all copies and that
10both that copyright notice and this permission notice appear in
11supporting documentation, and that the names of Stichting Mathematisch
12Centrum or CWI or Corporation for National Research Initiatives or
13CNRI not be used in advertising or publicity pertaining to
14distribution of the software without specific, written prior
15permission.
16
17While CWI is the initial source for this software, a modified version
18is made available by the Corporation for National Research Initiatives
19(CNRI) at the Internet address ftp://ftp.python.org.
20
21STICHTING MATHEMATISCH CENTRUM AND CNRI DISCLAIM ALL WARRANTIES WITH
22REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
23MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH
24CENTRUM OR CNRI BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
25DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
26PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
27TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
28PERFORMANCE OF THIS SOFTWARE.
29
30******************************************************************/
31
32/*
33 This library implements dlopen() - functions for OS/2 using
34 DosLoadModule() and company.
35*/
36
37#define INCL_DOS
38#define INCL_DOSERRORS
39#define INCL_DOSSESMGR
40#define INCL_WINPROGRAMLIST
41#define INCL_WINFRAMEMGR
42#include <os2.h>
43
44#include <stdio.h>
45#include <stdlib.h>
46#include <string.h>
47#include <malloc.h>
48
49/*-------------------------------------- Unix-like dynamic linking emulation -*/
50
51typedef struct _track_rec {
52 char *name;
53 HMODULE handle;
54 void *id;
55 struct _track_rec *next;
56} tDLLchain, *DLLchain;
57
58static DLLchain dlload = NULL; /* A simple chained list of DLL names */
59static char dlerr [256]; /* last error text string */
60static void *last_id;
61
62static DLLchain find_id(void *id)
63{
64 DLLchain tmp;
65
66 for (tmp = dlload; tmp; tmp = tmp->next)
67 if (id == tmp->id)
68 return (tmp);
69
70 return (NULL);
71}
72
73/* load a dynamic-link library and return handle */
74void *dlopen (char *filename, int flags)
75{
76 HMODULE hm;
77 DLLchain tmp;
78 char err[256];
79 char *errtxt;
80 int rc = 0, set_chain = 0;
81
82 for (tmp = dlload; tmp; tmp = tmp->next)
83 if (strnicmp(tmp->name, filename, 999) == 0)
84 break;
85
86 if (!tmp)
87 {
88 tmp = (DLLchain)malloc (sizeof (tDLLchain));
89 if (!tmp)
90 goto nomem;
91 tmp->name = strdup (filename);
92 tmp->next = dlload;
93 set_chain = 1;
94 }
95
96 switch (rc = DosLoadModule((PSZ)&err, sizeof(err), filename, &hm))
97 {
98 case NO_ERROR:
99 tmp->handle = hm;
100 if (set_chain) {
101 do {
102 last_id++;
103 } while ((last_id == 0) || (find_id(last_id)));
104 tmp->id = last_id;
105 dlload = tmp;
106 }
107 return (tmp->id);
108 case ERROR_FILE_NOT_FOUND:
109 case ERROR_PATH_NOT_FOUND:
110 errtxt = "module `%s' not found";
111 break;
112 case ERROR_TOO_MANY_OPEN_FILES:
113 case ERROR_NOT_ENOUGH_MEMORY:
114 case ERROR_SHARING_BUFFER_EXCEEDED:
115nomem:
116 errtxt = "out of system resources";
117 break;
118 case ERROR_ACCESS_DENIED:
119 errtxt = "access denied";
120 break;
121 case ERROR_BAD_FORMAT:
122 case ERROR_INVALID_SEGMENT_NUMBER:
123 case ERROR_INVALID_ORDINAL:
124 case ERROR_INVALID_MODULETYPE:
125 case ERROR_INVALID_EXE_SIGNATURE:
126 case ERROR_EXE_MARKED_INVALID:
127 case ERROR_ITERATED_DATA_EXCEEDS_64K:
128 case ERROR_INVALID_MINALLOCSIZE:
129 case ERROR_INVALID_SEGDPL:
130 case ERROR_AUTODATASEG_EXCEEDS_64K:
131 case ERROR_RELOCSRC_CHAIN_EXCEEDS_SEGLIMIT:
132 errtxt = "invalid module format";
133 break;
134 case ERROR_INVALID_NAME:
135 errtxt = "filename doesn't match module name";
136 break;
137 case ERROR_SHARING_VIOLATION:
138 case ERROR_LOCK_VIOLATION:
139 errtxt = "sharing violation";
140 break;
141 case ERROR_INIT_ROUTINE_FAILED:
142 errtxt = "module initialization failed";
143 break;
144 default:
145 errtxt = "cause `%s', error code = %d";
146 break;
147 }
148 snprintf (dlerr, sizeof (dlerr), errtxt, &err, rc);
149 if (tmp) {
150 if (tmp->name)
151 free(tmp->name);
152 free (tmp);
153 }
154 return (0);
155}
156
157/* return a pointer to the `symbol' in DLL */
158void *dlsym (void *handle, char *symbol)
159{
160 int rc = 0;
161 PFN addr;
162 char *errtxt;
163 int symord = 0;
164 DLLchain tmp = find_id (handle);
165
166 if (!tmp)
167 goto inv_handle;
168
169 if (*symbol == '#')
170 symord = atoi (symbol + 1);
171
172 switch (rc = DosQueryProcAddr(tmp->handle, symord, symbol, &addr))
173 {
174 case NO_ERROR:
175 return ((void *)addr);
176 case ERROR_INVALID_HANDLE:
177inv_handle:
178 errtxt = "invalid module handle";
179 break;
180 case ERROR_PROC_NOT_FOUND:
181 case ERROR_INVALID_NAME:
182 errtxt = "no symbol `%s' in module";
183 break;
184 default:
185 errtxt = "symbol `%s', error code = %d";
186 break;
187 }
188 snprintf (dlerr, sizeof (dlerr), errtxt, symbol, rc);
189 return (NULL);
190}
191
192/* free dynamicaly-linked library */
193int dlclose (void *handle)
194{
195 int rc;
196 DLLchain tmp = find_id (handle);
197
198 if (!tmp)
199 goto inv_handle;
200
201 switch (rc = DosFreeModule (tmp->handle))
202 {
203 case NO_ERROR:
204 free (tmp->name);
205 dlload = tmp->next;
206 free (tmp);
207 return (0);
208 case ERROR_INVALID_HANDLE:
209inv_handle:
210 strcpy(dlerr, "invalid module handle");
211 return (-1);
212 case ERROR_INVALID_ACCESS:
213 strcpy (dlerr, "access denied");
214 return (-1);
215 default:
216 return (-1);
217 }
218}
219
220/* return a string describing last occured dl error */
221char *dlerror()
222{
223 return (dlerr);
224}