From: Zbigniew Jędrzejewski-Szmek Date: Tue, 10 Mar 2015 01:23:53 +0000 (-0400) Subject: Introduce loop_read_exact helper X-Git-Tag: v219.0~412 X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?p=elogind.git;a=commitdiff_plain;h=a6dcc7e5924f9c27d3e9c6560a448b02ec28b65f Introduce loop_read_exact helper Usually when using loop_read(), we want to read the full buffer. Add a helper that mirrors loop_write(), and returns 0 when full buffer was read, and an error otherwise. Use -ENODATA for the short read, to distinguish it from a read error. --- diff --git a/src/core/automount.c b/src/core/automount.c index 0539fbbc4..cec90cbb3 100644 --- a/src/core/automount.c +++ b/src/core/automount.c @@ -725,7 +725,6 @@ static bool automount_check_gc(Unit *u) { static int automount_dispatch_io(sd_event_source *s, int fd, uint32_t events, void *userdata) { union autofs_v5_packet_union packet; Automount *a = AUTOMOUNT(userdata); - ssize_t l; int r; assert(a); @@ -736,12 +735,9 @@ static int automount_dispatch_io(sd_event_source *s, int fd, uint32_t events, vo goto fail; } - l = loop_read(a->pipe_fd, &packet, sizeof(packet), true); - if (l != sizeof(packet)) { - if (l < 0) - log_unit_error_errno(UNIT(a)->id, l, "Invalid read from pipe: %m"); - else - log_unit_error(UNIT(a)->id, "Invalid read from pipe: short read"); + r = loop_read_exact(a->pipe_fd, &packet, sizeof(packet), true); + if (r < 0) { + log_unit_error_errno(UNIT(a)->id, r, "Invalid read from pipe: %m"); goto fail; } diff --git a/src/core/machine-id-setup.c b/src/core/machine-id-setup.c index 063f705ed..623dffdea 100644 --- a/src/core/machine-id-setup.c +++ b/src/core/machine-id-setup.c @@ -64,7 +64,6 @@ static int generate(char id[34], const char *root) { unsigned char *p; sd_id128_t buf; char *q; - ssize_t k; const char *vm_id, *dbus_machine_id; assert(id); @@ -77,11 +76,10 @@ static int generate(char id[34], const char *root) { /* First, try reading the D-Bus machine id, unless it is a symlink */ fd = open(dbus_machine_id, O_RDONLY|O_CLOEXEC|O_NOCTTY|O_NOFOLLOW); if (fd >= 0) { - k = loop_read(fd, id, 33, false); + r = loop_read_exact(fd, id, 33, false); safe_close(fd); - if (k == 33 && id[32] == '\n') { - + if (r >= 0 && id[32] == '\n') { id[32] = 0; if (id128_is_valid(id)) { id[32] = '\n'; @@ -119,14 +117,14 @@ static int generate(char id[34], const char *root) { r = detect_vm(&vm_id); if (r > 0 && streq(vm_id, "kvm")) { - char uuid[37]; + char uuid[36]; fd = open("/sys/class/dmi/id/product_uuid", O_RDONLY|O_CLOEXEC|O_NOCTTY|O_NOFOLLOW); if (fd >= 0) { - k = loop_read(fd, uuid, 36, false); + r = loop_read_exact(fd, uuid, 36, false); safe_close(fd); - if (k >= 36) { + if (r >= 0) { r = shorten_uuid(id, uuid); if (r >= 0) { log_info("Initializing machine ID from KVM UUID."); @@ -162,7 +160,8 @@ static int get_valid_machine_id(int fd, char id[34]) { assert(fd >= 0); assert(id); - if (loop_read(fd, id_to_validate, 33, false) == 33 && id_to_validate[32] == '\n') { + if (loop_read_exact(fd, id_to_validate, 33, false) >= 0 && + id_to_validate[32] == '\n') { id_to_validate[32] = 0; if (id128_is_valid(id_to_validate)) { diff --git a/src/journal/compress.c b/src/journal/compress.c index 4232206f4..383f6a6e9 100644 --- a/src/journal/compress.c +++ b/src/journal/compress.c @@ -589,14 +589,12 @@ int decompress_stream_lz4(int fdf, int fdt, off_t max_bytes) { return log_oom(); for (;;) { - ssize_t n, m; + ssize_t m; int r; - n = read(fdf, &header, sizeof(header)); - if (n < 0) - return -errno; - if (n != sizeof(header)) - return errno ? -errno : -EIO; + r = loop_read_exact(fdf, &header, sizeof(header), false); + if (r < 0) + return r; m = le32toh(header); if (m == 0) @@ -618,12 +616,9 @@ int decompress_stream_lz4(int fdf, int fdt, off_t max_bytes) { if (!GREEDY_REALLOC(buf, buf_size, m)) return log_oom(); - errno = 0; - n = loop_read(fdf, buf, m, false); - if (n < 0) - return n; - if (n != m) - return errno ? -errno : -EIO; + r = loop_read_exact(fdf, buf, m, false); + if (r < 0) + return r; r = LZ4_decompress_safe_continue(&lz4_data, buf, out, m, 4*LZ4_BUFSIZE); if (r <= 0) @@ -636,9 +631,9 @@ int decompress_stream_lz4(int fdf, int fdt, off_t max_bytes) { return -EFBIG; } - n = loop_write(fdt, out, r, false); - if (n < 0) - return n; + r = loop_write(fdt, out, r, false); + if (r < 0) + return r; } log_debug("LZ4 decompression finished (%zu -> %zu bytes, %.1f%%)", diff --git a/src/journal/journalctl.c b/src/journal/journalctl.c index f0f03b069..4d45f5a69 100644 --- a/src/journal/journalctl.c +++ b/src/journal/journalctl.c @@ -1286,7 +1286,6 @@ static int setup_keys(void) { #ifdef HAVE_GCRYPT size_t mpk_size, seed_size, state_size, i; uint8_t *mpk, *seed, *state; - ssize_t l; int fd = -1, r; sd_id128_t machine, boot; char *p = NULL, *k = NULL; @@ -1351,10 +1350,9 @@ static int setup_keys(void) { } log_info("Generating seed..."); - l = loop_read(fd, seed, seed_size, true); - if (l < 0 || (size_t) l != seed_size) { - log_error_errno(EIO, "Failed to read random seed: %m"); - r = -EIO; + r = loop_read_exact(fd, seed, seed_size, true); + if (r < 0) { + log_error_errno(r, "Failed to read random seed: %m"); goto finish; } diff --git a/src/libsystemd/sd-id128/sd-id128.c b/src/libsystemd/sd-id128/sd-id128.c index c876f6e38..f0ffedc38 100644 --- a/src/libsystemd/sd-id128/sd-id128.c +++ b/src/libsystemd/sd-id128/sd-id128.c @@ -108,9 +108,9 @@ _public_ int sd_id128_get_machine(sd_id128_t *ret) { static thread_local bool saved_machine_id_valid = false; _cleanup_close_ int fd = -1; char buf[33]; - ssize_t k; unsigned j; sd_id128_t t; + int r; assert_return(ret, -EINVAL); @@ -123,13 +123,9 @@ _public_ int sd_id128_get_machine(sd_id128_t *ret) { if (fd < 0) return -errno; - k = loop_read(fd, buf, 33, false); - if (k < 0) - return (int) k; - - if (k != 33) - return -EIO; - + r = loop_read_exact(fd, buf, 33, false); + if (r < 0) + return r; if (buf[32] !='\n') return -EIO; @@ -157,10 +153,10 @@ _public_ int sd_id128_get_boot(sd_id128_t *ret) { static thread_local bool saved_boot_id_valid = false; _cleanup_close_ int fd = -1; char buf[36]; - ssize_t k; unsigned j; sd_id128_t t; char *p; + int r; assert_return(ret, -EINVAL); @@ -173,22 +169,19 @@ _public_ int sd_id128_get_boot(sd_id128_t *ret) { if (fd < 0) return -errno; - k = loop_read(fd, buf, 36, false); - if (k < 0) - return (int) k; - - if (k != 36) - return -EIO; + r = loop_read_exact(fd, buf, 36, false); + if (r < 0) + return r; for (j = 0, p = buf; j < 16; j++) { int a, b; - if (p >= buf + k - 1) + if (p >= buf + 35) return -EIO; if (*p == '-') { p++; - if (p >= buf + k - 1) + if (p >= buf + 35) return -EIO; } diff --git a/src/shared/logs-show.c b/src/shared/logs-show.c index 944d6856c..d3ee13988 100644 --- a/src/shared/logs-show.c +++ b/src/shared/logs-show.c @@ -1163,9 +1163,9 @@ static int get_boot_id_for_machine(const char *machine, sd_id128_t *boot_id) { if (fd < 0) _exit(EXIT_FAILURE); - k = loop_read(fd, buf, 36, false); + r = loop_read_exact(fd, buf, 36, false); safe_close(fd); - if (k != 36) + if (k < 0) _exit(EXIT_FAILURE); k = send(pair[1], buf, 36, MSG_NOSIGNAL); diff --git a/src/shared/util.c b/src/shared/util.c index 74f29949c..a13819e79 100644 --- a/src/shared/util.c +++ b/src/shared/util.c @@ -2326,6 +2326,17 @@ ssize_t loop_read(int fd, void *buf, size_t nbytes, bool do_poll) { return n; } +int loop_read_exact(int fd, void *buf, size_t nbytes, bool do_poll) { + ssize_t n; + + n = loop_read(fd, buf, nbytes, do_poll); + if (n < 0) + return n; + if ((size_t) n != nbytes) + return -EIO; + return 0; +} + int loop_write(int fd, const void *buf, size_t nbytes, bool do_poll) { const uint8_t *p = buf; @@ -2580,8 +2591,9 @@ char* dirname_malloc(const char *path) { int dev_urandom(void *p, size_t n) { static int have_syscall = -1; - int r, fd; - ssize_t k; + + _cleanup_close_ fd = -1; + int r; /* Gathers some randomness from the kernel. This call will * never block, and will always return some data from the @@ -2616,22 +2628,14 @@ int dev_urandom(void *p, size_t n) { return -errno; } else /* too short read? */ - return -EIO; + return -ENODATA; } fd = open("/dev/urandom", O_RDONLY|O_CLOEXEC|O_NOCTTY); if (fd < 0) return errno == ENOENT ? -ENOSYS : -errno; - k = loop_read(fd, p, n, true); - safe_close(fd); - - if (k < 0) - return (int) k; - if ((size_t) k != n) - return -EIO; - - return 0; + return loop_read_exact(fd, p, n, true); } void initialize_srand(void) { diff --git a/src/shared/util.h b/src/shared/util.h index 2de654f4c..d2da3e289 100644 --- a/src/shared/util.h +++ b/src/shared/util.h @@ -432,6 +432,7 @@ int sigaction_many(const struct sigaction *sa, ...); int fopen_temporary(const char *path, FILE **_f, char **_temp_path); ssize_t loop_read(int fd, void *buf, size_t nbytes, bool do_poll); +int loop_read_exact(int fd, void *buf, size_t nbytes, bool do_poll); int loop_write(int fd, const void *buf, size_t nbytes, bool do_poll); bool is_device_path(const char *path);