diff --git a/mozilla/netwerk/base/src/nsFileStreams.cpp b/mozilla/netwerk/base/src/nsFileStreams.cpp index d75edd62222..f29ed92fddc 100644 --- a/mozilla/netwerk/base/src/nsFileStreams.cpp +++ b/mozilla/netwerk/base/src/nsFileStreams.cpp @@ -507,9 +507,22 @@ nsSafeFileOutputStream::Init(nsIFile* file, PRInt32 ioFlags, PRInt32 perm, mTargetFileExists = PR_TRUE; // Safer to assume it exists - we just do more work. } - // XXXdwitte I think we want to be following symlinks here... see e.g. bug 206567. - nsCOMPtr tempResult; - rv = file->Clone(getter_AddRefs(tempResult)); + // follow symlinks, for two reasons: + // 1) if a user has deliberately set up a profile file as a symlink, we honor it + // 2) to make the MoveToNative() in Finish() an atomic operation (which may not + // be the case if moving across directories on different filesystems). + nsCOMPtr tempResult = do_CreateInstance("@mozilla.org/file/local;1", &rv); + if (NS_SUCCEEDED(rv)) { + nsCOMPtr tempLocal = do_QueryInterface(tempResult); + tempLocal->SetFollowLinks(PR_TRUE); + nsCOMPtr fileLocal = do_QueryInterface(file, &rv); + if (NS_SUCCEEDED(rv)) + rv = tempLocal->InitWithFile(fileLocal); + } + // XP_UNIX ignores SetFollowLinks(), so we have to normalize. + if (NS_SUCCEEDED(rv)) + rv = tempResult->Normalize(); + if (NS_SUCCEEDED(rv) && mTargetFileExists) { PRUint32 origPerm; if (NS_FAILED(file->GetPermissions(&origPerm))) { @@ -596,7 +609,7 @@ nsSafeFileOutputStream::Write(const char *buf, PRUint32 count, PRUint32 *result) else if (count != *result) mWriteResult = NS_ERROR_LOSS_OF_SIGNIFICANT_DATA; - if (NS_FAILED(mWriteResult)) + if (NS_FAILED(mWriteResult) && count > 0) NS_WARNING("writing to output stream failed! data may be lost"); } return rv;