summaryrefslogtreecommitdiff
path: root/src/fs
diff options
context:
space:
mode:
authorMax Kellermann <max.kellermann@gmail.com>2016-08-15 22:13:38 +0200
committerMax Kellermann <max.kellermann@gmail.com>2016-08-15 22:13:38 +0200
commit2bca3cd24746a3dd365f1478b185160fe84b5033 (patch)
tree1415b102c7334f0950136d073996ba11eb3af65a /src/fs
parent22a353b8e3402f814b3f88719e3ecda8672700bb (diff)
fs/FileSystem: add TruncateFile()
Diffstat (limited to 'src/fs')
-rw-r--r--src/fs/FileSystem.cxx22
-rw-r--r--src/fs/FileSystem.hxx7
2 files changed, 29 insertions, 0 deletions
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 <errno.h>
+#include <fcntl.h>
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
@@ -105,6 +105,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.
*/
static inline bool