diff options
Diffstat (limited to 'toolkit/profile/nsProfileLock.cpp')
-rw-r--r-- | toolkit/profile/nsProfileLock.cpp | 72 |
1 files changed, 70 insertions, 2 deletions
diff --git a/toolkit/profile/nsProfileLock.cpp b/toolkit/profile/nsProfileLock.cpp index 654fbcd465..d75b6082d3 100644 --- a/toolkit/profile/nsProfileLock.cpp +++ b/toolkit/profile/nsProfileLock.cpp @@ -13,6 +13,11 @@ #include "nsAutoPtr.h" #endif +#if defined(XP_MACOSX) +#include <Carbon/Carbon.h> +#include <CoreFoundation/CoreFoundation.h> +#endif + #ifdef XP_UNIX #include <unistd.h> #include <fcntl.h> @@ -421,7 +426,10 @@ nsresult nsProfileLock::GetReplacedLockTime(PRTime *aResult) { nsresult nsProfileLock::Lock(nsIFile* aProfileDir, nsIProfileUnlocker* *aUnlocker) { -#if defined (XP_UNIX) +#if defined (XP_MACOSX) + NS_NAMED_LITERAL_STRING(LOCKFILE_NAME, ".parentlock"); + NS_NAMED_LITERAL_STRING(OLD_LOCKFILE_NAME, "parent.lock"); +#elif defined (XP_UNIX) NS_NAMED_LITERAL_STRING(OLD_LOCKFILE_NAME, "lock"); NS_NAMED_LITERAL_STRING(LOCKFILE_NAME, ".parentlock"); #else @@ -450,7 +458,67 @@ nsresult nsProfileLock::Lock(nsIFile* aProfileDir, if (NS_FAILED(rv)) return rv; -#if defined(XP_UNIX) +#if defined(XP_MACOSX) + // First, try locking using fcntl. It is more reliable on + // a local machine, but may not be supported by an NFS server. + + rv = LockWithFcntl(lockFile); + if (NS_FAILED(rv) && (rv != NS_ERROR_FILE_ACCESS_DENIED)) + { + // If that failed for any reason other than NS_ERROR_FILE_ACCESS_DENIED, + // assume we tried an NFS that does not support it. Now, try with symlink. + rv = LockWithSymlink(lockFile, false); + } + + if (NS_SUCCEEDED(rv)) + { + // Check for the old-style lock used by pre-mozilla 1.3 builds. + // Those builds used an earlier check to prevent the application + // from launching if another instance was already running. Because + // of that, we don't need to create an old-style lock as well. + struct LockProcessInfo + { + ProcessSerialNumber psn; + unsigned long launchDate; + }; + + PRFileDesc *fd = nullptr; + int32_t ioBytes; + ProcessInfoRec processInfo; + LockProcessInfo lockProcessInfo; + + rv = lockFile->SetLeafName(OLD_LOCKFILE_NAME); + if (NS_FAILED(rv)) + return rv; + rv = lockFile->OpenNSPRFileDesc(PR_RDONLY, 0, &fd); + if (NS_SUCCEEDED(rv)) + { + ioBytes = PR_Read(fd, &lockProcessInfo, sizeof(LockProcessInfo)); + PR_Close(fd); + + if (ioBytes == sizeof(LockProcessInfo)) + { +#ifdef __LP64__ + processInfo.processAppRef = nullptr; +#else + processInfo.processAppSpec = nullptr; +#endif + processInfo.processName = nullptr; + processInfo.processInfoLength = sizeof(ProcessInfoRec); + if (::GetProcessInformation(&lockProcessInfo.psn, &processInfo) == noErr && + processInfo.processLaunchDate == lockProcessInfo.launchDate) + { + return NS_ERROR_FILE_ACCESS_DENIED; + } + } + else + { + NS_WARNING("Could not read lock file - ignoring lock"); + } + } + rv = NS_OK; // Don't propagate error from OpenNSPRFileDesc. + } +#elif defined(XP_UNIX) // Get the old lockfile name nsCOMPtr<nsIFile> oldLockFile; rv = aProfileDir->Clone(getter_AddRefs(oldLockFile)); |