blob: 9e88d5e7387eee0d2ca932bb18111bfbc251b9af [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
Andrew MacIntyre0c833482003-04-22 03:21:42 +000032/* This library implements dlopen() - Unix-like dynamic linking
33 * emulation functions for OS/2 using DosLoadModule() and company.
34 */
Andrew MacIntyre41d97d62002-02-17 05:23:30 +000035
36#define INCL_DOS
37#define INCL_DOSERRORS
38#define INCL_DOSSESMGR
39#define INCL_WINPROGRAMLIST
40#define INCL_WINFRAMEMGR
41#include <os2.h>
42
43#include <stdio.h>
44#include <stdlib.h>
45#include <string.h>
46#include <malloc.h>
47
Andrew MacIntyre41d97d62002-02-17 05:23:30 +000048typedef struct _track_rec {
49 char *name;
50 HMODULE handle;
51 void *id;
52 struct _track_rec *next;
53} tDLLchain, *DLLchain;
54
Andrew MacIntyre0c833482003-04-22 03:21:42 +000055static DLLchain dlload = NULL; /* A simple chained list of DLL names */
56static char dlerr [256]; /* last error text string */
Andrew MacIntyre41d97d62002-02-17 05:23:30 +000057static void *last_id;
58
59static DLLchain find_id(void *id)
60{
61 DLLchain tmp;
62
63 for (tmp = dlload; tmp; tmp = tmp->next)
64 if (id == tmp->id)
Andrew MacIntyre0c833482003-04-22 03:21:42 +000065 return tmp;
Andrew MacIntyre41d97d62002-02-17 05:23:30 +000066
Andrew MacIntyre0c833482003-04-22 03:21:42 +000067 return NULL;
Andrew MacIntyre41d97d62002-02-17 05:23:30 +000068}
69
70/* load a dynamic-link library and return handle */
Andrew MacIntyre0c833482003-04-22 03:21:42 +000071void *dlopen(char *filename, int flags)
Andrew MacIntyre41d97d62002-02-17 05:23:30 +000072{
73 HMODULE hm;
74 DLLchain tmp;
75 char err[256];
76 char *errtxt;
77 int rc = 0, set_chain = 0;
78
79 for (tmp = dlload; tmp; tmp = tmp->next)
80 if (strnicmp(tmp->name, filename, 999) == 0)
81 break;
82
83 if (!tmp)
84 {
Andrew MacIntyre0c833482003-04-22 03:21:42 +000085 tmp = (DLLchain) malloc(sizeof(tDLLchain));
Andrew MacIntyre41d97d62002-02-17 05:23:30 +000086 if (!tmp)
87 goto nomem;
Andrew MacIntyre0c833482003-04-22 03:21:42 +000088 tmp->name = strdup(filename);
Andrew MacIntyre41d97d62002-02-17 05:23:30 +000089 tmp->next = dlload;
90 set_chain = 1;
91 }
92
93 switch (rc = DosLoadModule((PSZ)&err, sizeof(err), filename, &hm))
94 {
95 case NO_ERROR:
96 tmp->handle = hm;
Andrew MacIntyre0c833482003-04-22 03:21:42 +000097 if (set_chain)
98 {
99 do
Andrew MacIntyre41d97d62002-02-17 05:23:30 +0000100 last_id++;
Andrew MacIntyre0c833482003-04-22 03:21:42 +0000101 while ((last_id == 0) || (find_id(last_id)));
Andrew MacIntyre41d97d62002-02-17 05:23:30 +0000102 tmp->id = last_id;
103 dlload = tmp;
104 }
Andrew MacIntyre0c833482003-04-22 03:21:42 +0000105 return tmp->id;
Andrew MacIntyre41d97d62002-02-17 05:23:30 +0000106 case ERROR_FILE_NOT_FOUND:
107 case ERROR_PATH_NOT_FOUND:
108 errtxt = "module `%s' not found";
109 break;
110 case ERROR_TOO_MANY_OPEN_FILES:
111 case ERROR_NOT_ENOUGH_MEMORY:
112 case ERROR_SHARING_BUFFER_EXCEEDED:
113nomem:
114 errtxt = "out of system resources";
115 break;
116 case ERROR_ACCESS_DENIED:
117 errtxt = "access denied";
118 break;
119 case ERROR_BAD_FORMAT:
120 case ERROR_INVALID_SEGMENT_NUMBER:
121 case ERROR_INVALID_ORDINAL:
122 case ERROR_INVALID_MODULETYPE:
123 case ERROR_INVALID_EXE_SIGNATURE:
124 case ERROR_EXE_MARKED_INVALID:
125 case ERROR_ITERATED_DATA_EXCEEDS_64K:
126 case ERROR_INVALID_MINALLOCSIZE:
127 case ERROR_INVALID_SEGDPL:
128 case ERROR_AUTODATASEG_EXCEEDS_64K:
129 case ERROR_RELOCSRC_CHAIN_EXCEEDS_SEGLIMIT:
130 errtxt = "invalid module format";
131 break;
132 case ERROR_INVALID_NAME:
133 errtxt = "filename doesn't match module name";
134 break;
135 case ERROR_SHARING_VIOLATION:
136 case ERROR_LOCK_VIOLATION:
137 errtxt = "sharing violation";
138 break;
139 case ERROR_INIT_ROUTINE_FAILED:
140 errtxt = "module initialization failed";
141 break;
142 default:
143 errtxt = "cause `%s', error code = %d";
144 break;
145 }
Andrew MacIntyre0c833482003-04-22 03:21:42 +0000146 snprintf(dlerr, sizeof(dlerr), errtxt, &err, rc);
147 if (tmp)
148 {
Andrew MacIntyre41d97d62002-02-17 05:23:30 +0000149 if (tmp->name)
150 free(tmp->name);
Andrew MacIntyre0c833482003-04-22 03:21:42 +0000151 free(tmp);
Andrew MacIntyre41d97d62002-02-17 05:23:30 +0000152 }
Andrew MacIntyre0c833482003-04-22 03:21:42 +0000153 return 0;
Andrew MacIntyre41d97d62002-02-17 05:23:30 +0000154}
155
156/* return a pointer to the `symbol' in DLL */
Andrew MacIntyre0c833482003-04-22 03:21:42 +0000157void *dlsym(void *handle, char *symbol)
Andrew MacIntyre41d97d62002-02-17 05:23:30 +0000158{
159 int rc = 0;
160 PFN addr;
161 char *errtxt;
162 int symord = 0;
Andrew MacIntyre0c833482003-04-22 03:21:42 +0000163 DLLchain tmp = find_id(handle);
Andrew MacIntyre41d97d62002-02-17 05:23:30 +0000164
165 if (!tmp)
166 goto inv_handle;
167
168 if (*symbol == '#')
Andrew MacIntyre0c833482003-04-22 03:21:42 +0000169 symord = atoi(symbol + 1);
Andrew MacIntyre41d97d62002-02-17 05:23:30 +0000170
171 switch (rc = DosQueryProcAddr(tmp->handle, symord, symbol, &addr))
172 {
173 case NO_ERROR:
Andrew MacIntyre0c833482003-04-22 03:21:42 +0000174 return (void *)addr;
Andrew MacIntyre41d97d62002-02-17 05:23:30 +0000175 case ERROR_INVALID_HANDLE:
176inv_handle:
177 errtxt = "invalid module handle";
178 break;
179 case ERROR_PROC_NOT_FOUND:
180 case ERROR_INVALID_NAME:
181 errtxt = "no symbol `%s' in module";
182 break;
183 default:
184 errtxt = "symbol `%s', error code = %d";
185 break;
186 }
Andrew MacIntyre0c833482003-04-22 03:21:42 +0000187 snprintf(dlerr, sizeof(dlerr), errtxt, symbol, rc);
188 return NULL;
Andrew MacIntyre41d97d62002-02-17 05:23:30 +0000189}
190
191/* free dynamicaly-linked library */
Andrew MacIntyre0c833482003-04-22 03:21:42 +0000192int dlclose(void *handle)
Andrew MacIntyre41d97d62002-02-17 05:23:30 +0000193{
194 int rc;
Andrew MacIntyre0c833482003-04-22 03:21:42 +0000195 DLLchain tmp = find_id(handle);
Andrew MacIntyre41d97d62002-02-17 05:23:30 +0000196
197 if (!tmp)
198 goto inv_handle;
199
Andrew MacIntyre0c833482003-04-22 03:21:42 +0000200 switch (rc = DosFreeModule(tmp->handle))
Andrew MacIntyre41d97d62002-02-17 05:23:30 +0000201 {
202 case NO_ERROR:
Andrew MacIntyre0c833482003-04-22 03:21:42 +0000203 free(tmp->name);
Andrew MacIntyre41d97d62002-02-17 05:23:30 +0000204 dlload = tmp->next;
Andrew MacIntyre0c833482003-04-22 03:21:42 +0000205 free(tmp);
206 return 0;
Andrew MacIntyre41d97d62002-02-17 05:23:30 +0000207 case ERROR_INVALID_HANDLE:
208inv_handle:
209 strcpy(dlerr, "invalid module handle");
Andrew MacIntyre0c833482003-04-22 03:21:42 +0000210 return -1;
Andrew MacIntyre41d97d62002-02-17 05:23:30 +0000211 case ERROR_INVALID_ACCESS:
Andrew MacIntyre0c833482003-04-22 03:21:42 +0000212 strcpy(dlerr, "access denied");
213 return -1;
Andrew MacIntyre41d97d62002-02-17 05:23:30 +0000214 default:
Andrew MacIntyre0c833482003-04-22 03:21:42 +0000215 return -1;
Andrew MacIntyre41d97d62002-02-17 05:23:30 +0000216 }
217}
218
Fred Drakedb390c12005-10-28 14:39:47 +0000219/* return a string describing last occurred dl error */
Andrew MacIntyre41d97d62002-02-17 05:23:30 +0000220char *dlerror()
221{
Andrew MacIntyre0c833482003-04-22 03:21:42 +0000222 return dlerr;
Andrew MacIntyre41d97d62002-02-17 05:23:30 +0000223}