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

📄 prlink.c

📁 Netscape NSPR库源码
💻 C
📖 第 1 页 / 共 3 页
字号:
    while (lm) {    const char* cp = strrchr(lm->name, PR_DIRECTORY_SEPARATOR);    cp = cp ? cp + 1 : lm->name;#ifdef XP_PC        /* Windows DLL names are case insensitive... */    if (strcmpi(np, cp) == 0) #else    if (strcmp(np, cp)  == 0) #endif    {        /* found */        lm->refCount++;        PR_LOG(_pr_linker_lm, PR_LOG_MIN,           ("%s incr => %d (find lib)",            lm->name, lm->refCount));        return lm;    }    lm = lm->next;    }    return NULL;}PR_IMPLEMENT(PRLibrary*)PR_LoadLibraryWithFlags(PRLibSpec libSpec, PRIntn flags){    if (flags == 0) {        flags = _PR_DEFAULT_LD_FLAGS;    }    switch (libSpec.type) {        case PR_LibSpec_Pathname:            return pr_LoadLibraryByPathname(libSpec.value.pathname, flags);#ifdef XP_MAC        case PR_LibSpec_MacNamedFragment:            return pr_Mac_LoadNamedFragment(                libSpec.value.mac_named_fragment.fsspec,                libSpec.value.mac_named_fragment.name);        case PR_LibSpec_MacIndexedFragment:            return pr_Mac_LoadIndexedFragment(                libSpec.value.mac_indexed_fragment.fsspec,                libSpec.value.mac_indexed_fragment.index);#endif /* XP_MAC */        default:            PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);            return NULL;    }}            PR_IMPLEMENT(PRLibrary*) PR_LoadLibrary(const char *name){    PRLibSpec libSpec;    libSpec.type = PR_LibSpec_Pathname;    libSpec.value.pathname = name;    return PR_LoadLibraryWithFlags(libSpec, 0);}#if TARGET_CARBON/*** Returns a CFBundleRef if the FSSpec refers to a Mac OS X bundle directory.** The caller is responsible for calling CFRelease() to deallocate.*/static CFBundleRef getLibraryBundle(const FSSpec* spec){    CFBundleRef bundle = NULL;    FSRef ref;    OSErr err = FSpMakeFSRef(spec, &ref);    char path[512];    if (err == noErr && ((UInt32)(FSRefMakePath) != kUnresolvedCFragSymbolAddress)) {        err = FSRefMakePath(&ref, (UInt8*)path, sizeof(path) - 1);        if (err == noErr) {            CFStringRef pathRef = CFStringCreateWithCString(NULL, path, kCFStringEncodingUTF8);            if (pathRef) {            	CFURLRef bundleURL = CFURLCreateWithFileSystemPath(NULL, pathRef, kCFURLPOSIXPathStyle, true);            	if (bundleURL != NULL) {                    bundle = CFBundleCreate(NULL, bundleURL);                    CFRelease(bundleURL);            	}            	CFRelease(pathRef);            }        }    }    return bundle;}#endif/*** Dynamically load a library. Only load libraries once, so scan the load** map first.*/static PRLibrary*pr_LoadLibraryByPathname(const char *name, PRIntn flags){    PRLibrary *lm;    PRLibrary* result;    PRInt32 oserr;    if (!_pr_initialized) _PR_ImplicitInitialization();    /* See if library is already loaded */    PR_EnterMonitor(pr_linker_lock);    result = pr_UnlockedFindLibrary(name);    if (result != NULL) goto unlock;    lm = PR_NEWZAP(PRLibrary);    if (lm == NULL) {        oserr = _MD_ERRNO();        goto unlock;    }    lm->staticTable = NULL;#ifdef XP_OS2  /* Why isn't all this stuff in MD code?! */    {        HMODULE h;        UCHAR pszError[_MAX_PATH];        ULONG ulRc = NO_ERROR;        retry:              ulRc = DosLoadModule(pszError, _MAX_PATH, (PSZ) name, &h);          if (ulRc != NO_ERROR) {              oserr = ulRc;              PR_DELETE(lm);              goto unlock;          }          lm->name = strdup(name);          lm->dlh  = h;          lm->next = pr_loadmap;          pr_loadmap = lm;    }#endif /* XP_OS2 */#if defined(WIN32) || defined(WIN16)    {    HINSTANCE h;    NODL_PROC *pfn;    h = LoadLibrary(name);    if (h < (HINSTANCE)HINSTANCE_ERROR) {        oserr = _MD_ERRNO();        PR_DELETE(lm);        goto unlock;    }    lm->name = strdup(name);    lm->dlh = h;    lm->next = pr_loadmap;    pr_loadmap = lm;        /*        ** Try to load a table of "static functions" provided by the DLL        */        pfn = (NODL_PROC *)GetProcAddress(h, "NODL_TABLE");        if (pfn != NULL) {            lm->staticTable = (*pfn)();        }    }#endif /* WIN32 || WIN16 */#if defined(XP_MAC) && TARGET_RT_MAC_CFM    {    OSErr                 err;    CFragConnectionID     connectionID;    Str255                errName;    Str255                pName;    char                  cName[64];    const char*           libName;            /*     * Algorithm: The "name" passed in could be either a shared     * library name that we should look for in the normal library     * search paths, or a full path name to a specific library on     * disk.  Since the full path will always contain a ":"     * (shortest possible path is "Volume:File"), and since a     * library name can not contain a ":", we can test for the     * presence of a ":" to see which type of library we should load.     * or its a full UNIX path which we for now assume is Java     * enumerating all the paths (see below)     */    if (strchr(name, PR_PATH_SEPARATOR) == NULL)    {        if (strchr(name, PR_DIRECTORY_SEPARATOR) == NULL)        {        /*         * The name did not contain a ":", so it must be a         * library name.  Convert the name to a Pascal string         * and try to find the library.         */        }        else        {            /* name contained a "/" which means we need to suck off the last part */            /* of the path and pass that on the NSGetSharedLibrary */            /* this may not be what we really want to do .. because Java could */            /* be iterating through the whole LD path, and we'll find it if it's */            /* anywhere on that path -- it appears that's what UNIX and the PC do */            /* too...so we'll emulate but it could be wrong. */            name = strrchr(name, PR_DIRECTORY_SEPARATOR) + 1;        }                PStrFromCStr(name, pName);            /*         * beard: NSGetSharedLibrary was so broken that I just decided to         * use GetSharedLibrary for now.  This will need to change for         * plugins, but those should go in the Extensions folder anyhow.         */#if 0        err = NSGetSharedLibrary(pName, &connectionID, &lm->main);#else        err = GetSharedLibrary(pName, kCompiledCFragArch, kReferenceCFrag,                &connectionID, &lm->main, errName);#endif        if (err != noErr)        {            oserr = err;            PR_DELETE(lm);            goto unlock;            }                libName = name;    }    else        {        /*         * The name did contain a ":", so it must be a full path name.         * Now we have to do a lot of work to convert the path name to         * an FSSpec (silly, since we were probably just called from the         * MacFE plug-in code that already knew the FSSpec and converted         * it to a full path just to pass to us).  First we copy out the         * volume name (the text leading up to the first ":"); then we         * separate the file name (the text following the last ":") from         * rest of the path.  After converting the strings to Pascal         * format we can call GetCatInfo to get the parent directory ID         * of the file, and then (finally) make an FSSpec and call         * GetDiskFragment.         */        FSSpec fileSpec;        Boolean tempUnusedBool;        PStrFromCStr(name, pName);        err = FSMakeFSSpec(0, 0, pName, &fileSpec);        if (err != noErr) {            oserr = _MD_ERRNO();            PR_DELETE(lm);            goto unlock;        }        /* Resolve an alias if this was one */        err = ResolveAliasFile(&fileSpec, true, &tempUnusedBool, &tempUnusedBool);        if (err != noErr)        {            oserr = err;            PR_DELETE(lm);            goto unlock;        }        /* Finally, try to load the library */        err = GetDiskFragment(&fileSpec, 0, kCFragGoesToEOF, fileSpec.name,                               kLoadCFrag, &connectionID, &lm->main, errName);        memcpy(cName, fileSpec.name + 1, fileSpec.name[0]);        cName[fileSpec.name[0]] = '\0';        libName = cName;                if (err != noErr)        {#if TARGET_CARBON            /* If not a CFM library, perhaps it's a CFBundle. */            lm->bundle = getLibraryBundle(&fileSpec);#ifdef DEBUG            fprintf(stderr, "*** loading bundle for library '%s' [%s]. ***\n",                    libName, lm->bundle ? "SUCCEEDED" : "FAILED");#endif            if (lm->bundle == NULL) {                oserr = err;                PR_DELETE(lm);                goto unlock;            }#else            oserr = err;            PR_DELETE(lm);            goto unlock;#endif        }    }        lm->name = strdup(libName);    lm->dlh = connectionID;    lm->next = pr_loadmap;    pr_loadmap = lm;    }#elif defined(XP_MAC) && !TARGET_RT_MAC_CFM    {    }#endif#ifdef XP_UNIX#ifdef HAVE_DLL    {#if defined(USE_DLFCN)#ifdef NTO    /* Neutrino needs RTLD_GROUP to load Netscape plugins. (bug 71179) */    int dl_flags = RTLD_GROUP;#else    int dl_flags = 0;#endif    void *h;    if (flags & PR_LD_LAZY) {        dl_flags |= RTLD_LAZY;    }    if (flags & PR_LD_NOW) {        dl_flags |= RTLD_NOW;    }    if (flags & PR_LD_GLOBAL) {        dl_flags |= RTLD_GLOBAL;    }    if (flags & PR_LD_LOCAL) {        dl_flags |= RTLD_LOCAL;    }    h = dlopen(name, dl_flags);#elif defined(USE_HPSHL)    int shl_flags = 0;    shl_t h;    /*     * Use the DYNAMIC_PATH flag only if 'name' is a plain file     * name (containing no directory) to match the behavior of     * dlopen().     */    if (strchr(name, PR_DIRECTORY_SEPARATOR) == NULL) {        shl_flags |= DYNAMIC_PATH;    }    if (flags & PR_LD_LAZY) {        shl_flags |= BIND_DEFERRED;    }    if (flags & PR_LD_NOW) {        shl_flags |= BIND_IMMEDIATE;    }    /* No equivalent of PR_LD_GLOBAL and PR_LD_LOCAL. */    h = shl_load(name, shl_flags, 0L);#elif defined(USE_MACH_DYLD)    NSObjectFileImage ofi;    NSModule h = NULL;    if (NSCreateObjectFileImageFromFile(name, &ofi)            == NSObjectFileImageSuccess) {        h = NSLinkModule(ofi, name, NSLINKMODULE_OPTION_PRIVATE);    }#else#error Configuration error#endif    if (!h) {        oserr = _MD_ERRNO();        PR_DELETE(lm);        goto unlock;    }    lm->name = strdup(name);    lm->dlh = h;    lm->next = pr_loadmap;    pr_loadmap = lm;    }#endif /* HAVE_DLL */#endif /* XP_UNIX */    lm->refCount = 1;#ifdef XP_BEOS    {        image_info info;        int32 cookie = 0;        image_id imageid = B_ERROR;        image_id stubid = B_ERROR;        PRLibrary *p;        for (p = pr_loadmap; p != NULL; p = p->next) {            /* hopefully, our caller will always use the same string               to refer to the same library */            if (strcmp(name, p->name) == 0) {                /* we've already loaded this library */                imageid = info.id;                lm->refCount++;                break;            }        }        if(imageid == B_ERROR) {            /* it appears the library isn't yet loaded - load it now */            char stubName [B_PATH_NAME_LENGTH + 1];            /* the following is a work-around to a "bug" in the beos -               the beos system loader allows only 32M (system-wide)               to be used by code loaded as "add-ons" (code loaded               through the 'load_add_on()' system call, which includes               mozilla components), but allows 256M to be used by               shared libraries.                              unfortunately, mozilla is too large to fit into the               "add-on" space, so we must trick the loader into               loading some of the components as shared libraries.  this               is accomplished by creating a "stub" add-on (an empty               shared object), and linking it with the component               (the actual .so file generated by the build process,               without any modifications).  when this stub is loaded               by load_add_on(), the loader will automatically load the               component into the shared library space.            */            strcpy(stubName, name);            strcat(stubName, ".stub");            /* first, attempt to load the stub (thereby loading the               component as a shared library */            if ((stubid = load_add_on(stubName)) > B_ERROR) {                /* the stub was loaded successfully. */                imageid = B_FILE_NOT_FOUND;                cookie = 0;                while (get_next_image_info(0, &cookie, &info) == B_OK) {                    char *endOfSystemName = strrchr(info.name, '/');                    char *endOfPassedName = strrchr(name, '/');                    if( 0 == endOfSystemName )                         endOfSystemName=info.name;                    else                        endOfSystemName++;                    if( 0 == endOfPassedName )                        endOfPassedName=name;                    else                        endOfPassedName++;                    if (strcmp(endOfSystemName, endOfPassedName) == 0) {                        /* this is the actual component - remember it */                        imageid = info.id;                        break;                    }                }            } else {                /* we failed to load the "stub" - try to load the                   component directly as an add-on */                stubid = B_ERROR;                imageid = load_add_on(name);            }        }        if (imageid <= B_ERROR) {            oserr = imageid;            PR_DELETE( lm );            goto unlock;        }        lm->name = strdup(name);        lm->dlh = (void*)imageid;        lm->stub_dlh = (void*)stubid;        lm->next = pr_loadmap;        pr_loadmap = lm;    }#endif    result = lm;    /* success */    PR_LOG(_pr_linker_lm, PR_LOG_MIN, ("Loaded library %s (load lib)", lm->name));  unlock:    if (result == NULL) {        PR_SetError(PR_LOAD_LIBRARY_ERROR, oserr);        DLLErrorInternal(oserr);  /* sets error text */    }    PR_ExitMonitor(pr_linker_lock);    return result;}PR_IMPLEMENT(PRLibrary*) PR_FindLibrary(const char *name){    PRLibrary* result;    if (!_pr_initialized) _PR_ImplicitInitialization();

⌨️ 快捷键说明

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