chiark / gitweb /
Introduce loop_read_exact helper
authorZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Tue, 10 Mar 2015 01:23:53 +0000 (21:23 -0400)
committerZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Tue, 10 Mar 2015 02:10:54 +0000 (22:10 -0400)
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.

src/core/automount.c
src/core/machine-id-setup.c
src/journal/compress.c
src/journal/journalctl.c
src/libsystemd/sd-id128/sd-id128.c
src/shared/logs-show.c
src/shared/util.c
src/shared/util.h

index 0539fbbc41c1dab4da93533589b9611acc23dfde..cec90cbb319d7d60bc2a7940e6eff630bb1b2f36 100644 (file)
@@ -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;
         }
 
index 063f705ede8477f533204ca4cf3fdd2273fc491e..623dffdea1d20c378481892b81488270fdc09925 100644 (file)
@@ -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)) {
index 4232206f445cb0702468240da6d4137072456c93..383f6a6e9665b84ac280b9d3c57e8f0f847c4f70 100644 (file)
@@ -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%%)",
index f0f03b069707fc075d368739743df2f7d3298664..4d45f5a691f2540491773facd28ee9e36300e983 100644 (file)
@@ -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;
         }
 
index c876f6e381f90d1f48962cc366a909c5348d2c0c..f0ffedc38b39c9c363a4a1b80ab2760a77108f33 100644 (file)
@@ -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;
                 }
 
index 944d6856cd8315a785d39817a093a13d8c71c4cf..d3ee1398806223c594457fcbc1baa1f9e6a05a3d 100644 (file)
@@ -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);
index 74f29949c97619ce429b49e5b6f8d49f43fb297a..a13819e79ac8acb5e21d71a9474412cee2b222a8 100644 (file)
@@ -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) {
index 2de654f4cc8615faf2cb766d0f0e11f245bd97e9..d2da3e2895e3fd1aba6c824129685b9f505024af 100644 (file)
@@ -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);