/* * %CopyrightBegin% * * Copyright Ericsson AB 2006-2016. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions 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); } }