Skip to content

Commit

Permalink
Fix (FileStream): Fix truncating file on Unix
Browse files Browse the repository at this point in the history
  • Loading branch information
smlu committed Jun 27, 2020
1 parent de0660f commit 85de7ac
Show file tree
Hide file tree
Showing 4 changed files with 25 additions and 21 deletions.
32 changes: 18 additions & 14 deletions libraries/libim/io/impl/filestream.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -69,10 +69,6 @@ struct FileStream::FileStreamImpl
mode(mode),
filePath(std::move(fp))
{
if(truncate && mode != Read) {
std::filesystem::remove(filePath);
}

auto flags = [&]()
{
switch (mode)
Expand All @@ -85,12 +81,11 @@ struct FileStream::FileStreamImpl
return static_cast<DWORD>(-1);
#else
case Read: return O_RDONLY;
case Write: return O_WRONLY | O_CREAT | O_TRUNC;
case ReadWrite: return O_RDWR | O_CREAT | O_TRUNC;
case Write: return O_WRONLY | O_CREAT;
case ReadWrite: return O_RDWR | O_CREAT;
default:
return -1;
#endif

}
}();

Expand All @@ -105,33 +100,38 @@ struct FileStream::FileStreamImpl
to flag param of function CreateFileX.
See: https://docs.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-flushfilebuffers#remarks
*/
DWORD dwCreationDisposition = flags == GENERIC_READ ? OPEN_EXISTING : OPEN_ALWAYS;
#if _WIN32_WINNT >= _WIN32_WINNT_WIN8
std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>> converter;
std::wstring wPath = converter.from_bytes(filePath.c_str());

hFile = CreateFile2(
wPath.c_str(),
flags,
FILE_SHARE_READ,
(flags == GENERIC_READ ? OPEN_EXISTING : OPEN_ALWAYS),
dwCreationDisposition,
nullptr
);
#else
hFile = CreateFileA(
filePath.c_str(),
flags,
FILE_SHARE_READ,
NULL,
(flags == GENERIC_READ ? OPEN_EXISTING : OPEN_ALWAYS),
nullptr,
dwCreationDisposition,
FILE_ATTRIBUTE_NORMAL,
NULL
nullptr
);
#endif

if (hFile == INVALID_HANDLE_VALUE) {
throw FileStreamError(getLastErrorAsString());
}

/* Truncate file if writable */
if ((flags & GENERIC_WRITE) && truncate && !SetEndOfFile(hFile)) {
throw FileStreamError(getLastErrorAsString());
}

/* Get file size */
LARGE_INTEGER lSize {{0, 0}};
if(!GetFileSizeEx(hFile, &lSize)) {
Expand All @@ -144,8 +144,12 @@ struct FileStream::FileStreamImpl
fileSize = lSize.LowPart;
#endif

#else // Not Win
#else // Unix
/* Open file */
if (mode != Read && truncate) {
flags |= O_TRUNC;
}

fd = open(filePath.c_str(), flags, (mode_t)0600);
if (fd == -1) {
throw FileStreamError(strerror(errno));
Expand Down Expand Up @@ -257,7 +261,7 @@ struct FileStream::FileStreamImpl
#ifdef OS_WINDOWS
LARGE_INTEGER li;
li.QuadPart = offset;
li.LowPart = SetFilePointer(hFile, li.LowPart, &li.HighPart, FILE_BEGIN);
li.LowPart = SetFilePointer(hFile, li.LowPart, &li.HighPart, FILE_BEGIN);
if (li.LowPart == INVALID_SET_FILE_POINTER && GetLastError() != NO_ERROR) {
#else
auto off = lseek(fd, offset, SEEK_SET);
Expand Down
8 changes: 4 additions & 4 deletions programs/cndtool/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -619,7 +619,7 @@ std::size_t extractAnimations(const InputStream& istream, const std::string& out
}

std::string keyFilePath(keyDir + "/" + key.name());
OutputFileStream ofs(std::move(keyFilePath));
OutputFileStream ofs(std::move(keyFilePath), /*truncate=*/true);
key.serialize(TextResourceWriter(ofs), keyHeaderComment);
}

Expand Down Expand Up @@ -668,7 +668,7 @@ std::size_t extractMaterials(const InputStream& istream, const std::string& outD
}

std::string matFilePath(matDir + "/" + mat.name());
mat.serialize(OutputFileStream(std::move(matFilePath)));
mat.serialize(OutputFileStream(std::move(matFilePath), /*truncate=*/true));

if(opt.verboseOutput)
{
Expand Down Expand Up @@ -759,14 +759,14 @@ std::size_t extractSounds(const InputStream& istream, const std::string& outDir,
std::cout << "Extracting sound: " << s.name() << std::endl;
}

OutputFileStream ofs(outPath.append(s.name()));
OutputFileStream ofs(outPath.append(s.name()), /*truncate=*/true);
s.serialize(ofs, Sound::SerializeFormat::IndyWV);
outPath = outPath.parent_path();

/* Save in WAV format */
if(opt.sound.convertToWav)
{
OutputFileStream ofs(wavDir.append(s.name()));
OutputFileStream ofs(wavDir.append(s.name()), /*truncate=*/true);
s.serialize(ofs, Sound::SerializeFormat::WAV);
wavDir = wavDir.parent_path();
}
Expand Down
4 changes: 2 additions & 2 deletions programs/cndtool/patch.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ using namespace libim::utils;

/* Open new output cnd file */
const std::string patchedCndFile = cndFile + ".patched";
OutputFileStream ofstream(patchedCndFile);
OutputFileStream ofstream(patchedCndFile, /*truncate=*/true);

/* Copy input cnd file to output stream until materials section */
const auto matSectionOffset = CND::getOffset_Materials(ifstream);
Expand Down Expand Up @@ -78,7 +78,7 @@ using namespace libim::utils;

/* Open new output cnd file */
const std::string patchedCndFile = cndFile + ".patched";
OutputFileStream ofstream(patchedCndFile);
OutputFileStream ofstream(patchedCndFile, /*truncate=*/true);

/* Copy input cnd file to output stream until materials section */
const auto keySectionOffset = CND::getOffset_Keyframes(ifstream, cndHeader);
Expand Down
2 changes: 1 addition & 1 deletion programs/gobext/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ bool extractGob(std::shared_ptr<const GobFileDirectory> gobDir, std::string outD
}

/* Open output file stream */
OutputFileStream ofs(outPath);
OutputFileStream ofs(outPath, /*truncate=*/true);

/* Write entry to file */
ByteArray buffer(4096);
Expand Down

0 comments on commit 85de7ac

Please # to comment.