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

📄 prlink.c

📁 Netscape NSPR库源码
💻 C
📖 第 1 页 / 共 3 页
字号:
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- *//*  * The contents of this file are subject to the Mozilla Public * License Version 1.1 (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.mozilla.org/MPL/ *  * 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 Original Code is the Netscape Portable Runtime (NSPR). *  * The Initial Developer of the Original Code is Netscape * Communications Corporation.  Portions created by Netscape are  * Copyright (C) 1998-2000 Netscape Communications Corporation.  All * Rights Reserved. *  * Contributor(s): *  * Alternatively, the contents of this file may be used under the * terms of the GNU General Public License Version 2 or later (the * "GPL"), in which case the provisions of the GPL are applicable  * instead of those above.  If you wish to allow use of your  * version of this file only under the terms of the GPL and not to * allow others to use your version of this file under the MPL, * indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by * the GPL.  If you do not delete the provisions above, a recipient * may use your version of this file under either the MPL or the * GPL. */#include "primpl.h"#include <string.h>#ifdef XP_BEOS#include <image.h>#endif#ifdef XP_MAC#include <CodeFragments.h>#include <TextUtils.h>#include <Types.h>#include <Strings.h>#include <Aliases.h>#if TARGET_CARBON#include <CFURL.h>#include <CFBundle.h>#include <CFString.h>#endif#include "macdll.h"#include "mdmac.h"#endif#ifdef XP_UNIX#ifdef USE_DLFCN#include <dlfcn.h>/* Define these on systems that don't have them. */#ifndef RTLD_NOW#define RTLD_NOW 0#endif#ifndef RTLD_LAZY#define RTLD_LAZY RTLD_NOW#endif#ifndef RTLD_GLOBAL#define RTLD_GLOBAL 0#endif#ifndef RTLD_LOCAL#define RTLD_LOCAL 0#endif#elif defined(USE_HPSHL)#include <dl.h>#elif defined(USE_MACH_DYLD)#include <mach-o/dyld.h>#endif#endif /* XP_UNIX */#define _PR_DEFAULT_LD_FLAGS PR_LD_LAZY/* * On these platforms, symbols have a leading '_'. */#if defined(SUNOS4) || defined(DARWIN) || defined(NEXTSTEP) \    || defined(OPENBSD) || defined(WIN16) \    || (defined(NETBSD) && !defined(__ELF__))#define NEED_LEADING_UNDERSCORE#endif#ifdef XP_PCtypedef PRStaticLinkTable *NODL_PROC(void);#endif/************************************************************************/struct PRLibrary {    char*                       name;  /* Our own copy of the name string */    PRLibrary*                  next;    int                         refCount;    const PRStaticLinkTable*    staticTable;#ifdef XP_PC#ifdef XP_OS2    HMODULE                     dlh;#else    HINSTANCE                   dlh;#endif#endif#ifdef XP_MAC    CFragConnectionID           dlh;#if TARGET_CARBON    CFBundleRef                 bundle;#endif    Ptr                         main;#endif#ifdef XP_UNIX#if defined(USE_HPSHL)    shl_t                       dlh;#elif defined(USE_MACH_DYLD)    NSModule                    dlh;#else    void*                       dlh;#endif #endif #ifdef XP_BEOS    void*                       dlh;    void*                       stub_dlh;#endif};static PRLibrary *pr_loadmap;static PRLibrary *pr_exe_loadmap;static PRMonitor *pr_linker_lock;static char* _pr_currentLibPath = NULL;static PRLibrary *pr_LoadLibraryByPathname(const char *name, PRIntn flags);#ifdef XP_MACstatic PRLibrary *pr_Mac_LoadNamedFragment(const FSSpec *fileSpec,    const char* fragmentName);static PRLibrary *pr_Mac_LoadIndexedFragment(const FSSpec *fileSpec,    PRUint32 fragIndex);#endif /* XP_MAC *//************************************************************************/#if !defined(USE_DLFCN) && !defined(HAVE_STRERROR)static char* errStrBuf = NULL;#define ERR_STR_BUF_LENGTH    20static char* errno_string(PRIntn oserr){    if (errStrBuf == NULL)        errStrBuf = PR_MALLOC(ERR_STR_BUF_LENGTH);    PR_snprintf(errStrBuf, ERR_STR_BUF_LENGTH, "error %d", oserr);    return errStrBuf;}#endifstatic void DLLErrorInternal(PRIntn oserr)/*** This whole function, and most of the code in this file, are run** with a big hairy lock wrapped around it. Not the best of situations,** but will eventually come up with the right answer.*/{    const char *error = NULL;#ifdef USE_DLFCN    error = dlerror();  /* $$$ That'll be wrong some of the time - AOF */#elif defined(HAVE_STRERROR)    error = strerror(oserr);  /* this should be okay */#else    error = errno_string(oserr);#endif    if (NULL != error)        PR_SetErrorText(strlen(error), error);}  /* DLLErrorInternal */void _PR_InitLinker(void){#ifndef XP_MAC    PRLibrary *lm;#endif#if defined(XP_UNIX)    void *h;#endif    if (!pr_linker_lock) {        pr_linker_lock = PR_NewNamedMonitor("linker-lock");    }    PR_EnterMonitor(pr_linker_lock);#if defined(XP_PC)    lm = PR_NEWZAP(PRLibrary);    lm->name = strdup("Executable");        /*         ** In WIN32, GetProcAddress(...) expects a module handle in order to        ** get exported symbols from the executable...        **        ** However, in WIN16 this is accomplished by passing NULL to         ** GetProcAddress(...)        */#if defined(_WIN32)        lm->dlh = GetModuleHandle(NULL);#else        lm->dlh = (HINSTANCE)NULL;#endif /* ! _WIN32 */    lm->refCount    = 1;    lm->staticTable = NULL;    pr_exe_loadmap  = lm;    pr_loadmap      = lm;#elif defined(XP_UNIX)#ifdef HAVE_DLL#ifdef USE_DLFCN    h = dlopen(0, RTLD_LAZY);    if (!h) {        char *error;                DLLErrorInternal(_MD_ERRNO());        error = (char*)PR_MALLOC(PR_GetErrorTextLength());        (void) PR_GetErrorText(error);        fprintf(stderr, "failed to initialize shared libraries [%s]\n",            error);        PR_DELETE(error);        abort();/* XXX */    }#elif defined(USE_HPSHL)    h = NULL;    /* don't abort with this NULL */#elif defined(USE_MACH_DYLD)    h = NULL; /* XXXX  toshok */#else#error no dll strategy#endif /* USE_DLFCN */    lm = PR_NEWZAP(PRLibrary);    if (lm) {        lm->name = strdup("a.out");        lm->refCount = 1;        lm->dlh = h;        lm->staticTable = NULL;    }    pr_exe_loadmap = lm;    pr_loadmap = lm;#endif /* HAVE_DLL */#endif /* XP_UNIX */#ifndef XP_MAC    PR_LOG(_pr_linker_lm, PR_LOG_MIN, ("Loaded library %s (init)", lm?lm->name:"NULL"));#endif    PR_ExitMonitor(pr_linker_lock);}#if defined(WIN16)/* * _PR_ShutdownLinker unloads all dlls loaded by the application via * calls to PR_LoadLibrary */void _PR_ShutdownLinker(void){    PR_EnterMonitor(pr_linker_lock);    while (pr_loadmap) {    if (pr_loadmap->refCount > 1) {#ifdef DEBUG        fprintf(stderr, "# Forcing library to unload: %s (%d outstanding references)\n",            pr_loadmap->name, pr_loadmap->refCount);#endif        pr_loadmap->refCount = 1;    }    PR_UnloadLibrary(pr_loadmap);    }        PR_ExitMonitor(pr_linker_lock);    PR_DestroyMonitor(pr_linker_lock);    pr_linker_lock = NULL;}#else/* * _PR_ShutdownLinker was originally only used on WIN16 (see above), * but I think it should also be used on other platforms.  However, * I disagree with the original implementation's unloading the dlls * for the application.  Any dlls that still remain on the pr_loadmap * list when NSPR shuts down are application programming errors.  The * only exception is pr_exe_loadmap, which was added to the list by * NSPR and hence should be cleaned up by NSPR. */void _PR_ShutdownLinker(void){    /* FIXME: pr_exe_loadmap should be destroyed. */        PR_DestroyMonitor(pr_linker_lock);    pr_linker_lock = NULL;    if (_pr_currentLibPath) {        free(_pr_currentLibPath);        _pr_currentLibPath = NULL;    }#if !defined(USE_DLFCN) && !defined(HAVE_STRERROR)    PR_DELETE(errStrBuf);#endif}#endif/******************************************************************************/PR_IMPLEMENT(PRStatus) PR_SetLibraryPath(const char *path){    PRStatus rv = PR_SUCCESS;    if (!_pr_initialized) _PR_ImplicitInitialization();    PR_EnterMonitor(pr_linker_lock);    if (_pr_currentLibPath) {        free(_pr_currentLibPath);    }    if (path) {        _pr_currentLibPath = strdup(path);        if (!_pr_currentLibPath) {            PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);        rv = PR_FAILURE;        }    } else {        _pr_currentLibPath = 0;    }    PR_ExitMonitor(pr_linker_lock);    return rv;}/*** Return the library path for finding shared libraries.*/PR_IMPLEMENT(char *) PR_GetLibraryPath(void){    char *ev;    char *copy = NULL;  /* a copy of _pr_currentLibPath */    if (!_pr_initialized) _PR_ImplicitInitialization();    PR_EnterMonitor(pr_linker_lock);    if (_pr_currentLibPath != NULL) {        goto exit;    }    /* initialize pr_currentLibPath */#ifdef XP_PC    ev = getenv("LD_LIBRARY_PATH");    if (!ev) {    ev = ".;\\lib";    }    ev = strdup(ev);#endif#ifdef XP_MAC    {    char *p;    int len;    ev = getenv("LD_LIBRARY_PATH");        if (!ev)        ev = "";        len = strlen(ev) + 1;        /* +1 for the null */    p = (char*) malloc(len);    if (p) {        strcpy(p, ev);    }    ev = p;    }#endif#if defined(XP_UNIX) || defined(XP_BEOS)#if defined(USE_DLFCN) || defined(USE_MACH_DYLD) || defined(XP_BEOS)    {    char *p=NULL;    int len;#ifdef XP_BEOS    ev = getenv("LIBRARY_PATH");    if (!ev) {        ev = "%A/lib:/boot/home/config/lib:/boot/beos/system/lib";    }#else    ev = getenv("LD_LIBRARY_PATH");    if (!ev) {        ev = "/usr/lib:/lib";    }#endif    len = strlen(ev) + 1;        /* +1 for the null */    p = (char*) malloc(len);    if (p) {        strcpy(p, ev);    }   /* if (p)  */    ev = p;    PR_LOG(_pr_io_lm, PR_LOG_NOTICE, ("linker path '%s'", ev));    }#else    /* AFAIK there isn't a library path with the HP SHL interface --Rob */    ev = strdup("");#endif#endif    /*     * If ev is NULL, we have run out of memory     */    _pr_currentLibPath = ev;  exit:    if (_pr_currentLibPath) {        copy = strdup(_pr_currentLibPath);    }    PR_ExitMonitor(pr_linker_lock);    if (!copy) {        PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);    }    return copy;}/*** Build library name from path, lib and extensions*/PR_IMPLEMENT(char*) PR_GetLibraryName(const char *path, const char *lib){    char *fullname;#ifdef XP_PC    if (strstr(lib, PR_DLL_SUFFIX) == NULL)    {        fullname = PR_smprintf("%s\\%s%s", path, lib, PR_DLL_SUFFIX);    } else {        fullname = PR_smprintf("%s\\%s", path, lib);    }#endif /* XP_PC */#ifdef XP_MAC    fullname = PR_smprintf("%s%s", path, lib);#endif#if defined(XP_UNIX) || defined(XP_BEOS)    if (strstr(lib, PR_DLL_SUFFIX) == NULL)    {        fullname = PR_smprintf("%s/lib%s%s", path, lib, PR_DLL_SUFFIX);    } else {        fullname = PR_smprintf("%s/%s", path, lib);    }#endif /* XP_UNIX || XP_BEOS */    return fullname;}/*** Free the memory allocated, for the caller, by PR_GetLibraryName*/PR_IMPLEMENT(void) PR_FreeLibraryName(char *mem){    PR_smprintf_free(mem);}static PRLibrary* pr_UnlockedFindLibrary(const char *name){    PRLibrary* lm = pr_loadmap;    const char* np = strrchr(name, PR_DIRECTORY_SEPARATOR);    np = np ? np + 1 : name;

⌨️ 快捷键说明

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