erl_vxworks_sys_ddll.c

来自「OTP是开放电信平台的简称」· C语言 代码 · 共 232 行

C
232
字号
/* ``The contents of this file are subject to the Erlang Public License, * Version 1.1, (the "License"); you may not use this file except in * compliance with the License. You should have received a copy of the * Erlang Public License along with this software. If not, it can be * retrieved via the world wide web at http://www.erlang.org/. *  * Software distributed under the License is distributed on an "AS IS" * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See * the License for the specific language governing rights and limitations * under the License. *  * The Initial Developer of the Original Code is Ericsson Utvecklings AB. * Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings * AB. All Rights Reserved.'' *  *     $Id$ *//*  * Interface functions to the dynamic linker using dl* functions. * (As far as I know it works on SunOS 4, 5, Linux and FreeBSD. /Seb)  */#ifdef HAVE_CONFIG_H#  include "config.h"#endif#include <vxWorks.h>#include <stdio.h>#include <string.h>#include <stdarg.h>#include <a_out.h>#include <symLib.h>#include <loadLib.h>#include <unldLib.h>#include <moduleLib.h>#include <sysSymTbl.h>#include "sys.h"#include "global.h"#include "erl_alloc.h"#include "erl_driver.h"#define EXT_LEN          4#define FILE_EXT         ".eld"#define ALT_FILE_EXT     ".o"#define DRIVER_INIT_SUFFIX "_init"static MODULE_ID get_mid(char *);static FUNCPTR lookup(char *);typedef enum {    NoError,    ModuleNotFound,    ModuleNotUnloadable,    UnknownError} FakeSytemError;static char *errcode_tab[] = {    "No error",    "Module/file not found",    "Module cannot be unloaded",    "Unknown error"};void erl_sys_ddll_init(void) {    return;}/*  * Open a shared object */int erts_sys_ddll_open(char *full_name, void **handle){    MODULE_ID mid;    int len;    int ret = ERL_DE_NO_ERROR;    static char dlname[PATH_MAX + EXT_LEN + 1];    if ((mid = get_mid(full_name)) == NULL) {	if ((len = sys_strlen(full_name)) > PATH_MAX-EXT_LEN-1) {	    ret = ERL_DE_LOAD_ERROR_NAME_TO_LONG;	    goto done;	}	sys_strcpy(dlname, full_name);	sys_strcpy(dlname+len, FILE_EXT);	if((mid = get_mid(dlname)) == NULL) {	    sys_strcpy(dlname+len, ALT_FILE_EXT);	    if((mid = get_mid(dlname)) == NULL) {		ret = ERL_DE_DYNAMIC_ERROR_OFFSET - ((int) ModuleNotFound);		goto done;	    }	}    }    *handle = (void *) mid; done:    return ret;}/*  * Find a symbol in the shared object */#define PREALLOC_BUFFER_SIZE 256int erts_sys_ddll_sym(void *handle, char *func_name, void **function){    FUNCPTR proc;    static char statbuf[PREALLOC_BUFFER_SIZE];    char *buf = statbuf;    int need;    if ((proc = lookup(func_name)) == NULL) {	if ((need = strlen(func_name)+2) > PREALLOC_BUFFER_SIZE) {	    buf = erts_alloc(ERTS_ALC_T_DDLL_TMP_BUF,need);	}	buf[0] = '_';	sys_strcpy(buf+1,func_name);	proc = lookup(buf);	if (buf != statbuf) {	    erts_free(ERTS_ALC_T_DDLL_TMP_BUF, buf);	}	if (proc == NULL) {	    return  ERL_DE_LOOKUP_ERROR_NOT_FOUND;	}    }    *function = (void *) proc;    return ERL_DE_NO_ERROR;}/* XXX:PaN These two will be changed with new driver interface! *//*  * Load the driver init function, might appear under different names depending on object arch...  */int erts_sys_ddll_load_driver_init(void *handle, void **function){    MODULE_ID mid = (MODULE_ID) handle;    char *modname;    char *cp;    static char statbuf[PREALLOC_BUFFER_SIZE];    char *fname = statbuf;    int len;    int res;    void *func;    int need;    if((modname = moduleNameGet(mid)) == NULL) {	return ERL_DE_DYNAMIC_ERROR_OFFSET - ((int) ModuleNotFound);    }        if((cp = strrchr(modname, '.')) == NULL) {	len = strlen(modname);    } else {	len = cp - modname;    }        need =  len + strlen(DRIVER_INIT_SUFFIX) + 1;    if (need > PREALLOC_BUFFER_SIZE) {	fname = erts_alloc(ERTS_ALC_T_DDLL_TMP_BUF, need); /* erts_alloc exits on failure */    }    sys_strncpy(fname, modname, len);    fname[len] = '\0';    sys_strcat(fname, DRIVER_INIT_SUFFIX);    res = erts_sys_ddll_sym(handle, fname, &func);    if (fname != statbuf) {	erts_free(ERTS_ALC_T_DDLL_TMP_BUF, fname);    }    if ( res != ERL_DE_NO_ERROR) {	return res;    }    *function = func;    return ERL_DE_NO_ERROR;}/*  * Call the driver_init function, whatever it's really called, simple on unix... */void *erts_sys_ddll_call_init(void *function) {    void *(*initfn)(void) = function;    return (*initfn)();}/*  * Close a chared object */int erts_sys_ddll_close(void *handle){    MODULE_ID mid = (MODULE_ID) handle;    if (unld(mid, 0) < 0) {	return  ERL_DE_DYNAMIC_ERROR_OFFSET - ((int) ModuleNotUnloadable);    }    return  ERL_DE_NO_ERROR;}/* * Return string that describes the (current) error */char *erts_sys_ddll_error(int code){    int actual_code;    if (code > ERL_DE_DYNAMIC_ERROR_OFFSET) {	return "Unspecified error";    }    actual_code = -1*(code - ERL_DE_DYNAMIC_ERROR_OFFSET);    if (actual_code > ((int) UnknownError)) {	actual_code = UnknownError;    }    return  errcode_tab[actual_code];}static FUNCPTR lookup(char *sym){    FUNCPTR entry;    SYM_TYPE type;        if (symFindByNameAndType(sysSymTbl, sym, (char **)&entry,			     &type, N_EXT | N_TEXT, N_EXT | N_TEXT) != OK) {	return NULL ;    }    return entry;}static MODULE_ID get_mid(char* name) {     int fd;    MODULE_ID mid = NULL;        if((fd = open(name, O_RDONLY, 0664)) >= 0) {	mid = loadModule(fd, GLOBAL_SYMBOLS);	close(fd);    }    return mid;}

⌨️ 快捷键说明

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