vxworks_ddll_drv.c

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

C
189
字号
/* ``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$ *//* Purpose: Low level driver for dynamic driver loader/unloader and * linker for VxWorks. */#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 "erl_vm.h"#include "erl_ddll.h"static char thismodname[] = "vxworks_ddll_drv";static char *curr_error = "No error";static MODULE_ID get_mid(char *);static FUNCPTR lookup(char *);static void drv_error(char*, ...);/* * ddll_open(full_name) * * full_name is the path to the file containing the driver. * The basename of full_name is the driver name. *  * Returns the MODULE_ID of the module containing the driver. * */void *ddll_open(char *full_name){    char *path;    char *drvname;    char *cp;    MODULE_ID mid;    int len;    if ((mid = get_mid(full_name)) == NULL) {	if((path = malloc(strlen(full_name)+5)) == NULL) {	    curr_error = "ddll_open: Cannot malloc";	    return NULL;	}	strcpy(path, full_name);	len = strlen(path);	strcpy(path + len, ".eld");	if(((mid = get_mid(path)) == NULL) &&	   strcpy(path + len, ".o") &&	   ((mid = get_mid(path)) == NULL)) {	    curr_error = "ddll_open: Module not found";	}	free(path);    }    return (void *) mid;}static MODULE_IDget_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;}/* * Return pointer to function MODULENAME_init. * * n.b. func_name is ignored. * * The convention is that the module name of the driver is .eld (e.g. echo_drv.eld). * But if it has .o as suffix or no suffix it is also ok (e.g. echo_drv.o and echo_drv) * */void *ddll_sym(void *handle, char *func_name){    MODULE_ID mid = (MODULE_ID) handle;    char *modname;    char *cp;    char *fname;    char *suffix = "_init";    int len;    FUNCPTR func;        if((modname = moduleNameGet(mid)) == NULL) {	curr_error = "ddll_sym: Module not found";	return 0;    }    if((cp = strrchr(modname, '.')) == NULL) {	len = strlen(modname);    } else {	len = cp - modname;    }    if((fname = malloc(len + strlen(suffix) + 1)) == NULL) {	curr_error = "ddll_sym: cannot malloc";	return 0;    }    strncpy(fname, modname, len);    fname[len] = '\0';    strcat(fname, suffix);    if((func = lookup(fname)) == NULL)	curr_error = "ddll_sym: function NAME_init not found";    free(fname);    return func;}int ddll_close(void *handle){    MODULE_ID mid = (MODULE_ID) handle;    int ret;        if((ret = unld(mid, 0)) < 0)	curr_error = "ddll_close: Module not found";    return ret;}char *ddll_error(void){    return curr_error;}/* * Lookup and return global text symbol or NULL on failure * * ddll_drv.c looks for sym with and without a leading '_'. * (this is needed since gcc for PPC doesn't include the * leading '_' while gcc for e.g. 68k does so) */static FUNCPTR lookup(char *sym){    FUNCPTR entry;    SYM_TYPE type;    char buf[256];    char *u_score_sym = buf;    int len;        if (symFindByNameAndType(sysSymTbl, sym, (char **)&entry,			     &type, N_EXT | N_TEXT, N_EXT | N_TEXT) != OK) {	len = strlen(sym);	if (len > 254 && (u_score_sym = malloc(len+2)) == NULL)	    return(NULL);	sprintf(u_score_sym, "_%s", sym);	if (symFindByNameAndType(sysSymTbl, u_score_sym, (char **)&entry,				 &type, N_EXT | N_TEXT, N_EXT | N_TEXT) != OK)	    entry = NULL;	if (u_score_sym != buf)	    free(u_score_sym);    }    return(entry);}static void drv_error(char* format, ...){    va_list va;    fprintf(stdout, "%s: ", thismodname);    va_start(va, format);    vfprintf(stdout, format, va);    va_end(va);}

⌨️ 快捷键说明

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