Home | History | Annotate | Download | only in os2emx
      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 dynamically-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 }
    224