/* * %CopyrightBegin% * * Copyright Ericsson AB 2006-2013. All Rights Reserved. * * 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 online 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. * * %CopyrightEnd% */ /* * 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 "sys.h" #include "erl_vm.h" #include "global.h" #ifdef HAVE_DLFCN_H #include #endif /* some systems do not have RTLD_NOW defined, and require the "mode" * argument to dload() always be 1. */ #ifndef RTLD_NOW # define RTLD_NOW 1 #endif #define MAX_NAME_LEN 255 /* XXX should we get the system path size? */ #define EXT_LEN 3 #define FILE_EXT ".so" /* extension appended to the filename */ static char **errcodes = NULL; static int num_errcodes = 0; static int num_errcodes_allocated = 0; #define my_strdup(WHAT) my_strdup_in(ERTS_ALC_T_DDLL_ERRCODES, WHAT); static char *my_strdup_in(ErtsAlcType_t type, char *what) { char *res = erts_alloc(type, strlen(what) + 1); strcpy(res, what); return res; } static int find_errcode(char *string, ErtsSysDdllError* err) { int i; if (err != NULL) { erts_sys_ddll_free_error(err); /* in case we ignored an earlier error */ err->str = my_strdup_in(ERTS_ALC_T_DDLL_TMP_BUF, string); return 0; } for(i=0;i ERL_DE_DYNAMIC_ERROR_OFFSET) { return "Unspecified error"; } actual_code = -1*(code - ERL_DE_DYNAMIC_ERROR_OFFSET); #if defined(HAVE_DLOPEN) { char *msg; if (actual_code >= num_errcodes) { msg = "Unknown dlload error"; } else { msg = errcodes[actual_code]; } return msg; } #endif return "no error"; } void erts_sys_ddll_free_error(ErtsSysDdllError* err) { if (err->str != NULL) { erts_free(ERTS_ALC_T_DDLL_TMP_BUF, err->str); } }