diff options
Diffstat (limited to 'programs')
-rw-r--r-- | programs/cmd_digest.c | 7 | ||||
-rw-r--r-- | programs/cmd_dump_metadata.c | 163 | ||||
-rw-r--r-- | programs/cmd_sign.c | 57 | ||||
-rw-r--r-- | programs/fsverity.c | 101 | ||||
-rw-r--r-- | programs/fsverity.h | 13 | ||||
-rw-r--r-- | programs/test_compute_digest.c | 133 | ||||
-rw-r--r-- | programs/utils.c | 59 | ||||
-rw-r--r-- | programs/utils.h | 3 |
8 files changed, 22 insertions, 514 deletions
diff --git a/programs/cmd_digest.c b/programs/cmd_digest.c index fd9f4de..1a3c769 100644 --- a/programs/cmd_digest.c +++ b/programs/cmd_digest.c @@ -18,8 +18,6 @@ static const struct option longopts[] = { {"hash-alg", required_argument, NULL, OPT_HASH_ALG}, {"block-size", required_argument, NULL, OPT_BLOCK_SIZE}, {"salt", required_argument, NULL, OPT_SALT}, - {"out-merkle-tree", required_argument, NULL, OPT_OUT_MERKLE_TREE}, - {"out-descriptor", required_argument, NULL, OPT_OUT_DESCRIPTOR}, {"compact", no_argument, NULL, OPT_COMPACT}, {"for-builtin-sig", no_argument, NULL, OPT_FOR_BUILTIN_SIG}, {NULL, 0, NULL, 0} @@ -42,8 +40,6 @@ int fsverity_cmd_digest(const struct fsverity_command *cmd, case OPT_HASH_ALG: case OPT_BLOCK_SIZE: case OPT_SALT: - case OPT_OUT_MERKLE_TREE: - case OPT_OUT_DESCRIPTOR: if (!parse_tree_param(c, optarg, &tree_params)) goto out_usage; break; @@ -118,8 +114,7 @@ int fsverity_cmd_digest(const struct fsverity_command *cmd, } status = 0; out: - if (!destroy_tree_params(&tree_params) && status == 0) - status = 1; + destroy_tree_params(&tree_params); return status; out_err: diff --git a/programs/cmd_dump_metadata.c b/programs/cmd_dump_metadata.c deleted file mode 100644 index 94cc8ec..0000000 --- a/programs/cmd_dump_metadata.c +++ /dev/null @@ -1,163 +0,0 @@ -// SPDX-License-Identifier: MIT -/* - * The 'fsverity dump_metadata' command - * - * Copyright 2021 Google LLC - * - * Use of this source code is governed by an MIT-style - * license that can be found in the LICENSE file or at - * https://opensource.org/licenses/MIT. - */ - -#include "fsverity.h" - -#include <fcntl.h> -#include <getopt.h> -#include <sys/ioctl.h> -#include <unistd.h> - -static const struct option longopts[] = { - {"offset", required_argument, NULL, OPT_OFFSET}, - {"length", required_argument, NULL, OPT_LENGTH}, - {NULL, 0, NULL, 0} -}; - -static const struct { - const char *name; - int val; -} metadata_types[] = { - {"merkle_tree", FS_VERITY_METADATA_TYPE_MERKLE_TREE}, - {"descriptor", FS_VERITY_METADATA_TYPE_DESCRIPTOR}, - {"signature", FS_VERITY_METADATA_TYPE_SIGNATURE}, -}; - -static bool parse_metadata_type(const char *name, __u64 *val_ret) -{ - size_t i; - - for (i = 0; i < ARRAY_SIZE(metadata_types); i++) { - if (strcmp(name, metadata_types[i].name) == 0) { - *val_ret = metadata_types[i].val; - return true; - } - } - error_msg("unknown metadata type: %s", name); - fputs(" Expected", stderr); - for (i = 0; i < ARRAY_SIZE(metadata_types); i++) { - if (i != 0 && ARRAY_SIZE(metadata_types) > 2) - putc(',', stderr); - putc(' ', stderr); - if (i != 0 && i == ARRAY_SIZE(metadata_types) - 1) - fputs("or ", stderr); - fprintf(stderr, "\"%s\"", metadata_types[i].name); - } - fprintf(stderr, "\n"); - return false; -} - -/* Dump the fs-verity metadata of the given file. */ -int fsverity_cmd_dump_metadata(const struct fsverity_command *cmd, - int argc, char *argv[]) -{ - bool offset_specified = false; - bool length_specified = false; - struct filedes file = { .fd = -1 }; - struct filedes stdout_filedes = { .fd = STDOUT_FILENO, - .name = "stdout" }; - struct fsverity_read_metadata_arg arg = { .length = 32768 }; - void *buf = NULL; - char *tmp; - int c; - int status; - int bytes_read; - - while ((c = getopt_long(argc, argv, "", longopts, NULL)) != -1) { - switch (c) { - case OPT_OFFSET: - if (offset_specified) { - error_msg("--offset can only be specified once"); - goto out_usage; - } - errno = 0; - arg.offset = strtoull(optarg, &tmp, 10); - if (errno || *tmp) { - error_msg("invalid value for --offset"); - goto out_usage; - } - offset_specified = true; - break; - case OPT_LENGTH: - if (length_specified) { - error_msg("--length can only be specified once"); - goto out_usage; - } - errno = 0; - arg.length = strtoull(optarg, &tmp, 10); - if (errno || *tmp || arg.length > SIZE_MAX) { - error_msg("invalid value for --length"); - goto out_usage; - } - length_specified = true; - break; - default: - goto out_usage; - } - } - - argv += optind; - argc -= optind; - - if (argc != 2) - goto out_usage; - - if (!parse_metadata_type(argv[0], &arg.metadata_type)) - goto out_usage; - - if (length_specified && !offset_specified) { - error_msg("--length specified without --offset"); - goto out_usage; - } - if (offset_specified && !length_specified) { - error_msg("--offset specified without --length"); - goto out_usage; - } - - buf = xzalloc(arg.length); - arg.buf_ptr = (uintptr_t)buf; - - if (!open_file(&file, argv[1], O_RDONLY, 0)) - goto out_err; - - /* - * If --offset and --length were specified, then do only the single read - * requested. Otherwise read until EOF. - */ - do { - bytes_read = ioctl(file.fd, FS_IOC_READ_VERITY_METADATA, &arg); - if (bytes_read < 0) { - error_msg_errno("FS_IOC_READ_VERITY_METADATA failed on '%s'", - file.name); - goto out_err; - } - if (bytes_read == 0) - break; - if (!full_write(&stdout_filedes, buf, bytes_read)) - goto out_err; - arg.offset += bytes_read; - } while (!length_specified); - - status = 0; -out: - free(buf); - filedes_close(&file); - return status; - -out_err: - status = 1; - goto out; - -out_usage: - usage(cmd, stderr); - status = 2; - goto out; -} diff --git a/programs/cmd_sign.c b/programs/cmd_sign.c index aab8f00..47ba6a2 100644 --- a/programs/cmd_sign.c +++ b/programs/cmd_sign.c @@ -27,16 +27,11 @@ static bool write_signature(const char *filename, const u8 *sig, u32 sig_size) } static const struct option longopts[] = { - {"key", required_argument, NULL, OPT_KEY}, - {"cert", required_argument, NULL, OPT_CERT}, - {"pkcs11-engine", required_argument, NULL, OPT_PKCS11_ENGINE}, - {"pkcs11-module", required_argument, NULL, OPT_PKCS11_MODULE}, - {"pkcs11-keyid", required_argument, NULL, OPT_PKCS11_KEYID}, - {"hash-alg", required_argument, NULL, OPT_HASH_ALG}, - {"block-size", required_argument, NULL, OPT_BLOCK_SIZE}, - {"salt", required_argument, NULL, OPT_SALT}, - {"out-merkle-tree", required_argument, NULL, OPT_OUT_MERKLE_TREE}, - {"out-descriptor", required_argument, NULL, OPT_OUT_DESCRIPTOR}, + {"hash-alg", required_argument, NULL, OPT_HASH_ALG}, + {"block-size", required_argument, NULL, OPT_BLOCK_SIZE}, + {"salt", required_argument, NULL, OPT_SALT}, + {"key", required_argument, NULL, OPT_KEY}, + {"cert", required_argument, NULL, OPT_CERT}, {NULL, 0, NULL, 0} }; @@ -56,6 +51,12 @@ int fsverity_cmd_sign(const struct fsverity_command *cmd, while ((c = getopt_long(argc, argv, "", longopts, NULL)) != -1) { switch (c) { + case OPT_HASH_ALG: + case OPT_BLOCK_SIZE: + case OPT_SALT: + if (!parse_tree_param(c, optarg, &tree_params)) + goto out_usage; + break; case OPT_KEY: if (sig_params.keyfile != NULL) { error_msg("--key can only be specified once"); @@ -70,35 +71,6 @@ int fsverity_cmd_sign(const struct fsverity_command *cmd, } sig_params.certfile = optarg; break; - case OPT_PKCS11_ENGINE: - if (sig_params.pkcs11_engine != NULL) { - error_msg("--pkcs11-engine can only be specified once"); - goto out_usage; - } - sig_params.pkcs11_engine = optarg; - break; - case OPT_PKCS11_MODULE: - if (sig_params.pkcs11_module != NULL) { - error_msg("--pkcs11-module can only be specified once"); - goto out_usage; - } - sig_params.pkcs11_module = optarg; - break; - case OPT_PKCS11_KEYID: - if (sig_params.pkcs11_keyid != NULL) { - error_msg("--pkcs11-keyid can only be specified once"); - goto out_usage; - } - sig_params.pkcs11_keyid = optarg; - break; - case OPT_HASH_ALG: - case OPT_BLOCK_SIZE: - case OPT_SALT: - case OPT_OUT_MERKLE_TREE: - case OPT_OUT_DESCRIPTOR: - if (!parse_tree_param(c, optarg, &tree_params)) - goto out_usage; - break; default: goto out_usage; } @@ -110,6 +82,10 @@ int fsverity_cmd_sign(const struct fsverity_command *cmd, if (argc != 2) goto out_usage; + if (sig_params.keyfile == NULL) { + error_msg("Missing --key argument"); + goto out_usage; + } if (sig_params.certfile == NULL) sig_params.certfile = sig_params.keyfile; @@ -141,8 +117,7 @@ int fsverity_cmd_sign(const struct fsverity_command *cmd, status = 0; out: filedes_close(&file); - if (!destroy_tree_params(&tree_params) && status == 0) - status = 1; + destroy_tree_params(&tree_params); free(digest); free(sig); return status; diff --git a/programs/fsverity.c b/programs/fsverity.c index e4e348b..b911b2e 100644 --- a/programs/fsverity.c +++ b/programs/fsverity.c @@ -11,7 +11,6 @@ #include "fsverity.h" -#include <fcntl.h> #include <limits.h> static const struct fsverity_command { @@ -28,16 +27,9 @@ static const struct fsverity_command { .usage_str = " fsverity digest FILE...\n" " [--hash-alg=HASH_ALG] [--block-size=BLOCK_SIZE] [--salt=SALT]\n" -" [--out-merkle-tree=FILE] [--out-descriptor=FILE]\n" " [--compact] [--for-builtin-sig]\n" #ifndef _WIN32 }, { - .name = "dump_metadata", - .func = fsverity_cmd_dump_metadata, - .short_desc = "Dump the fs-verity metadata of the given file", - .usage_str = -" fsverity dump_metadata TYPE FILE [--offset=OFFSET] [--length=LENGTH]\n" - }, { .name = "enable", .func = fsverity_cmd_enable, .short_desc = "Enable fs-verity on a file", @@ -56,13 +48,11 @@ static const struct fsverity_command { }, { .name = "sign", .func = fsverity_cmd_sign, - .short_desc = "Sign a file for fs-verity built-in signature verification", + .short_desc = "Sign a file for fs-verity", .usage_str = -" fsverity sign FILE OUT_SIGFILE\n" -" [--key=KEYFILE] [--cert=CERTFILE] [--pkcs11-engine=SOFILE]\n" -" [--pkcs11-module=SOFILE] [--pkcs11-keyid=KEYID]\n" +" fsverity sign FILE OUT_SIGFILE --key=KEYFILE\n" " [--hash-alg=HASH_ALG] [--block-size=BLOCK_SIZE] [--salt=SALT]\n" -" [--out-merkle-tree=FILE] [--out-descriptor=FILE]\n" +" [--cert=CERTFILE]\n" } }; @@ -204,74 +194,6 @@ static bool parse_salt_option(const char *arg, u8 **salt_ptr, return true; } -struct metadata_callback_ctx { - struct filedes merkle_tree_file; - struct filedes descriptor_file; - struct libfsverity_metadata_callbacks callbacks; -}; - -static int handle_merkle_tree_size(void *_ctx, u64 size) -{ - struct metadata_callback_ctx *ctx = _ctx; - - if (!preallocate_file(&ctx->merkle_tree_file, size)) - return -EIO; - return 0; -} - -static int handle_merkle_tree_block(void *_ctx, const void *block, size_t size, - u64 offset) -{ - struct metadata_callback_ctx *ctx = _ctx; - - if (!full_pwrite(&ctx->merkle_tree_file, block, size, offset)) - return -EIO; - return 0; -} - -static int handle_descriptor(void *_ctx, const void *descriptor, size_t size) -{ - struct metadata_callback_ctx *ctx = _ctx; - - if (!full_write(&ctx->descriptor_file, descriptor, size)) - return -EIO; - return 0; -} - -static bool parse_out_metadata_option(int opt_char, const char *arg, - const struct libfsverity_metadata_callbacks **cbs) -{ - struct metadata_callback_ctx *ctx; - struct filedes *file; - const char *opt_name; - - if (*cbs) { - ctx = (*cbs)->ctx; - } else { - ctx = xzalloc(sizeof(*ctx)); - ctx->merkle_tree_file.fd = -1; - ctx->descriptor_file.fd = -1; - ctx->callbacks.ctx = ctx; - *cbs = &ctx->callbacks; - } - - if (opt_char == OPT_OUT_MERKLE_TREE) { - file = &ctx->merkle_tree_file; - opt_name = "--out-merkle-tree"; - ctx->callbacks.merkle_tree_size = handle_merkle_tree_size; - ctx->callbacks.merkle_tree_block = handle_merkle_tree_block; - } else { - file = &ctx->descriptor_file; - opt_name = "--out-descriptor"; - ctx->callbacks.descriptor = handle_descriptor; - } - if (file->fd >= 0) { - error_msg("%s can only be specified once", opt_name); - return false; - } - return open_file(file, arg, O_WRONLY|O_CREAT|O_TRUNC, 0644); -} - bool parse_tree_param(int opt_char, const char *arg, struct libfsverity_merkle_tree_params *params) { @@ -283,30 +205,15 @@ bool parse_tree_param(int opt_char, const char *arg, case OPT_SALT: return parse_salt_option(arg, (u8 **)¶ms->salt, ¶ms->salt_size); - case OPT_OUT_MERKLE_TREE: - case OPT_OUT_DESCRIPTOR: - return parse_out_metadata_option(opt_char, arg, - ¶ms->metadata_callbacks); default: ASSERT(0); } } -bool destroy_tree_params(struct libfsverity_merkle_tree_params *params) +void destroy_tree_params(struct libfsverity_merkle_tree_params *params) { - bool ok = true; - free((u8 *)params->salt); - if (params->metadata_callbacks) { - struct metadata_callback_ctx *ctx = - params->metadata_callbacks->ctx; - - ok &= filedes_close(&ctx->merkle_tree_file); - ok &= filedes_close(&ctx->descriptor_file); - free(ctx); - } memset(params, 0, sizeof(*params)); - return ok; } int main(int argc, char *argv[]) diff --git a/programs/fsverity.h b/programs/fsverity.h index ad54cc2..45c4fe1 100644 --- a/programs/fsverity.h +++ b/programs/fsverity.h @@ -27,13 +27,6 @@ enum { OPT_FOR_BUILTIN_SIG, OPT_HASH_ALG, OPT_KEY, - OPT_LENGTH, - OPT_OFFSET, - OPT_OUT_DESCRIPTOR, - OPT_OUT_MERKLE_TREE, - OPT_PKCS11_ENGINE, - OPT_PKCS11_KEYID, - OPT_PKCS11_MODULE, OPT_SALT, OPT_SIGNATURE, }; @@ -44,10 +37,6 @@ struct fsverity_command; int fsverity_cmd_digest(const struct fsverity_command *cmd, int argc, char *argv[]); -/* cmd_dump_metadata.c */ -int fsverity_cmd_dump_metadata(const struct fsverity_command *cmd, - int argc, char *argv[]); - /* cmd_enable.c */ int fsverity_cmd_enable(const struct fsverity_command *cmd, int argc, char *argv[]); @@ -64,6 +53,6 @@ int fsverity_cmd_sign(const struct fsverity_command *cmd, void usage(const struct fsverity_command *cmd, FILE *fp); bool parse_tree_param(int opt_char, const char *arg, struct libfsverity_merkle_tree_params *params); -bool destroy_tree_params(struct libfsverity_merkle_tree_params *params); +void destroy_tree_params(struct libfsverity_merkle_tree_params *params); #endif /* PROGRAMS_FSVERITY_H */ diff --git a/programs/test_compute_digest.c b/programs/test_compute_digest.c index 67266fa..e7f2645 100644 --- a/programs/test_compute_digest.c +++ b/programs/test_compute_digest.c @@ -13,7 +13,6 @@ #include <ctype.h> #include <inttypes.h> -#include <openssl/sha.h> struct mem_file { u8 *data; @@ -38,13 +37,6 @@ static int error_read_fn(void *fd __attribute__((unused)), return -EIO; } -static int zeroes_read_fn(void *fd __attribute__((unused)), - void *buf, size_t count) -{ - memset(buf, 0, count); - return 0; -} - static const struct test_case { u32 hash_algorithm; u32 block_size; @@ -257,130 +249,6 @@ static void test_invalid_params(void) ASSERT(d == NULL); } -static struct { - u64 merkle_tree_size; - u64 merkle_tree_block; - u64 descriptor; -} metadata_callback_counts; - -static int handle_merkle_tree_size(void *ctx, u64 size) -{ - metadata_callback_counts.merkle_tree_size++; - - /* Test that the ctx argument is passed through correctly. */ - ASSERT(ctx == (void *)1); - - /* Test that the expected Merkle tree size is reported. */ - ASSERT(size == 5 * 1024); - return 0; -} - -static int handle_merkle_tree_block(void *ctx, const void *block, size_t size, - u64 offset) -{ - u8 digest[SHA256_DIGEST_LENGTH]; - u64 count = metadata_callback_counts.merkle_tree_block++; - const char *expected_digest; - - /* Test that ->merkle_tree_size() was called first. */ - ASSERT(metadata_callback_counts.merkle_tree_size == 1); - - /* Test that the ctx argument is passed through correctly. */ - ASSERT(ctx == (void *)1); - - /* - * Test that this Merkle tree block has the expected size, offset, and - * contents. The 4 blocks at "level 0" should be reported first, in - * order; then the 1 block at "level 1" should be reported last (but the - * level 1 block should have the smallest offset). - */ - ASSERT(size == 1024); - SHA256(block, size, digest); - if (count == 4) { - /* 1 block at level 1 */ - ASSERT(offset == 0); - expected_digest = "\x68\xc5\x38\xe1\x19\x58\xd6\x5d" - "\x68\xb6\xfe\x8e\x9f\xb8\xcc\xab" - "\xec\xfd\x92\x8b\x01\xd0\x63\x44" - "\xe2\x23\xed\x41\xdd\xc4\x54\x4a"; - } else { - /* 4 blocks at level 0 */ - ASSERT(offset == 1024 + (count * 1024)); - if (count < 3) { - expected_digest = "\xf7\x89\xba\xab\x53\x85\x9f\xaf" - "\x36\xd6\xd7\x5d\x10\x42\x06\x42" - "\x94\x20\x2d\x6e\x13\xe7\x71\x6f" - "\x39\x4f\xba\x43\x4c\xcc\x49\x86"; - } else { - expected_digest = "\x00\xfe\xd0\x3c\x5d\x6e\xab\x21" - "\x31\x43\xf3\xd9\x6a\x5c\xa3\x1c" - "\x2b\x89\xf5\x68\x4e\x6c\x8e\x07" - "\x87\x3e\x5e\x97\x65\x17\xb4\x8f"; - } - } - ASSERT(!memcmp(digest, expected_digest, SHA256_DIGEST_LENGTH)); - return 0; -} - -static const u8 expected_file_digest[SHA256_DIGEST_LENGTH] = - "\x09\xcb\xba\xee\xd2\xa0\x4c\x2d\xa2\x42\xc1\x0e\x15\x68\xd9\x6f" - "\x35\x8a\x16\xaa\x1e\xbe\x8c\xf0\x28\x61\x20\xc1\x3c\x93\x66\xd1"; - -static int handle_descriptor(void *ctx, const void *descriptor, size_t size) -{ - u8 digest[SHA256_DIGEST_LENGTH]; - - metadata_callback_counts.descriptor++; - /* Test that the ctx argument is passed through correctly. */ - ASSERT(ctx == (void *)1); - - /* Test that the fs-verity descriptor is reported correctly. */ - ASSERT(size == 256); - SHA256(descriptor, size, digest); - ASSERT(!memcmp(digest, expected_file_digest, SHA256_DIGEST_LENGTH)); - return 0; -} - -static const struct libfsverity_metadata_callbacks metadata_callbacks = { - .ctx = (void *)1, /* arbitrary value for testing purposes */ - .merkle_tree_size = handle_merkle_tree_size, - .merkle_tree_block = handle_merkle_tree_block, - .descriptor = handle_descriptor, -}; - -/* Test that the libfsverity_metadata_callbacks work correctly. */ -static void test_metadata_callbacks(void) -{ - /* - * For a useful test, we want a file whose Merkle tree will have at - * least 2 levels (this one will have exactly 2). The contents of the - * file aren't too important. - */ - struct libfsverity_merkle_tree_params params = { - .version = 1, - .hash_algorithm = FS_VERITY_HASH_ALG_SHA256, - .block_size = 1024, - .file_size = 100000, - .metadata_callbacks = &metadata_callbacks, - }; - struct libfsverity_digest *d; - - ASSERT(libfsverity_compute_digest(NULL, zeroes_read_fn, - ¶ms, &d) == 0); - - /* Test that the callbacks were called the correct number of times. */ - ASSERT(metadata_callback_counts.merkle_tree_size == 1); - ASSERT(metadata_callback_counts.merkle_tree_block == 5); - ASSERT(metadata_callback_counts.descriptor == 1); - - /* Test that the computed file digest is as expected. */ - ASSERT(d->digest_algorithm == FS_VERITY_HASH_ALG_SHA256); - ASSERT(d->digest_size == SHA256_DIGEST_LENGTH); - ASSERT(!memcmp(d->digest, expected_file_digest, SHA256_DIGEST_LENGTH)); - - free(d); -} - int main(int argc, char *argv[]) { const bool update = (argc == 2 && !strcmp(argv[1], "--update")); @@ -437,7 +305,6 @@ int main(int argc, char *argv[]) } test_invalid_params(); - test_metadata_callbacks(); printf("test_compute_digest passed\n"); return 0; } diff --git a/programs/utils.c b/programs/utils.c index 116eb95..ce19b57 100644 --- a/programs/utils.c +++ b/programs/utils.c @@ -13,14 +13,10 @@ #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 ========== */ @@ -130,26 +126,6 @@ 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) { @@ -184,41 +160,6 @@ 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; diff --git a/programs/utils.h b/programs/utils.h index 9a5c97a..ab5005f 100644 --- a/programs/utils.h +++ b/programs/utils.h @@ -40,11 +40,8 @@ struct filedes { bool open_file(struct filedes *file, const char *filename, int flags, int mode); bool get_file_size(struct filedes *file, u64 *size_ret); -bool preallocate_file(struct filedes *file, u64 size); bool full_read(struct filedes *file, void *buf, size_t count); bool full_write(struct filedes *file, const void *buf, size_t count); -bool full_pwrite(struct filedes *file, const void *buf, size_t count, - u64 offset); bool filedes_close(struct filedes *file); int read_callback(void *file, void *buf, size_t count); |