зеркало из https://github.com/mozilla/gecko-dev.git
Fix for bug #81659, r=pinkerton/wtc, sr=sfraser.
This commit is contained in:
Родитель
8efbae9be1
Коммит
66cad9ad74
|
@ -1,35 +1,19 @@
|
|||
/* -*- 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/
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.1 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* 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.
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Original Code is the Netscape Portable Runtime (NSPR).
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* The Initial Developer of this code under the NPL 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.
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#include "primpl.h"
|
||||
|
@ -47,6 +31,12 @@
|
|||
#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
|
||||
|
@ -107,6 +97,10 @@ struct PRLibrary {
|
|||
|
||||
#ifdef XP_MAC
|
||||
CFragConnectionID dlh;
|
||||
|
||||
#if TARGET_CARBON
|
||||
CFBundleRef bundle;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef XP_UNIX
|
||||
|
@ -488,6 +482,37 @@ PR_LoadLibrary(const char *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.
|
||||
|
@ -640,75 +665,19 @@ pr_LoadLibraryByPathname(const char *name, PRIntn flags)
|
|||
* of the file, and then (finally) make an FSSpec and call
|
||||
* GetDiskFragment.
|
||||
*/
|
||||
char* cMacPath = NULL;
|
||||
char* cFileName = NULL;
|
||||
char* position = NULL;
|
||||
CInfoPBRec pb;
|
||||
FSSpec fileSpec;
|
||||
PRUint32 index;
|
||||
Boolean tempUnusedBool;
|
||||
|
||||
/* Copy the name: we'll change it */
|
||||
cMacPath = strdup(name);
|
||||
if (cMacPath == NULL)
|
||||
{
|
||||
PStrFromCStr(name, pName);
|
||||
err = FSMakeFSSpec(0, 0, pName, &fileSpec);
|
||||
if (err != noErr) {
|
||||
oserr = _MD_ERRNO();
|
||||
PR_DELETE(lm);
|
||||
goto unlock;
|
||||
}
|
||||
|
||||
/* First, get the vRefNum */
|
||||
position = strchr(cMacPath, PR_PATH_SEPARATOR);
|
||||
if ((position == cMacPath) || (position == NULL))
|
||||
fileSpec.vRefNum = 0; /* Use application relative searching */
|
||||
else
|
||||
{
|
||||
char cVolName[32];
|
||||
memset(cVolName, 0, sizeof(cVolName));
|
||||
strncpy(cVolName, cMacPath, position-cMacPath);
|
||||
fileSpec.vRefNum = GetVolumeRefNumFromName(cVolName);
|
||||
}
|
||||
|
||||
/* Next, break the path and file name apart */
|
||||
index = 0;
|
||||
while (cMacPath[index] != 0)
|
||||
index++;
|
||||
while (cMacPath[index] != PR_PATH_SEPARATOR && index > 0)
|
||||
index--;
|
||||
if (index == 0 || index == strlen(cMacPath))
|
||||
{
|
||||
oserr = _MD_ERRNO();
|
||||
PR_DELETE(cMacPath);
|
||||
PR_DELETE(lm);
|
||||
goto unlock;
|
||||
}
|
||||
cMacPath[index] = 0;
|
||||
cFileName = &(cMacPath[index + 1]);
|
||||
|
||||
/* Convert the path and name into Pascal strings */
|
||||
PStrFromCStr(cMacPath, pName);
|
||||
PStrFromCStr(cFileName, fileSpec.name);
|
||||
strcpy(cName, cFileName);
|
||||
PR_DELETE(cMacPath);
|
||||
cMacPath = NULL;
|
||||
|
||||
/* Now we can look up the path on the volume */
|
||||
pb.dirInfo.ioNamePtr = pName;
|
||||
pb.dirInfo.ioVRefNum = fileSpec.vRefNum;
|
||||
pb.dirInfo.ioDrDirID = 0;
|
||||
pb.dirInfo.ioFDirIndex = 0;
|
||||
err = PBGetCatInfoSync(&pb);
|
||||
if (err != noErr)
|
||||
{
|
||||
oserr = err;
|
||||
PR_DELETE(lm);
|
||||
goto unlock;
|
||||
}
|
||||
fileSpec.parID = pb.dirInfo.ioDrDirID;
|
||||
|
||||
/* Resolve an alias if this was one */
|
||||
err = ResolveAliasFile(&fileSpec, true, &tempUnusedBool,
|
||||
&tempUnusedBool);
|
||||
err = ResolveAliasFile(&fileSpec, true, &tempUnusedBool, &tempUnusedBool);
|
||||
if (err != noErr)
|
||||
{
|
||||
oserr = err;
|
||||
|
@ -720,13 +689,30 @@ pr_LoadLibraryByPathname(const char *name, PRIntn flags)
|
|||
err = GetDiskFragment(&fileSpec, 0, kCFragGoesToEOF, fileSpec.name,
|
||||
kLoadCFrag, &connectionID, &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);
|
||||
|
@ -761,17 +747,9 @@ pr_LoadLibraryByPathname(const char *name, PRIntn flags)
|
|||
}
|
||||
h = dlopen(name, dl_flags);
|
||||
#elif defined(USE_HPSHL)
|
||||
int shl_flags = 0;
|
||||
int shl_flags = DYNAMIC_PATH;
|
||||
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;
|
||||
}
|
||||
|
@ -1097,6 +1075,11 @@ PR_UnloadLibrary(PRLibrary *lib)
|
|||
|
||||
#if defined(XP_MAC) && TARGET_RT_MAC_CFM
|
||||
/* Close the connection */
|
||||
#if TARGET_CARBON
|
||||
if (lib->bundle)
|
||||
CFRelease(lib->bundle);
|
||||
else
|
||||
#endif
|
||||
CloseConnection(&(lib->dlh));
|
||||
#endif
|
||||
|
||||
|
@ -1175,6 +1158,17 @@ pr_FindSymbolInLib(PRLibrary *lm, const char *name)
|
|||
#endif /* WIN32 || WIN16 */
|
||||
|
||||
#ifdef XP_MAC
|
||||
#if TARGET_CARBON
|
||||
if (lm->bundle)
|
||||
{
|
||||
CFStringRef nameRef = CFStringCreateWithCString(NULL, name, kCFStringEncodingASCII);
|
||||
if (nameRef) {
|
||||
f = CFBundleGetFunctionPointerForName(lm->bundle, nameRef);
|
||||
CFRelease(nameRef);
|
||||
}
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
Ptr symAddr;
|
||||
CFragSymbolClass symClass;
|
||||
|
@ -1261,15 +1255,6 @@ PR_FindSymbol(PRLibrary *lib, const char *raw_name)
|
|||
return f;
|
||||
}
|
||||
|
||||
/*
|
||||
** Return the address of the function 'raw_name' in the library 'lib'
|
||||
*/
|
||||
PR_IMPLEMENT(PRFuncPtr)
|
||||
PR_FindFunctionSymbol(PRLibrary *lib, const char *raw_name)
|
||||
{
|
||||
return ((PRFuncPtr) PR_FindSymbol(lib, raw_name));
|
||||
}
|
||||
|
||||
PR_IMPLEMENT(void*)
|
||||
PR_FindSymbolAndLibrary(const char *raw_name, PRLibrary* *lib)
|
||||
{
|
||||
|
@ -1321,12 +1306,6 @@ PR_FindSymbolAndLibrary(const char *raw_name, PRLibrary* *lib)
|
|||
return f;
|
||||
}
|
||||
|
||||
PR_IMPLEMENT(PRFuncPtr)
|
||||
PR_FindFunctionSymbolAndLibrary(const char *raw_name, PRLibrary* *lib)
|
||||
{
|
||||
return ((PRFuncPtr) PR_FindSymbolAndLibrary(raw_name, lib));
|
||||
}
|
||||
|
||||
/*
|
||||
** Add a static library to the list of loaded libraries. If LoadLibrary
|
||||
** is called with the name then we will pretend it was already loaded
|
||||
|
|
Загрузка…
Ссылка в новой задаче