X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/1a6944fd74cfb70ace96d60bde31a7c8e0a5896d..8354aa92a177f27ebe55869ecc254e1f6da05331:/src/iodbc/dlf.c diff --git a/src/iodbc/dlf.c b/src/iodbc/dlf.c index 5745f8f07e..46cf232907 100644 --- a/src/iodbc/dlf.c +++ b/src/iodbc/dlf.c @@ -1,30 +1,39 @@ -/** dynamic library loader (mapping to svr4) - - Copyright (C) 1995 by Ke Jin - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. -**/ - -#include "wx/setup.h" +/* + * dlf.c + * + * $Id$ + * + * Dynamic Library Loader (mapping to SVR4) + * + * The iODBC driver manager. + * + * Copyright (C) 1995 by Ke Jin + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free + * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ -#include <../iodbc/dlf.h> +#include "dlf.h" #include -#ifdef DLDAPI_DEFINED -# undef DLDAPI_DEFINED +#ifdef DLDAPI_DEFINED +#undef DLDAPI_DEFINED #endif -#ifdef DLDAPI_SVR4_DLFCN -# define DLDAPI_DEFINED -static char sccsid[] = "@(#)dynamic load interface -- SVR4 dlfcn"; +#ifdef DLDAPI_SVR4_DLFCN +#define DLDAPI_DEFINED +static char sccsid[] = "@(#)dynamic load interface -- SVR4 dlfcn"; #endif /********************************* @@ -32,63 +41,72 @@ static char sccsid[] = "@(#)dynamic load interface -- SVR4 dlfcn"; * HP/UX * *********************************/ + #ifdef DLDAPI_HP_SHL -# define DLDAPI_DEFINED -# include +#define DLDAPI_DEFINED +#include -static char sccsid[] = "@(#)dynamic load interface -- HP/UX dl(shl)"; +static char sccsid[] = "@(#)dynamic load interface -- HP/UX dl(shl)"; -void* dlopen(char* path, int mode) +void * +dlopen (char *path, int mode) { - return (void*)shl_load((char*)(path), BIND_DEFERRED, 0L); + return (void *) shl_load ((char *) (path), BIND_DEFERRED, 0L); } -void* dlsym(void* hdll, char* sym) + +void * +dlsym (void *hdll, char *sym) { - void* symaddr = 0; - int ret; + void *symaddr = 0; + int ret; - if( ! hdll ) - hdll = (void*)PROG_HANDLE; + if (!hdll) + hdll = (void *) PROG_HANDLE; - /* Remember, a driver may export calls as function pointers - * (i.e. with type TYPE_DATA) rather than as functions - * (i.e. with type TYPE_PROCEDURE). Thus, to be safe, we - * uses TYPE_UNDEFINED to cover all of them. - */ - ret = shl_findsym((shl_t*)&hdll, sym, TYPE_UNDEFINED, &symaddr); + /* Remember, a driver may export calls as function pointers + * (i.e. with type TYPE_DATA) rather than as functions + * (i.e. with type TYPE_PROCEDURE). Thus, to be safe, we + * uses TYPE_UNDEFINED to cover all of them. + */ + ret = shl_findsym ((shl_t *) & hdll, sym, TYPE_UNDEFINED, &symaddr); - if( ret == -1 ) - return 0; + if (ret == -1) + return 0; - return symaddr; + return symaddr; } -char* dlerror() + +char * +dlerror () { - extern char* strerror(); + extern char *strerror (); - return strerror(errno); + return strerror (errno); } -int dlclose(void* hdll) + +int +dlclose (void *hdll) { - return shl_unload((shl_t)hdll); + return shl_unload ((shl_t) hdll); } +#endif /* end of HP/UX Seection */ -#endif /* end of HP/UX Seection */ /********************************* * * IBM AIX * *********************************/ + #ifdef DLDAPI_AIX_LOAD -# define DLDAPI_DEFINED -# include -# include -# include -# include +#define DLDAPI_DEFINED +#include +#include +#include +#include /* * Following id sting is a copyright mark. Removing(i.e. use the @@ -97,25 +115,26 @@ int dlclose(void* hdll) * it without permission from original author(kejin@empress.com) * are copyright violation. */ -static char sccsid[] - = "@(#)dynamic load interface, Copyright(c) 1995 by Ke Jin"; +static char sccsid[] += "@(#)dynamic load interface, Copyright(c) 1995 by Ke Jin"; -# ifndef HTAB_SIZE -# define HTAB_SIZE 256 -# endif +#ifndef HTAB_SIZE +#define HTAB_SIZE 256 +#endif -# define FACTOR 0.618039887 /* i.e. (sqrt(5) - 1)/2 */ +#define FACTOR 0.618039887 /* i.e. (sqrt(5) - 1)/2 */ -# ifndef ENTRY_SYM -# define ENTRY_SYM ".__start" /* default entry point for aix */ -# endif +#ifndef ENTRY_SYM +#define ENTRY_SYM ".__start" /* default entry point for aix */ +#endif typedef struct slot_s -{ - char* sym; - long fdesc[3]; /* 12 bytes function descriptor */ - struct slot_s* next; -} slot_t; + { + char *sym; + long fdesc[3]; /* 12 bytes function descriptor */ + struct slot_s *next; + } +slot_t; /* Note: on AIX, a function pointer actually points to a * function descriptor, a 12 bytes data. The first 4 bytes @@ -136,393 +155,382 @@ typedef struct slot_s * the module library file). */ -typedef slot_t* hent_t; -typedef struct nlist nlist_t; -typedef struct stat stat_t; - -typedef struct obj -{ - int dev; /* device id */ - int ino; /* inode number */ - char* path; /* file name */ - int (*pentry)(); /* entry point of this share library */ - int refn; /* number of reference */ - hent_t htab[HTAB_SIZE]; - struct obj* - next; -} obj_t; - -static char* errmsg = 0; - -static void init_htab(hent_t* ht) +typedef slot_t *hent_t; +typedef struct nlist nlist_t; +typedef struct stat stat_t; + +typedef struct obj + { + int dev; /* device id */ + int ino; /* inode number */ + char *path; /* file name */ + int (*pentry) (); /* entry point of this share library */ + int refn; /* number of reference */ + hent_t htab[HTAB_SIZE]; + struct obj * next; + } +obj_t; + +static char *errmsg = 0; + +static void +init_htab (hent_t * ht) /* initate a hashing table */ { - int i; + int i; - for(i=0; inext; - - free(ent->sym); - free(ent); + tent = ent->next; - ent = tent; - } + free (ent->sym); + free (ent); - ht[i] = 0; + ent = tent; } - return; + ht[i] = 0; + } + + return; } -static int hash(char* sym ) + +static int +hash (char *sym) { - int a, key; - double f; + int a, key; + double f; - if( !sym || !*sym ) - return 0; + if (!sym || !*sym) + return 0; - for(key=*sym;*sym;sym++) - { - key += *sym; - a = key; + for (key = *sym; *sym; sym++) + { + key += *sym; + a = key; - key = (int)( (a<<8) + (key>>8) ); - key = (key>0)? key:-key; - } + key = (int) ((a << 8) + (key >> 8)); + key = (key > 0) ? key : -key; + } - f = key*FACTOR; - a = (int)f; + f = key * FACTOR; + a = (int) f; - return (int)((HTAB_SIZE - 1)*( f - a )); + return (int) ((HTAB_SIZE - 1) * (f - a)); } -static hent_t search(hent_t* htab, char* sym) + +static hent_t +search (hent_t * htab, char *sym) /* search hashing table to find a matched slot */ { - int key; - slot_t* ent; + int key; + slot_t *ent; - key = hash(sym); + key = hash (sym); - for(ent = htab[key]; ent; ent = ent->next ) - { - if(!strcmp(ent->sym, sym)) - return ent; - } + for (ent = htab[key]; ent; ent = ent->next) + { + if (!strcmp (ent->sym, sym)) + return ent; + } - return 0; /* no match */ + return 0; /* no match */ } -static void insert(hent_t* htab, slot_t* ent) + +static void +insert (hent_t * htab, slot_t * ent) /* insert a new slot to hashing table */ { - int key; + int key; - key = hash(ent->sym); + key = hash (ent->sym); - ent->next = htab[key]; - htab[key] = ent; + ent->next = htab[key]; + htab[key] = ent; - return; + return; } -static slot_t* slot_alloc(char* sym) + +static slot_t * +slot_alloc (char *sym) /* allocate a new slot with symbol */ { - slot_t* ent; + slot_t *ent; - ent = (slot_t*)malloc(sizeof(slot_t)); + ent = (slot_t *) malloc (sizeof (slot_t)); - ent->sym = (char*)malloc(strlen(sym)+1); + ent->sym = (char *) malloc (strlen (sym) + 1); - if( ! ent->sym ) - { - free(ent); - return 0; - } + if (!ent->sym) + { + free (ent); + return 0; + } - strcpy( ent->sym, sym ); + strcpy (ent->sym, sym); - return ent; + return ent; } -static obj_t* obj_list = 0; -void* dlopen(char* file, int mode ) -{ - stat_t st; - obj_t* pobj; - char buf[1024]; - - if( ! file || ! *file ) - { - errno = EINVAL; - return 0; - } - - errno = 0; - errmsg = 0; - -#if 0 - if( file[0] != '/' && file[0] != '.' ) - { - for(;;) - { - sprintf(buf, "/lib/%s", file); - - if( stat( buf, &st ) ) - { - file = buf; - break; - } - - sprintf(buf, "/usr/lib/%s", file); - - if( stat( buf, &st ) ) - { - file = buf; - break; - } - - if( stat( file, &st ) ) - break; - - return 0; - } - } - else -#endif - if( stat( file, &st ) ) - return 0; +static obj_t *obj_list = 0; - for( pobj = obj_list; pobj; pobj = pobj->next ) - /* find a match object */ +void * +dlopen (char *file, int mode) +{ + stat_t st; + obj_t *pobj; + char buf[1024]; + + if (!file || !*file) + { + errno = EINVAL; + return 0; + } + + errno = 0; + errmsg = 0; + + if (stat (file, &st)) + return 0; + + for (pobj = obj_list; pobj; pobj = pobj->next) + /* find a match object */ + { + if (pobj->ino == st.st_ino + && pobj->dev == st.st_dev) { - if( pobj->ino == st.st_ino - && pobj->dev == st.st_dev ) - { - /* found a match. increase its - * reference count and return - * its address */ - pobj->refn ++; - return pobj; - } + /* found a match. increase its + * reference count and return + * its address */ + pobj->refn++; + return pobj; } + } - pobj = (obj_t*)malloc( sizeof(obj_t) ); + pobj = (obj_t *) malloc (sizeof (obj_t)); - if( ! pobj ) - return 0; + if (!pobj) + return 0; - pobj->path = (char*)malloc( strlen(file) + 1); + pobj->path = (char *) malloc (strlen (file) + 1); - if( ! pobj->path ) - { - free( pobj ); - return 0; - } + if (!pobj->path) + { + free (pobj); + return 0; + } - strcpy( pobj->path, file ); + strcpy (pobj->path, file); - pobj->dev = st.st_dev; - pobj->ino = st.st_ino; - pobj->refn = 1; + pobj->dev = st.st_dev; + pobj->ino = st.st_ino; + pobj->refn = 1; - pobj->pentry = (int(*)())load(file, 0, 0); + pobj->pentry = (int (*)()) load (file, 0, 0); - if( ! pobj->pentry ) - { - free( pobj->path ); - free( pobj ); - return 0; - } + if (!pobj->pentry) + { + free (pobj->path); + free (pobj); + return 0; + } - init_htab(pobj->htab); + init_htab (pobj->htab); - pobj->next = obj_list; - obj_list = pobj; + pobj->next = obj_list; + obj_list = pobj; - return pobj; + return pobj; } -int dlclose(void* hobj) + +int +dlclose (void *hobj) { - obj_t* pobj = (obj_t*)hobj; - obj_t* tpobj; - int match = 0; + obj_t *pobj = (obj_t *) hobj; + obj_t *tpobj; + int match = 0; - if( ! hobj ) - { - errno = EINVAL; - return -1; - } + if (!hobj) + { + errno = EINVAL; + return -1; + } - errno = 0; - errmsg = 0; + errno = 0; + errmsg = 0; - if( pobj == obj_list ) - { - pobj->refn --; + if (pobj == obj_list) + { + pobj->refn--; - if( pobj->refn ) - return 0; + if (pobj->refn) + return 0; - match = 1; - obj_list = pobj->next; - } + match = 1; + obj_list = pobj->next; + } - for( tpobj = obj_list; !match && tpobj; tpobj = tpobj->next ) + for (tpobj = obj_list; !match && tpobj; tpobj = tpobj->next) + { + if (tpobj->next == pobj) { - if( tpobj->next == pobj ) - { - pobj->refn --; + pobj->refn--; - if( pobj->refn ) - return 0; + if (pobj->refn) + return 0; - match = 1; - tpobj->next = pobj->next; - } + match = 1; + tpobj->next = pobj->next; } + } - if(match) - { - unload((void*)(pobj->pentry)); - clean_htab(pobj->htab); - free(pobj->path); - free(pobj); - } + if (match) + { + unload ((void *) (pobj->pentry)); + clean_htab (pobj->htab); + free (pobj->path); + free (pobj); + } - return 0; + return 0; } -char* dlerror() -{ - extern char* sys_errlist[]; - - if( ! errmsg || ! errmsg[0] ) - { - if( errno >= 0 ) - return sys_errlist[errno]; - - return ""; - } - return errmsg; -} - -void* dlsym(void* hdl, char* sym) +char * +dlerror () { - nlist_t nl[3]; - obj_t* pobj = (obj_t*)hdl; - slot_t* ent; - int (*fp)(); - long lbuf[3]; - - if( !hdl || !(pobj->htab) || !sym || ! *sym ) - { - errno = EINVAL; - return 0; - } - - errno = 0; - errmsg = 0; + extern char *sys_errlist[]; - ent = search( pobj->htab, sym ); + if (!errmsg || !errmsg[0]) + { + if (errno >= 0) + return sys_errlist[errno]; - if( ent ) - return ent->fdesc; + return ""; + } -#define n_name _n._n_name - - nl[0].n_name = ENTRY_SYM; - nl[1].n_name = sym; - nl[2].n_name = 0; - - /* There is a potential problem here. If application - * did not pass a full path name, and changed the - * working directory after the load(), then nlist() - * will be unable to open the original shared library - * file to resolve the symbols. there are 3 ways to working - * round this: 1. convert to full pathname in driver - * manager. 2. applications always pass driver's full - * path name. 3. if driver itself don't support - * SQLGetFunctions(), call it with SQL_ALL_FUNCTIONS - * as flag immidately after SQLConnect(), SQLDriverConnect() - * and SQLBrowseConnect() to force the driver manager - * resolving all will be used symbols. - */ - if( nlist( pobj->path, nl) == -1 ) - return 0; - - if( ! nl[0].n_type && ! nl[0].n_value ) - { - errmsg = "can't locate module entry symbol"; - return 0; - } - - /* Note: On AIX 3.x if the object library is not - * built with -g compiling option, .n_type field - * is always 0. While on 4.x it will be 32. - * On AIX 4.x, if the symbol is a entry point, - * n_value will be 0. However, one thing is for sure - * that if a symbol is not existance in the file, - * both .n_type and .n_value would be 0. - */ - - if( ! nl[1].n_type && ! nl[1].n_value ) - { - errmsg = "symbol not existance in this module"; - return 0; - } + return errmsg; +} - ent = slot_alloc(sym); - if( ! ent ) - return 0; +void * +dlsym (void *hdl, char *sym) +{ + nlist_t nl[3]; + obj_t *pobj = (obj_t *) hdl; + slot_t *ent; + int (*fp) (); + long lbuf[3]; - /* catch it with a slot in the hashing table */ - insert(pobj->htab, ent); + if (!hdl || !(pobj->htab) || !sym || !*sym) + { + errno = EINVAL; + return 0; + } - memcpy(ent->fdesc, pobj->pentry, sizeof(ent->fdesc)); + errno = 0; + errmsg = 0; - /* now ent->fdesc[0] is the virtual address of entry point - * and ent->fdesc[1] is the TOC of the module - */ + ent = search (pobj->htab, sym); - /* let's calculate the virtual address of the symbol - * by adding a relative offset getting from the module - * file symbol table, i.e - * - * functin virtual address = entry point virtual address + - * + ( function offset in file - entry point offset in file ) - */ + if (ent) + return ent->fdesc; - (ent->fdesc)[0] = (ent->fdesc)[0] + - ( nl[1].n_value - nl[0].n_value ); +#define n_name _n._n_name - /* return the function descriptor */ - return ent->fdesc; + nl[0].n_name = ENTRY_SYM; + nl[1].n_name = sym; + nl[2].n_name = 0; + + /* There is a potential problem here. If application + * did not pass a full path name, and changed the + * working directory after the load(), then nlist() + * will be unable to open the original shared library + * file to resolve the symbols. there are 3 ways to working + * round this: 1. convert to full pathname in driver + * manager. 2. applications always pass driver's full + * path name. 3. if driver itself don't support + * SQLGetFunctions(), call it with SQL_ALL_FUNCTIONS + * as flag immidately after SQLConnect(), SQLDriverConnect() + * and SQLBrowseConnect() to force the driver manager + * resolving all will be used symbols. + */ + if (nlist (pobj->path, nl) == -1) + return 0; + + if (!nl[0].n_type && !nl[0].n_value) + { + errmsg = "can't locate module entry symbol"; + return 0; + } + + /* Note: On AIX 3.x if the object library is not + * built with -g compiling option, .n_type field + * is always 0. While on 4.x it will be 32. + * On AIX 4.x, if the symbol is a entry point, + * n_value will be 0. However, one thing is for sure + * that if a symbol is not existance in the file, + * both .n_type and .n_value would be 0. + */ + + if (!nl[1].n_type && !nl[1].n_value) + { + errmsg = "symbol not existance in this module"; + return 0; + } + + ent = slot_alloc (sym); + + if (!ent) + return 0; + + /* catch it with a slot in the hashing table */ + insert (pobj->htab, ent); + + memcpy (ent->fdesc, pobj->pentry, sizeof (ent->fdesc)); + + /* now ent->fdesc[0] is the virtual address of entry point + * and ent->fdesc[1] is the TOC of the module + */ + + /* let's calculate the virtual address of the symbol + * by adding a relative offset getting from the module + * file symbol table, i.e + * + * functin virtual address = entry point virtual address + + * + ( function offset in file - entry point offset in file ) + */ + + (ent->fdesc)[0] = (ent->fdesc)[0] + + (nl[1].n_value - nl[0].n_value); + + /* return the function descriptor */ + return ent->fdesc; } - -#endif /* end of IBM AIX Section */ +#endif /* end of IBM AIX Section */ /********************************* @@ -530,66 +538,75 @@ void* dlsym(void* hdl, char* sym) * Windows 3.x, 95, NT * *********************************/ + #ifdef DLDAPI_WINDOWS -# define DLDAPI_DEFINED -# include +#define DLDAPI_DEFINED +#include -void FAR* dlopen(char FAR* dll, int mode) +void FAR * +dlopen (char FAR * dll, int mode) { - HINSTANCE hint; + HINSTANCE hint; - if( dll == NULL ) - { - return GetWindowWord( NULL, GWW_HINSTANCE ); - } + if (dll == NULL) + { + return GetWindowWord (NULL, GWW_HINSTANCE); + } - hint = LoadLibrary(dll); + hint = LoadLibrary (dll); - if( hint < HINSTANCE_ERROR ) - { - return NULL; - } + if (hint < HINSTANCE_ERROR) + { + return NULL; + } - return (void FAR*)hint; + return (void FAR *) hint; } -void FAR* dlsym( void FAR* hdll, char FAR* sym ) + +void FAR * +dlsym (void FAR * hdll, char FAR * sym) { - return (void FAR*)GetProcAddress(hdll, sym); + return (void FAR *) GetProcAddress (hdll, sym); } -char FAR* dlerror() + +char FAR * +dlerror () { - return 0L; /* unimplemented yet */ + return 0L; /* unimplemented yet */ } -int dlclose(void FAR* hdll) + +int +dlclose (void FAR * hdll) { - FreeLibrary((HINSTANCE)hdll); + FreeLibrary ((HINSTANCE) hdll); } +#endif /* end of Windows family */ -#endif /* end of Windows family */ /*********************************** * * other platforms * ***********************************/ + #ifdef DLDAPI_OS2 -# define DLDAPI_DEFINED +#define DLDAPI_DEFINED /* - * DosLoadModule(), DosQueryProcAddress(), DosFreeModule(), ... + * DosLoadModule(), DosQueryProcAddress(), DosFreeModule(), ... */ #endif #ifdef DLDAPI_MAC -# define DLDAPI_DEFINED +#define DLDAPI_DEFINED #endif #ifdef DLDAPI_NEXT -# define DLDAPI_DEFINED +#define DLDAPI_DEFINED #endif #ifndef DLDAPI_DEFINED -# error "dynamic load editor undefined" +#error "dynamic load editor undefined" #endif