⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dl_aix.xs

📁 UNIX下perl实现代码
💻 XS
📖 第 1 页 / 共 2 页
字号:
/* dl_aix.xs * * Written: 8/31/94 by Wayne Scott (wscott@ichips.intel.com) * *  All I did was take Jens-Uwe Mager's libdl emulation library for *  AIX and merged it with the dl_dlopen.xs file to create a dynamic library *  package that works for AIX. * *  I did change all malloc's, free's, strdup's, calloc's to use the perl *  equilvant.  I also removed some stuff we will not need.  Call fini() *  on statup...   It can probably be trimmed more. */#define PERLIO_NOT_STDIO 0/* * @(#)dlfcn.c	1.5 revision of 93/02/14  20:14:17 * This is an unpublished work copyright (c) 1992 Helios Software GmbH * 3000 Hannover 1, Germany */#include "EXTERN.h"#include "perl.h"#include "XSUB.h"/* When building as a 64-bit binary on AIX, define this to get the * correct structure definitions.  Also determines the field-name * macros and gates some logic in readEntries().  -- Steven N. Hirsch * <hirschs@btv.ibm.com> */#ifdef USE_64_BIT_ALL#   define __XCOFF64__#   define __XCOFF32__#endif#include <stdio.h>#include <errno.h>#include <string.h>#include <stdlib.h>#include <sys/types.h>#include <sys/ldr.h>#include <a.out.h>#undef FREAD#undef FWRITE#include <ldfcn.h>#ifdef USE_64_BIT_ALL#   define AIX_SCNHDR SCNHDR_64#   define AIX_LDHDR LDHDR_64#   define AIX_LDSYM LDSYM_64#   define AIX_LDHDRSZ LDHDRSZ_64#else#   define AIX_SCNHDR SCNHDR#   define AIX_LDHDR LDHDR#   define AIX_LDSYM LDSYM#   define AIX_LDHDRSZ LDHDRSZ#endif/* When using Perl extensions written in C++ the longer versions * of load() and unload() from libC and libC_r need to be used, * otherwise statics in the extensions won't get initialized right. * -- Stephanie Beals <bealzy@us.ibm.com> *//* Older AIX C compilers cannot deal with C++ double-slash comments in   the ibmcxx and/or xlC includes.  Since we only need a single file,   be more fine-grained about what's included <hirschs@btv.ibm.com> */#ifdef USE_libC /* The define comes, when it comes, from hints/aix.pl. */#   define LOAD   loadAndInit#   define UNLOAD terminateAndUnload#   if defined(USE_vacpp_load_h)#       include "/usr/vacpp/include/load.h"#   elif defined(USE_ibmcxx_load_h)#       include "/usr/ibmcxx/include/load.h"#   elif defined(USE_xlC_load_h)#       include "/usr/lpp/xlC/include/load.h"#   elif defined(USE_load_h)#       include "/usr/include/load.h"#   endif#else#   define LOAD   load#   define UNLOAD unload#endif/* * AIX 4.3 does remove some useful definitions from ldfcn.h. Define * these here to compensate for that lossage. */#ifndef BEGINNING# define BEGINNING SEEK_SET#endif#ifndef FSEEK# define FSEEK(ldptr,o,p)	fseek(IOPTR(ldptr),(p==BEGINNING)?(OFFSET(ldptr) +o):o,p)#endif#ifndef FREAD# define FREAD(p,s,n,ldptr)	fread(p,s,n,IOPTR(ldptr))#endif/* * We simulate dlopen() et al. through a call to load. Because AIX has * no call to find an exported symbol we read the loader section of the * loaded module and build a list of exported symbols and their virtual * address. */typedef struct {	char		*name;		/* the symbols's name */	void		*addr;		/* its relocated virtual address */} Export, *ExportPtr;/* * The void * handle returned from dlopen is actually a ModulePtr. */typedef struct Module {	struct Module	*next;	char		*name;		/* module name for refcounting */	int		refCnt;		/* the number of references */	void		*entry;		/* entry point from load */	int		nExports;	/* the number of exports found */	ExportPtr	exports;	/* the array of exports */} Module, *ModulePtr;/* * We keep a list of all loaded modules to be able to reference count * duplicate dlopen's. */static ModulePtr modList;		/* XXX threaded *//* * The last error from one of the dl* routines is kept in static * variables here. Each error is returned only once to the caller. */static char errbuf[BUFSIZ];		/* XXX threaded */static int errvalid;			/* XXX threaded */static void caterr(char *);static int readExports(ModulePtr);static void *findMain(void);static char *strerror_failed   = "(strerror failed)";static char *strerror_r_failed = "(strerror_r failed)";char *strerrorcat(char *str, int err) {    int strsiz = strlen(str);    int msgsiz;    char *msg;#ifdef USE_THREADS    char *buf = malloc(BUFSIZ);    if (buf == 0)      return 0;    if (strerror_r(err, buf, BUFSIZ) == 0)      msg = buf;    else      msg = strerror_r_failed;    msgsiz = strlen(msg);    if (strsiz + msgsiz < BUFSIZ)      strcat(str, msg);    free(buf);#else    if ((msg = strerror(err)) == 0)      msg = strerror_failed;    msgsiz = strlen(msg);		/* Note msg = buf and free() above. */    if (strsiz + msgsiz < BUFSIZ)	/* Do not move this after #endif. */      strcat(str, msg);#endif    return str;}char *strerrorcpy(char *str, int err) {    int msgsiz;    char *msg;#ifdef USE_THREADS    char *buf = malloc(BUFSIZ);    if (buf == 0)      return 0;    if (strerror_r(err, buf, BUFSIZ) == 0)      msg = buf;    else      msg = strerror_r_failed;    msgsiz = strlen(msg);    if (msgsiz < BUFSIZ)      strcpy(str, msg);    free(buf);#else    if ((msg = strerror(err)) == 0)      msg = strerror_failed;    msgsiz = strlen(msg);	/* Note msg = buf and free() above. */    if (msgsiz < BUFSIZ)	/* Do not move this after #endif. */      strcpy(str, msg);#endif    return str;}  /* ARGSUSED */void *dlopen(char *path, int mode){	dTHX;	register ModulePtr mp;	static void *mainModule;		/* XXX threaded */	/*	 * Upon the first call register a terminate handler that will	 * close all libraries.	 */	if (mainModule == NULL) {		if ((mainModule = findMain()) == NULL)			return NULL;	}	/*	 * Scan the list of modules if have the module already loaded.	 */	for (mp = modList; mp; mp = mp->next)		if (strcmp(mp->name, path) == 0) {			mp->refCnt++;			return mp;		}	Newz(1000,mp,1,Module);	if (mp == NULL) {		errvalid++;		strcpy(errbuf, "Newz: ");		strerrorcat(errbuf, errno);		return NULL;	}		if ((mp->name = savepv(path)) == NULL) {		errvalid++;		strcpy(errbuf, "savepv: ");		strerrorcat(errbuf, errno);		safefree(mp);		return NULL;	}	/*	 * load should be declared load(const char *...). Thus we	 * cast the path to a normal char *. Ugly.	 */	if ((mp->entry = (void *)LOAD((char *)path,#ifdef L_LIBPATH_EXEC				      L_LIBPATH_EXEC |#endif				      L_NOAUTODEFER,				      NULL)) == NULL) {	        int saverrno = errno;				safefree(mp->name);		safefree(mp);		errvalid++;		strcpy(errbuf, "dlopen: ");		strcat(errbuf, path);		strcat(errbuf, ": ");		/*		 * If AIX says the file is not executable, the error		 * can be further described by querying the loader about		 * the last error.		 */		if (saverrno == ENOEXEC) {			char *moreinfo[BUFSIZ/sizeof(char *)];			if (loadquery(L_GETMESSAGES, moreinfo, sizeof(moreinfo)) == -1)				strerrorcpy(errbuf, saverrno);			else {				char **p;				for (p = moreinfo; *p; p++)					caterr(*p);			}		} else			strerrorcat(errbuf, saverrno);		return NULL;	}	mp->refCnt = 1;	mp->next = modList;	modList = mp;	/*	 * Assume anonymous exports come from the module this dlopen	 * is linked into, that holds true as long as dlopen and all	 * of the perl core are in the same shared object. Also bind	 * against the main part, in the case a perl is not the main	 * part, e.g mod_perl as DSO in Apache so perl modules can	 * also reference Apache symbols.	 */	if (loadbind(0, (void *)dlopen, mp->entry) == -1 ||	    loadbind(0, mainModule, mp->entry)) {	        int saverrno = errno;		dlclose(mp);		errvalid++;		strcpy(errbuf, "loadbind: ");		strerrorcat(errbuf, saverrno);		return NULL;	}	if (readExports(mp) == -1) {		dlclose(mp);		return NULL;	}	return mp;}/* * Attempt to decipher an AIX loader error message and append it * to our static error message buffer. */static void caterr(char *s){	register char *p = s;	while (*p >= '0' && *p <= '9')		p++;	switch(atoi(s)) {	case L_ERROR_TOOMANY:		strcat(errbuf, "too many errors");		break;	case L_ERROR_NOLIB:		strcat(errbuf, "can't load library");		strcat(errbuf, p);		break;	case L_ERROR_UNDEF:		strcat(errbuf, "can't find symbol");		strcat(errbuf, p);		break;	case L_ERROR_RLDBAD:		strcat(errbuf, "bad RLD");		strcat(errbuf, p);		break;	case L_ERROR_FORMAT:		strcat(errbuf, "bad exec format in");		strcat(errbuf, p);		break;	case L_ERROR_ERRNO:		strerrorcat(errbuf, atoi(++p));		break;	default:		strcat(errbuf, s);		break;	}}void *dlsym(void *handle, const char *symbol){	register ModulePtr mp = (ModulePtr)handle;	register ExportPtr ep;	register int i;	/*	 * Could speed up search, but I assume that one assigns	 * the result to function pointers anyways.	 */	for (ep = mp->exports, i = mp->nExports; i; i--, ep++)		if (strcmp(ep->name, symbol) == 0)			return ep->addr;	errvalid++;	strcpy(errbuf, "dlsym: undefined symbol ");	strcat(errbuf, symbol);	return NULL;}char *dlerror(void){	if (errvalid) {		errvalid = 0;		return errbuf;	}	return NULL;}int dlclose(void *handle){	register ModulePtr mp = (ModulePtr)handle;	int result;	register ModulePtr mp1;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -