Replace all use of POSIX truncate

Use `<filesystem>` instead of `truncate` and remove `truncate`
portability wrapper.

Add a helper function `StatusFromSystemError` to convert error_code to
`Status`.

Signed-off-by: Ralph Sennhauser <ralph.sennhauser@gmail.com>
This commit is contained in:
Ralph Sennhauser 2026-06-14 19:49:19 +02:00
parent 57f5b73458
commit 149baf116b
No known key found for this signature in database
7 changed files with 29 additions and 40 deletions

View file

@ -1,4 +1,4 @@
/* Copyright (C) 2025 Wildfire Games.
/* Copyright (C) 2026 Wildfire Games.
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
@ -38,7 +38,7 @@
#include "lib/posix/posix_aio.h" // LIO_READ, LIO_WRITE
#include "lib/posix/posix_types.h"
#include "lib/status.h"
#include "lib/sysdep/filesystem.h" // wtruncate
#include "lib/sysdep/filesystem.h"
#include "lib/sysdep/os.h"
#include "lib/sysdep/rtl.h"
#include "lib/types.h"
@ -47,7 +47,9 @@
#include <cstddef>
#include <cstdint>
#include <fcntl.h>
#include <filesystem>
#include <memory>
#include <system_error>
namespace ERR
{
@ -332,9 +334,12 @@ static inline Status Store(const OsPath& pathname, const void* data, size_t size
RETURN_STATUS_IF_ERR(io::Run(op, p, completedHook, issueHook));
file.Close(); // (required by wtruncate)
file.Close(); // (required by resize_file)
RETURN_STATUS_IF_ERR(wtruncate(pathname, size));
std::error_code ec{};
std::filesystem::resize_file(pathname.string(), size, ec);
if (ec)
return StatusFromSystemError(ec);
return INFO::OK;
}

View file

@ -1,4 +1,4 @@
/* Copyright (C) 2025 Wildfire Games.
/* Copyright (C) 2026 Wildfire Games.
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
@ -100,6 +100,16 @@ int ErrnoFromStatus(Status status)
return EPERM;
}
Status StatusFromSystemError(std::error_code& ec)
{
if (!ec)
return INFO::OK;
std::error_condition cond = ec.default_error_condition();
if (cond.category() != std::generic_category())
return ERR::FAIL;
const StatusDefinition* def = DefinitionFromErrno(cond.value());
return def ? def->status : ERR::FAIL;
}
Status StatusFromErrno()
{

View file

@ -1,4 +1,4 @@
/* Copyright (C) 2025 Wildfire Games.
/* Copyright (C) 2026 Wildfire Games.
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
@ -165,6 +165,7 @@ To summarize: +/-1SHHCC (S=subsystem, HH=header, CC=code number)
#include "lib/types.h"
#include <cstddef>
#include <system_error>
// an integral type allows defining error codes in separate headers,
// but is not as type-safe as an enum. use Lint's 'strong type' checking
@ -246,6 +247,11 @@ extern int ErrnoFromStatus(Status status);
**/
extern Status StatusFromErrno();
/**
* @return Status equivalent of error_code, or ERR::FAIL if there's no equivalent.
*/
extern Status StatusFromSystemError(std::error_code& ec);
// note: other conversion routines (e.g. to/from Win32) are implemented in
// the corresponding modules to keep this header portable.

View file

@ -56,18 +56,6 @@ extern int wopen(const OsPath& pathname, int oflag, mode_t mode);
extern int wclose(int fd);
//
// unistd.h
//
// waio requires offsets and sizes to be multiples of the sector size.
// to allow arbitrarily sized files, we truncate them after I/O.
// however, ftruncate cannot be used since it is also subject to the
// sector-alignment requirement. instead, the file must be closed and
// this function called.
int wtruncate(const OsPath& pathname, off_t length);
//
// stdlib.h
//

View file

@ -93,11 +93,6 @@ int wclose(int fd)
return close(fd);
}
int wtruncate(const OsPath& pathname, off_t length)
{
return truncate(OsString(pathname).c_str(), length);
}
int wrename(const OsPath& pathnameOld, const OsPath& pathnameNew)
{
return rename(OsString(pathnameOld).c_str(), OsString(pathnameNew).c_str());

View file

@ -1,4 +1,4 @@
/* Copyright (C) 2025 Wildfire Games.
/* Copyright (C) 2026 Wildfire Games.
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
@ -130,7 +130,7 @@ extern Status waio_close(int fd);
// @param size is rounded up to a multiple of maxSectorSize (required by
// SetEndOfFile; this could be avoided by using the undocumented
// NtSetInformationFile or SetFileInformationByHandle on Vista and later).
// use wtruncate after I/O is complete to chop off the excess padding.
// use truncate after I/O is complete to chop off the excess padding.
//
// NB: writes that extend a file (i.e. ALL WRITES when creating new files)
// are synchronous, which prevents overlapping I/O and other work.

View file

@ -131,21 +131,6 @@ int wclose(int fd)
}
int wtruncate(const OsPath& pathname, off_t length)
{
// (re-open the file to avoid the FILE_FLAG_NO_BUFFERING
// sector-alignment restriction)
HANDLE hFile = CreateFileW(OsString(pathname).c_str(), GENERIC_WRITE, 0, 0, OPEN_EXISTING, 0, 0);
ENSURE(hFile != INVALID_HANDLE_VALUE);
LARGE_INTEGER ofs; ofs.QuadPart = length;
WARN_IF_FALSE(SetFilePointerEx(hFile, ofs, 0, FILE_BEGIN));
WARN_IF_FALSE(SetEndOfFile(hFile));
WARN_IF_FALSE(CloseHandle(hFile));
return 0;
}
OsPath wrealpath(const OsPath& pathname)
{
wchar_t resolved[PATH_MAX];