• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* -*- C -*- ***********************************************
2 Copyright 1991-1995 by Stichting Mathematisch Centrum, Amsterdam,
3 The Netherlands.
4 
5                         All Rights Reserved
6 
7 Permission to use, copy, modify, and distribute this software and its
8 documentation for any purpose and without fee is hereby granted,
9 provided that the above copyright notice appear in all copies and that
10 both that copyright notice and this permission notice appear in
11 supporting documentation, and that the names of Stichting Mathematisch
12 Centrum or CWI or Corporation for National Research Initiatives or
13 CNRI not be used in advertising or publicity pertaining to
14 distribution of the software without specific, written prior
15 permission.
16 
17 While CWI is the initial source for this software, a modified version
18 is made available by the Corporation for National Research Initiatives
19 (CNRI) at the Internet address ftp://ftp.python.org.
20 
21 STICHTING MATHEMATISCH CENTRUM AND CNRI DISCLAIM ALL WARRANTIES WITH
22 REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
23 MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH
24 CENTRUM OR CNRI BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
25 DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
26 PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
27 TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
28 PERFORMANCE OF THIS SOFTWARE.
29 
30 ******************************************************************/
31 
32 /* This library implements dlopen() - Unix-like dynamic linking
33  * emulation functions for OS/2 using DosLoadModule() and company.
34  */
35 
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 
48 typedef struct _track_rec {
49     char *name;
50     HMODULE handle;
51     void *id;
52     struct _track_rec *next;
53 } tDLLchain, *DLLchain;
54 
55 static DLLchain dlload = NULL;  /* A simple chained list of DLL names */
56 static char dlerr [256];        /* last error text string */
57 static void *last_id;
58 
find_id(void * id)59 static DLLchain find_id(void *id)
60 {
61     DLLchain tmp;
62 
63     for (tmp = dlload; tmp; tmp = tmp->next)
64         if (id == tmp->id)
65             return tmp;
66 
67     return NULL;
68 }
69 
70 /* load a dynamic-link library and return handle */
dlopen(char * filename,int flags)71 void *dlopen(char *filename, int flags)
72 {
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     {
85         tmp = (DLLchain) malloc(sizeof(tDLLchain));
86         if (!tmp)
87             goto nomem;
88         tmp->name = strdup(filename);
89         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;
97             if (set_chain)
98             {
99                 do
100                     last_id++;
101                 while ((last_id == 0) || (find_id(last_id)));
102                 tmp->id = last_id;
103                 dlload = tmp;
104             }
105             return tmp->id;
106         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:
113 nomem:
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     }
146     snprintf(dlerr, sizeof(dlerr), errtxt, &err, rc);
147     if (tmp)
148     {
149         if (tmp->name)
150             free(tmp->name);
151         free(tmp);
152     }
153     return 0;
154 }
155 
156 /* return a pointer to the `symbol' in DLL */
dlsym(void * handle,char * symbol)157 void *dlsym(void *handle, char *symbol)
158 {
159     int rc = 0;
160     PFN addr;
161     char *errtxt;
162     int symord = 0;
163     DLLchain tmp = find_id(handle);
164 
165     if (!tmp)
166         goto inv_handle;
167 
168     if (*symbol == '#')
169         symord = atoi(symbol + 1);
170 
171     switch (rc = DosQueryProcAddr(tmp->handle, symord, symbol, &addr))
172     {
173         case NO_ERROR:
174             return (void *)addr;
175         case ERROR_INVALID_HANDLE:
176 inv_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     }
187     snprintf(dlerr, sizeof(dlerr), errtxt, symbol, rc);
188     return NULL;
189 }
190 
191 /* free dynamically-linked library */
dlclose(void * handle)192 int dlclose(void *handle)
193 {
194     int rc;
195     DLLchain tmp = find_id(handle);
196 
197     if (!tmp)
198         goto inv_handle;
199 
200     switch (rc = DosFreeModule(tmp->handle))
201     {
202         case NO_ERROR:
203             free(tmp->name);
204             dlload = tmp->next;
205             free(tmp);
206             return 0;
207         case ERROR_INVALID_HANDLE:
208 inv_handle:
209             strcpy(dlerr, "invalid module handle");
210             return -1;
211         case ERROR_INVALID_ACCESS:
212             strcpy(dlerr, "access denied");
213             return -1;
214         default:
215             return -1;
216     }
217 }
218 
219 /* return a string describing last occurred dl error */
dlerror()220 char *dlerror()
221 {
222     return dlerr;
223 }
224