-/** dynamic library loader (mapping to svr4)
-
- Copyright (C) 1995 by Ke Jin <kejin@empress.com>
-
- 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 <kejin@empress.com>
+ *
+ * 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 <errno.h>
-#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
/*********************************
* HP/UX
*
*********************************/
+
#ifdef DLDAPI_HP_SHL
-# define DLDAPI_DEFINED
-# include <dl.h>
+#define DLDAPI_DEFINED
+#include <dl.h>
-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 <sys/types.h>
-# include <sys/ldr.h>
-# include <sys/stat.h>
-# include <nlist.h>
+#define DLDAPI_DEFINED
+#include <sys/types.h>
+#include <sys/ldr.h>
+#include <sys/stat.h>
+#include <nlist.h>
/*
* Following id sting is a copyright mark. Removing(i.e. use the
* 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
* 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; i<HTAB_SIZE; i++)
- ht[i] = (slot_t*)0;
+ for (i = 0; i < HTAB_SIZE; i++)
+ ht[i] = (slot_t *) 0;
- return;
+ return;
}
-static void clean_htab(hent_t* ht)
+
+static void
+clean_htab (hent_t * ht)
/* free all slots */
{
- int i;
- slot_t* ent;
- slot_t* tent;
+ int i;
+ slot_t *ent;
+ slot_t *tent;
- for(i = 0; i< HTAB_SIZE; i++)
+ for (i = 0; i < HTAB_SIZE; i++)
+ {
+ for (ent = ht[i]; ent;)
{
- for( ent = ht[i]; ent; )
- {
- tent = ent->next;
-
- 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 */
/*********************************
* Windows 3.x, 95, NT
*
*********************************/
+
#ifdef DLDAPI_WINDOWS
-# define DLDAPI_DEFINED
-# include <windows.h>
+#define DLDAPI_DEFINED
+#include <windows.h>
-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