From 6bf0a5cb5034a7e684dcc3500e841785237ce2dd Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sun, 7 Apr 2024 19:32:43 +0200 Subject: Adding upstream version 1:115.7.0. Signed-off-by: Daniel Baumann --- comm/mailnews/db/mork/morkFile.cpp | 738 +++++++++++++++++++++++++++++++++++++ 1 file changed, 738 insertions(+) create mode 100644 comm/mailnews/db/mork/morkFile.cpp (limited to 'comm/mailnews/db/mork/morkFile.cpp') diff --git a/comm/mailnews/db/mork/morkFile.cpp b/comm/mailnews/db/mork/morkFile.cpp new file mode 100644 index 0000000000..b7b7848cc2 --- /dev/null +++ b/comm/mailnews/db/mork/morkFile.cpp @@ -0,0 +1,738 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef _MDB_ +# include "mdb.h" +#endif + +#ifndef _MORK_ +# include "mork.h" +#endif + +#ifndef _MORKNODE_ +# include "morkNode.h" +#endif + +#ifndef _MORKENV_ +# include "morkEnv.h" +#endif + +#ifndef _MORKFILE_ +# include "morkFile.h" +#endif + +#ifdef MORK_WIN +# include "io.h" +# include +#endif + +#include "mozilla/Unused.h" +#include "nsString.h" + +// 456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789 + +// ````` ````` ````` ````` ````` +// { ===== begin morkNode interface ===== + +/*public virtual*/ void morkFile::CloseMorkNode( + morkEnv* ev) // CloseFile() only if open +{ + if (this->IsOpenNode()) { + this->MarkClosing(); + this->CloseFile(ev); + this->MarkShut(); + } +} + +/*public virtual*/ +morkFile::~morkFile() // assert CloseFile() executed earlier +{ + MORK_ASSERT(mFile_Frozen == 0); + MORK_ASSERT(mFile_DoTrace == 0); + MORK_ASSERT(mFile_IoOpen == 0); + MORK_ASSERT(mFile_Active == 0); +} + +/*public non-poly*/ +morkFile::morkFile(morkEnv* ev, const morkUsage& inUsage, nsIMdbHeap* ioHeap, + nsIMdbHeap* ioSlotHeap) + : morkObject(ev, inUsage, ioHeap, morkColor_kNone, (morkHandle*)0), + mFile_Frozen(0), + mFile_DoTrace(0), + mFile_IoOpen(0), + mFile_Active(0) + + , + mFile_SlotHeap(0), + mFile_Name(0), + mFile_Thief(0) { + if (ev->Good()) { + if (ioSlotHeap) { + nsIMdbHeap_SlotStrongHeap(ioSlotHeap, ev, &mFile_SlotHeap); + if (ev->Good()) mNode_Derived = morkDerived_kFile; + } else + ev->NilPointerError(); + } +} + +NS_IMPL_ISUPPORTS_INHERITED(morkFile, morkObject, nsIMdbFile) +/*public non-poly*/ void morkFile::CloseFile( + morkEnv* ev) // called by CloseMorkNode(); +{ + if (this->IsNode()) { + mFile_Frozen = 0; + mFile_DoTrace = 0; + mFile_IoOpen = 0; + mFile_Active = 0; + + if (mFile_Name) this->SetFileName(ev, nullptr); + + nsIMdbHeap_SlotStrongHeap((nsIMdbHeap*)0, ev, &mFile_SlotHeap); + nsIMdbFile_SlotStrongFile((nsIMdbFile*)0, ev, &mFile_Thief); + + this->MarkShut(); + } else + this->NonNodeError(ev); +} + +// } ===== end morkNode methods ===== +// ````` ````` ````` ````` ````` + +/*static*/ morkFile* morkFile::OpenOldFile(morkEnv* ev, nsIMdbHeap* ioHeap, + const PathChar* inFilePath, + mork_bool inFrozen) +// Choose some subclass of morkFile to instantiate, in order to read +// (and write if not frozen) the file known by inFilePath. The file +// returned should be open and ready for use, and presumably positioned +// at the first byte position of the file. The exact manner in which +// files must be opened is considered a subclass specific detail, and +// other portions or Mork source code don't want to know how it's done. +{ + return morkStdioFile::OpenOldStdioFile(ev, ioHeap, inFilePath, inFrozen); +} + +/*static*/ morkFile* morkFile::CreateNewFile(morkEnv* ev, nsIMdbHeap* ioHeap, + const PathChar* inFilePath) +// Choose some subclass of morkFile to instantiate, in order to read +// (and write if not frozen) the file known by inFilePath. The file +// returned should be created and ready for use, and presumably positioned +// at the first byte position of the file. The exact manner in which +// files must be opened is considered a subclass specific detail, and +// other portions or Mork source code don't want to know how it's done. +{ + return morkStdioFile::CreateNewStdioFile(ev, ioHeap, inFilePath); +} + +void morkFile::NewMissingIoError(morkEnv* ev) const { + ev->NewError("file missing io"); +} + +/*static*/ void morkFile::NonFileTypeError(morkEnv* ev) { + ev->NewError("non morkFile"); +} + +/*static*/ void morkFile::NilSlotHeapError(morkEnv* ev) { + ev->NewError("nil mFile_SlotHeap"); +} + +/*static*/ void morkFile::NilFileNameError(morkEnv* ev) { + ev->NewError("nil mFile_Name"); +} + +void morkFile::SetThief(morkEnv* ev, nsIMdbFile* ioThief) { + nsIMdbFile_SlotStrongFile(ioThief, ev, &mFile_Thief); +} + +void morkFile::SetFileName(morkEnv* ev, + const PathChar* inName) // inName can be nil +{ + nsIMdbHeap* heap = mFile_SlotHeap; + if (heap) { + PathChar* name = mFile_Name; + if (name) { + mFile_Name = 0; + ev->FreeString(heap, name); + } + if (ev->Good() && inName) mFile_Name = ev->CopyString(heap, inName); + } else + this->NilSlotHeapError(ev); +} + +void morkFile::NewFileDownError(morkEnv* ev) const +// call NewFileDownError() when either IsOpenAndActiveFile() +// is false, or when IsOpenActiveAndMutableFile() is false. +{ + if (this->IsOpenNode()) { + if (this->FileActive()) { + if (this->FileFrozen()) { + ev->NewError("file frozen"); + } else + ev->NewError("unknown file problem"); + } else + ev->NewError("file not active"); + } else + ev->NewError("file not open"); +} + +void morkFile::NewFileErrnoError(morkEnv* ev) const +// call NewFileErrnoError() to convert std C errno into AB fault +{ + const char* errnoString = strerror(errno); + ev->NewError(errnoString); // maybe pass value of strerror() instead +} + +// ````` ````` ````` ````` newlines ````` ````` ````` ````` + +#if defined(MORK_MAC) +static const char morkFile_kNewlines[] = + "\015\015\015\015\015\015\015\015\015\015\015\015\015\015\015\015"; +# define morkFile_kNewlinesCount 16 +#else +# if defined(MORK_WIN) +static const char morkFile_kNewlines[] = + "\015\012\015\012\015\012\015\012\015\012\015\012\015\012\015\012"; +# define morkFile_kNewlinesCount 8 +# else +# ifdef MORK_UNIX +static const char morkFile_kNewlines[] = + "\012\012\012\012\012\012\012\012\012\012\012\012\012\012\012\012"; +# define morkFile_kNewlinesCount 16 +# endif /* MORK_UNIX */ +# endif /* MORK_WIN */ +#endif /* MORK_MAC */ + +mork_size morkFile::WriteNewlines(morkEnv* ev, mork_count inNewlines) +// WriteNewlines() returns the number of bytes written. +{ + mork_size outSize = 0; + while (inNewlines && ev->Good()) // more newlines to write? + { + mork_u4 quantum = inNewlines; + if (quantum > morkFile_kNewlinesCount) quantum = morkFile_kNewlinesCount; + + mork_size quantumSize = quantum * mork_kNewlineSize; + mdb_size bytesWritten; + this->Write(ev->AsMdbEnv(), morkFile_kNewlines, quantumSize, &bytesWritten); + outSize += quantumSize; + inNewlines -= quantum; + } + return outSize; +} + +NS_IMETHODIMP +morkFile::Eof(nsIMdbEnv* mev, mdb_pos* outPos) { + nsresult outErr = NS_OK; + mdb_pos pos = -1; + morkEnv* ev = morkEnv::FromMdbEnv(mev); + pos = Length(ev); + outErr = ev->AsErr(); + if (outPos) *outPos = pos; + return outErr; +} + +NS_IMETHODIMP +morkFile::Get(nsIMdbEnv* mev, void* outBuf, mdb_size inSize, mdb_pos inPos, + mdb_size* outActualSize) { + nsresult rv = NS_OK; + morkEnv* ev = morkEnv::FromMdbEnv(mev); + if (ev) { + mdb_pos outPos; + Seek(mev, inPos, &outPos); + if (ev->Good()) rv = Read(mev, outBuf, inSize, outActualSize); + } + return rv; +} + +NS_IMETHODIMP +morkFile::Put(nsIMdbEnv* mev, const void* inBuf, mdb_size inSize, mdb_pos inPos, + mdb_size* outActualSize) { + nsresult outErr = NS_OK; + *outActualSize = 0; + morkEnv* ev = morkEnv::FromMdbEnv(mev); + if (ev) { + mdb_pos outPos; + + Seek(mev, inPos, &outPos); + if (ev->Good()) Write(mev, inBuf, inSize, outActualSize); + outErr = ev->AsErr(); + } + return outErr; +} + +// { ----- begin path methods ----- +NS_IMETHODIMP +morkFile::Path(nsIMdbEnv* mev, mdbYarn* outFilePath) { + nsresult outErr = NS_OK; + if (outFilePath) outFilePath->mYarn_Fill = 0; + morkEnv* ev = morkEnv::FromMdbEnv(mev); + if (ev) { + ev->StringToYarn(GetFileNameString(), outFilePath); + outErr = ev->AsErr(); + } + return outErr; +} + +// } ----- end path methods ----- + +// { ----- begin replacement methods ----- + +NS_IMETHODIMP +morkFile::Thief(nsIMdbEnv* mev, nsIMdbFile** acqThief) { + nsresult outErr = NS_OK; + nsIMdbFile* outThief = 0; + morkEnv* ev = morkEnv::FromMdbEnv(mev); + if (ev) { + outThief = GetThief(); + NS_IF_ADDREF(outThief); + outErr = ev->AsErr(); + } + if (acqThief) *acqThief = outThief; + return outErr; +} + +// } ----- end replacement methods ----- + +// { ----- begin versioning methods ----- + +// ````` ````` ````` ````` ````` +// { ===== begin morkNode interface ===== + +/*public virtual*/ void morkStdioFile::CloseMorkNode( + morkEnv* ev) // CloseStdioFile() only if open +{ + if (this->IsOpenNode()) { + this->MarkClosing(); + this->CloseStdioFile(ev); + this->MarkShut(); + } +} + +/*public virtual*/ +morkStdioFile::~morkStdioFile() // assert CloseStdioFile() executed earlier +{ + if (mStdioFile_File) CloseStdioFile(mMorkEnv); + MORK_ASSERT(mStdioFile_File == 0); +} + +/*public non-poly*/ void morkStdioFile::CloseStdioFile( + morkEnv* ev) // called by CloseMorkNode(); +{ + if (this->IsNode()) { + if (mStdioFile_File && this->FileActive() && this->FileIoOpen()) { + this->CloseStdio(ev); + } + + mStdioFile_File = 0; + + this->CloseFile(ev); + this->MarkShut(); + } else + this->NonNodeError(ev); +} + +// } ===== end morkNode methods ===== +// ````` ````` ````` ````` ````` + +// compatible with the morkFile::MakeFile() entry point + +/*static*/ morkStdioFile* morkStdioFile::OpenOldStdioFile( + morkEnv* ev, nsIMdbHeap* ioHeap, const PathChar* inFilePath, + mork_bool inFrozen) { + morkStdioFile* outFile = 0; + if (ioHeap && inFilePath) { + const char* mode = (inFrozen) ? "rb" : "rb+"; + outFile = new (*ioHeap, ev) + morkStdioFile(ev, morkUsage::kHeap, ioHeap, ioHeap, inFilePath, mode); + + if (outFile) { + outFile->SetFileFrozen(inFrozen); + } + } else + ev->NilPointerError(); + + return outFile; +} + +/*static*/ morkStdioFile* morkStdioFile::CreateNewStdioFile( + morkEnv* ev, nsIMdbHeap* ioHeap, const PathChar* inFilePath) { + morkStdioFile* outFile = 0; + if (ioHeap && inFilePath) { + const char* mode = "wb+"; + outFile = new (*ioHeap, ev) + morkStdioFile(ev, morkUsage::kHeap, ioHeap, ioHeap, inFilePath, mode); + } else + ev->NilPointerError(); + + return outFile; +} + +NS_IMETHODIMP +morkStdioFile::BecomeTrunk(nsIMdbEnv* ev) +// If this file is a file version branch created by calling AcquireBud(), +// BecomeTrunk() causes this file's content to replace the original +// file's content, typically by assuming the original file's identity. +{ + return Flush(ev); +} + +NS_IMETHODIMP +morkStdioFile::AcquireBud(nsIMdbEnv* mdbev, nsIMdbHeap* ioHeap, + nsIMdbFile** acquiredFile) +// AcquireBud() starts a new "branch" version of the file, empty of content, +// so that a new version of the file can be written. This new file +// can later be told to BecomeTrunk() the original file, so the branch +// created by budding the file will replace the original file. Some +// file subclasses might initially take the unsafe but expedient +// approach of simply truncating this file down to zero length, and +// then returning the same morkFile pointer as this, with an extra +// reference count increment. Note that the caller of AcquireBud() is +// expected to eventually call CutStrongRef() on the returned file +// in order to release the strong reference. High quality versions +// of morkFile subclasses will create entirely new files which later +// are renamed to become the old file, so that better transactional +// behavior is exhibited by the file, so crashes protect old files. +// Note that AcquireBud() is an illegal operation on readonly files. +{ + NS_ENSURE_ARG(acquiredFile); + MORK_USED_1(ioHeap); + nsresult rv = NS_OK; + morkFile* outFile = 0; + morkEnv* ev = morkEnv::FromMdbEnv(mdbev); + + if (this->IsOpenAndActiveFile()) { + FILE* file = (FILE*)mStdioFile_File; + if (file) { + // #ifdef MORK_WIN + // truncate(file, /*eof*/ 0); + // #else /*MORK_WIN*/ + PathChar* name = mFile_Name; + if (name) { + if (MORK_FILECLOSE(file) >= 0) { + this->SetFileActive(morkBool_kFalse); + this->SetFileIoOpen(morkBool_kFalse); + mStdioFile_File = 0; + + file = MORK_FILEOPEN( + name, "wb+"); // open for write, discarding old content + if (file) { + mStdioFile_File = file; + this->SetFileActive(morkBool_kTrue); + this->SetFileIoOpen(morkBool_kTrue); + this->SetFileFrozen(morkBool_kFalse); + } else + this->new_stdio_file_fault(ev); + } else + this->new_stdio_file_fault(ev); + } else + this->NilFileNameError(ev); + + // #endif /*MORK_WIN*/ + + if (ev->Good() && this->AddStrongRef(ev->AsMdbEnv())) { + outFile = this; + AddRef(); + } + } else if (mFile_Thief) { + rv = mFile_Thief->AcquireBud(ev->AsMdbEnv(), ioHeap, acquiredFile); + } else + this->NewMissingIoError(ev); + } else + this->NewFileDownError(ev); + + *acquiredFile = outFile; + return rv; +} + +mork_pos morkStdioFile::Length(morkEnv* ev) const { + mork_pos outPos = 0; + + if (this->IsOpenAndActiveFile()) { + FILE* file = (FILE*)mStdioFile_File; + if (file) { + long start = MORK_FILETELL(file); + if (start >= 0) { + long fore = MORK_FILESEEK(file, 0, SEEK_END); + if (fore >= 0) { + long eof = MORK_FILETELL(file); + if (eof >= 0) { + long back = MORK_FILESEEK(file, start, SEEK_SET); + if (back >= 0) + outPos = eof; + else + this->new_stdio_file_fault(ev); + } else + this->new_stdio_file_fault(ev); + } else + this->new_stdio_file_fault(ev); + } else + this->new_stdio_file_fault(ev); + } else if (mFile_Thief) + mFile_Thief->Eof(ev->AsMdbEnv(), &outPos); + else + this->NewMissingIoError(ev); + } else + this->NewFileDownError(ev); + + return outPos; +} + +NS_IMETHODIMP +morkStdioFile::Tell(nsIMdbEnv* ev, mork_pos* outPos) const { + nsresult rv = NS_OK; + NS_ENSURE_ARG(outPos); + morkEnv* mev = morkEnv::FromMdbEnv(ev); + if (this->IsOpenAndActiveFile()) { + FILE* file = (FILE*)mStdioFile_File; + if (file) { + long where = MORK_FILETELL(file); + if (where >= 0) + *outPos = where; + else + this->new_stdio_file_fault(mev); + } else if (mFile_Thief) + mFile_Thief->Tell(ev, outPos); + else + this->NewMissingIoError(mev); + } else + this->NewFileDownError(mev); + + return rv; +} + +NS_IMETHODIMP +morkStdioFile::Read(nsIMdbEnv* ev, void* outBuf, mork_size inSize, + mork_num* outCount) { + nsresult rv = NS_OK; + morkEnv* mev = morkEnv::FromMdbEnv(ev); + if (this->IsOpenAndActiveFile()) { + FILE* file = (FILE*)mStdioFile_File; + if (file) { + long count = (long)MORK_FILEREAD(outBuf, inSize, file); + if (count >= 0) { + *outCount = (mork_num)count; + } else + this->new_stdio_file_fault(mev); + } else if (mFile_Thief) + mFile_Thief->Read(ev, outBuf, inSize, outCount); + else + this->NewMissingIoError(mev); + } else + this->NewFileDownError(mev); + + return rv; +} + +NS_IMETHODIMP +morkStdioFile::Seek(nsIMdbEnv* mdbev, mork_pos inPos, mork_pos* aOutPos) { + mork_pos outPos = 0; + nsresult rv = NS_OK; + morkEnv* ev = morkEnv::FromMdbEnv(mdbev); + + if (this->IsOpenOrClosingNode() && this->FileActive()) { + FILE* file = (FILE*)mStdioFile_File; + if (file) { + long where = MORK_FILESEEK(file, inPos, SEEK_SET); + if (where >= 0) + outPos = inPos; + else + this->new_stdio_file_fault(ev); + } else if (mFile_Thief) + mFile_Thief->Seek(mdbev, inPos, aOutPos); + else + this->NewMissingIoError(ev); + } else + this->NewFileDownError(ev); + + *aOutPos = outPos; + return rv; +} + +NS_IMETHODIMP +morkStdioFile::Write(nsIMdbEnv* mdbev, const void* inBuf, mork_size inSize, + mork_size* aOutSize) { + mork_num outCount = 0; + nsresult rv = NS_OK; + morkEnv* ev = morkEnv::FromMdbEnv(mdbev); + if (this->IsOpenActiveAndMutableFile()) { + FILE* file = (FILE*)mStdioFile_File; + if (file) { + mozilla::Unused << fwrite(inBuf, 1, inSize, file); + if (!ferror(file)) + outCount = inSize; + else + this->new_stdio_file_fault(ev); + } else if (mFile_Thief) + mFile_Thief->Write(mdbev, inBuf, inSize, &outCount); + else + this->NewMissingIoError(ev); + } else + this->NewFileDownError(ev); + + *aOutSize = outCount; + return rv; +} + +NS_IMETHODIMP +morkStdioFile::Flush(nsIMdbEnv* mdbev) { + morkEnv* ev = morkEnv::FromMdbEnv(mdbev); + if (this->IsOpenOrClosingNode() && this->FileActive()) { + FILE* file = (FILE*)mStdioFile_File; + if (file) { + MORK_FILEFLUSH(file); + + } else if (mFile_Thief) + mFile_Thief->Flush(mdbev); + else + this->NewMissingIoError(ev); + } else + this->NewFileDownError(ev); + return NS_OK; +} + +// ````` ````` ````` ````` ````` ````` ````` ````` +// protected: // protected non-poly morkStdioFile methods + +void morkStdioFile::new_stdio_file_fault(morkEnv* ev) const { + FILE* file = (FILE*)mStdioFile_File; + + int copyErrno = errno; // facilitate seeing error in debugger + + // bunch of stuff not ported here + if (!copyErrno && file) { + copyErrno = ferror(file); + errno = copyErrno; + } + + this->NewFileErrnoError(ev); +} + +// ````` ````` ````` ````` ````` ````` ````` ````` +// public: // public non-poly morkStdioFile methods + +/*public non-poly*/ +morkStdioFile::morkStdioFile(morkEnv* ev, const morkUsage& inUsage, + nsIMdbHeap* ioHeap, nsIMdbHeap* ioSlotHeap) + : morkFile(ev, inUsage, ioHeap, ioSlotHeap), mStdioFile_File(0) { + if (ev->Good()) mNode_Derived = morkDerived_kStdioFile; +} + +morkStdioFile::morkStdioFile(morkEnv* ev, const morkUsage& inUsage, + nsIMdbHeap* ioHeap, nsIMdbHeap* ioSlotHeap, + const PathChar* inName, const char* inMode) + // calls OpenStdio() after construction + : morkFile(ev, inUsage, ioHeap, ioSlotHeap), mStdioFile_File(0) { + if (ev->Good()) this->OpenStdio(ev, inName, inMode); +} + +morkStdioFile::morkStdioFile(morkEnv* ev, const morkUsage& inUsage, + nsIMdbHeap* ioHeap, nsIMdbHeap* ioSlotHeap, + void* ioFile, const PathChar* inName, + mork_bool inFrozen) + // calls UseStdio() after construction + : morkFile(ev, inUsage, ioHeap, ioSlotHeap), mStdioFile_File(0) { + if (ev->Good()) this->UseStdio(ev, ioFile, inName, inFrozen); +} + +void morkStdioFile::OpenStdio(morkEnv* ev, const PathChar* inName, + const char* inMode) +// Open a new FILE with name inName, using mode flags from inMode. +{ + if (ev->Good()) { + if (!inMode) inMode = ""; + + mork_bool frozen = (*inMode == 'r'); // cursory attempt to note readonly + + if (this->IsOpenNode()) { + if (!this->FileActive()) { + this->SetFileIoOpen(morkBool_kFalse); + if (inName && *inName) { + this->SetFileName(ev, inName); + if (ev->Good()) { + FILE* file = MORK_FILEOPEN(inName, inMode); + if (file) { + mStdioFile_File = file; + this->SetFileActive(morkBool_kTrue); + this->SetFileIoOpen(morkBool_kTrue); + this->SetFileFrozen(frozen); + } else + this->new_stdio_file_fault(ev); + } + } else + ev->NewError("no file name"); + } else + ev->NewError("file already active"); + } else + this->NewFileDownError(ev); + } +} + +void morkStdioFile::UseStdio(morkEnv* ev, void* ioFile, const PathChar* inName, + mork_bool inFrozen) +// Use an existing file, like stdin/stdout/stderr, which should not +// have the io stream closed when the file is closed. The ioFile +// parameter must actually be of type FILE (but we don't want to make +// this header file include the stdio.h header file). +{ + if (ev->Good()) { + if (this->IsOpenNode()) { + if (!this->FileActive()) { + if (ioFile) { + this->SetFileIoOpen(morkBool_kFalse); + this->SetFileName(ev, inName); + if (ev->Good()) { + mStdioFile_File = ioFile; + this->SetFileActive(morkBool_kTrue); + this->SetFileFrozen(inFrozen); + } + } else + ev->NilPointerError(); + } else + ev->NewError("file already active"); + } else + this->NewFileDownError(ev); + } +} + +void morkStdioFile::CloseStdio(morkEnv* ev) +// Close the stream io if both and FileActive() and FileIoOpen(), but +// this does not close this instances (like CloseStdioFile() does). +// If stream io was made active by means of calling UseStdio(), +// then this method does little beyond marking the stream inactive +// because FileIoOpen() is false. +{ + if (mStdioFile_File && this->FileActive() && this->FileIoOpen()) { + FILE* file = (FILE*)mStdioFile_File; + if (MORK_FILECLOSE(file) < 0) this->new_stdio_file_fault(ev); + + mStdioFile_File = 0; + this->SetFileActive(morkBool_kFalse); + this->SetFileIoOpen(morkBool_kFalse); + } +} + +NS_IMETHODIMP +morkStdioFile::Steal(nsIMdbEnv* ev, nsIMdbFile* ioThief) +// If this file is a file version branch created by calling AcquireBud(), +// BecomeTrunk() causes this file's content to replace the original +// file's content, typically by assuming the original file's identity. +{ + morkEnv* mev = morkEnv::FromMdbEnv(ev); + if (mStdioFile_File && FileActive() && FileIoOpen()) { + FILE* file = (FILE*)mStdioFile_File; + if (MORK_FILECLOSE(file) < 0) new_stdio_file_fault(mev); + + mStdioFile_File = 0; + } + SetThief(mev, ioThief); + return NS_OK; +} + +#if defined(MORK_WIN) + +void mork_fileflush(FILE* file) { fflush(file); } + +#endif /*MORK_WIN*/ + +// 456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789 -- cgit v1.2.3