diff --git a/src/fs/FileSystem.cxx b/src/fs/FileSystem.cxx index 59571e138..b2d4c69da 100644 --- a/src/fs/FileSystem.cxx +++ b/src/fs/FileSystem.cxx @@ -21,8 +21,10 @@ #include "FileSystem.hxx" #include "AllocatedPath.hxx" #include "Limits.hxx" +#include "system/Error.hxx" #include +#include AllocatedPath ReadLink(Path path) @@ -44,3 +46,23 @@ ReadLink(Path path) return AllocatedPath::FromFS(buffer); #endif } + +void +TruncateFile(Path path) +{ +#ifdef WIN32 + HANDLE h = CreateFile(path.c_str(), GENERIC_WRITE, 0, nullptr, + TRUNCATE_EXISTING, FILE_ATTRIBUTE_NORMAL, + nullptr); + if (h == INVALID_HANDLE_VALUE) + throw FormatLastError("Failed to truncate %s", path.c_str()); + + CloseHandle(h); +#else + int fd = open_cloexec(path.c_str(), O_WRONLY|O_TRUNC, 0); + if (fd < 0) + throw FormatErrno("Failed to truncate %s", path.c_str()); + + close(fd); +#endif +} diff --git a/src/fs/FileSystem.hxx b/src/fs/FileSystem.hxx index d76c159fb..b6c4d59e3 100644 --- a/src/fs/FileSystem.hxx +++ b/src/fs/FileSystem.hxx @@ -104,6 +104,13 @@ StatFile(Path file, struct stat &buf, bool follow_symlinks = true) #endif +/** + * Truncate a file that exists already. Throws std::system_error on + * error. + */ +void +TruncateFile(Path path); + /** * Wrapper for unlink() that uses #Path names. */