aboutsummaryrefslogtreecommitdiff
path: root/programs/utils.c
diff options
context:
space:
mode:
authorAndroid Build Coastguard Worker <android-build-coastguard-worker@google.com>2022-05-17 07:30:55 +0000
committerAndroid Build Coastguard Worker <android-build-coastguard-worker@google.com>2022-05-17 07:30:55 +0000
commit802267b91d9dc1f571fa6a37df10e1b909f18aa7 (patch)
treebf153cc41ae7aeecb590993a582eca8ca07f988b /programs/utils.c
parent596ec1420a085648278e390b61ed1cadb5d08fc3 (diff)
parent84ff393b112706a82c491b8c8e6062635b503670 (diff)
downloadfsverity-utils-802267b91d9dc1f571fa6a37df10e1b909f18aa7.tar.gz
Snap for 8603585 from 84ff393b112706a82c491b8c8e6062635b503670 to mainline-tzdata3-release
Change-Id: Ic3b14af99349669e66a66d37f2b3532f0966ac43
Diffstat (limited to 'programs/utils.c')
-rw-r--r--programs/utils.c59
1 files changed, 59 insertions, 0 deletions
diff --git a/programs/utils.c b/programs/utils.c
index ce19b57..116eb95 100644
--- a/programs/utils.c
+++ b/programs/utils.c
@@ -13,10 +13,14 @@
#include <errno.h>
#include <fcntl.h>
+#include <inttypes.h>
#include <limits.h>
#include <stdarg.h>
#include <sys/stat.h>
#include <unistd.h>
+#ifdef _WIN32
+# include <windows.h>
+#endif
/* ========== Memory allocation ========== */
@@ -126,6 +130,26 @@ bool get_file_size(struct filedes *file, u64 *size_ret)
return true;
}
+bool preallocate_file(struct filedes *file, u64 size)
+{
+ int res;
+
+ if (size == 0)
+ return true;
+#ifdef _WIN32
+ /* Not exactly the same as posix_fallocate(), but good enough... */
+ res = _chsize_s(file->fd, size);
+#else
+ res = posix_fallocate(file->fd, 0, size);
+#endif
+ if (res != 0) {
+ error_msg_errno("preallocating %" PRIu64 "-byte file '%s'",
+ size, file->name);
+ return false;
+ }
+ return true;
+}
+
bool full_read(struct filedes *file, void *buf, size_t count)
{
while (count) {
@@ -160,6 +184,41 @@ bool full_write(struct filedes *file, const void *buf, size_t count)
return true;
}
+static int raw_pwrite(int fd, const void *buf, int count, u64 offset)
+{
+#ifdef _WIN32
+ HANDLE h = (HANDLE)_get_osfhandle(fd);
+ OVERLAPPED pos = { .Offset = offset, .OffsetHigh = offset >> 32 };
+ DWORD written = 0;
+
+ /* Not exactly the same as pwrite(), but good enough... */
+ if (!WriteFile(h, buf, count, &written, &pos)) {
+ errno = EIO;
+ return -1;
+ }
+ return written;
+#else
+ return pwrite(fd, buf, count, offset);
+#endif
+}
+
+bool full_pwrite(struct filedes *file, const void *buf, size_t count,
+ u64 offset)
+{
+ while (count) {
+ int n = raw_pwrite(file->fd, buf, min(count, INT_MAX), offset);
+
+ if (n < 0) {
+ error_msg_errno("writing to '%s'", file->name);
+ return false;
+ }
+ buf += n;
+ count -= n;
+ offset += n;
+ }
+ return true;
+}
+
bool filedes_close(struct filedes *file)
{
int res;