symbian-qemu-0.9.1-12/python-2.6.1/PC/os2emx/dlfcn.c
changeset 1 2fb8b9db1c86
equal deleted inserted replaced
0:ffa851df0825 1:2fb8b9db1c86
       
     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 
       
    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 */
       
    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 */
       
   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 dynamicaly-linked library */
       
   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 */
       
   220 char *dlerror()
       
   221 {
       
   222 	return dlerr;
       
   223 }