chiark / gitweb /
util: minor cleanups for loop_read() and friends
[elogind.git] / src / basic / util.c
index 3df91488c2de44bf812fa76ce1fa4aa189414ce4..707b0fab6b006655250eb7ef3a2b845fc29aa7c3 100644 (file)
 #include  "config.h"
 #include  "macro.h"
 #include  "util.h"
-#include  "ioprio.h"
+// #include  "ioprio.h"
 // #include  "missing.h"
 // #include  "log.h"
 #include  "strv.h"
 #include  "mkdir.h"
 #include  "path-util.h"
 // #include  "exit-status.h"
-// #include  "hashmap.h"
+#include  "hashmap.h"
+#include  "set.h"
 // #include  "env-util.h"
 #include  "fileio.h"
 // #include  "device-nodes.h"
@@ -2124,7 +2125,13 @@ ssize_t loop_read(int fd, void *buf, size_t nbytes, bool do_poll) {
         assert(fd >= 0);
         assert(buf);
 
-        while (nbytes > 0) {
+        /* If called with nbytes == 0, let's call read() at least
+         * once, to validate the operation */
+
+        if (nbytes > (size_t) SSIZE_MAX)
+                return -EINVAL;
+
+        do {
                 ssize_t k;
 
                 k = read(fd, p, nbytes);
@@ -2138,7 +2145,7 @@ ssize_t loop_read(int fd, void *buf, size_t nbytes, bool do_poll) {
                                  * and expect that any error/EOF is reported
                                  * via read() */
 
-                                fd_wait_for_event(fd, POLLIN, USEC_INFINITY);
+                                (void) fd_wait_for_event(fd, POLLIN, USEC_INFINITY);
                                 continue;
                         }
 
@@ -2148,10 +2155,12 @@ ssize_t loop_read(int fd, void *buf, size_t nbytes, bool do_poll) {
                 if (k == 0)
                         return n;
 
+                assert((size_t) k <= nbytes);
+
                 p += k;
                 nbytes -= k;
                 n += k;
-        }
+        } while (nbytes > 0);
 
         return n;
 }
@@ -2161,9 +2170,10 @@ int loop_read_exact(int fd, void *buf, size_t nbytes, bool do_poll) {
 
         n = loop_read(fd, buf, nbytes, do_poll);
         if (n < 0)
-                return n;
+                return (int) n;
         if ((size_t) n != nbytes)
                 return -EIO;
+
         return 0;
 }
 
@@ -2173,7 +2183,8 @@ int loop_write(int fd, const void *buf, size_t nbytes, bool do_poll) {
         assert(fd >= 0);
         assert(buf);
 
-        errno = 0;
+        if (nbytes > (size_t) SSIZE_MAX)
+                return -EINVAL;
 
         do {
                 ssize_t k;
@@ -2188,16 +2199,18 @@ int loop_write(int fd, const void *buf, size_t nbytes, bool do_poll) {
                                  * and expect that any error/EOF is reported
                                  * via write() */
 
-                                fd_wait_for_event(fd, POLLOUT, USEC_INFINITY);
+                                (void) fd_wait_for_event(fd, POLLOUT, USEC_INFINITY);
                                 continue;
                         }
 
                         return -errno;
                 }
 
-                if (nbytes > 0 && k == 0) /* Can't really happen */
+                if (_unlikely_(nbytes > 0 && k == 0)) /* Can't really happen */
                         return -EIO;
 
+                assert((size_t) k <= nbytes);
+
                 p += k;
                 nbytes -= k;
         } while (nbytes > 0);
@@ -2567,8 +2580,6 @@ int files_same(const char *filea, const char *fileb) {
                a.st_ino == b.st_ino;
 }
 
-/// UNNEEDED by elogind
-#if 0
 int running_in_chroot(void) {
         int ret;
 
@@ -2578,7 +2589,6 @@ int running_in_chroot(void) {
 
         return ret == 0;
 }
-#endif // 0
 
 static char *ascii_ellipsize_mem(const char *s, size_t old_length, size_t new_length, unsigned percent) {
         size_t x;
@@ -2890,8 +2900,6 @@ bool dirent_is_file_with_suffix(const struct dirent *de, const char *suffix) {
         return endswith(de->d_name, suffix);
 }
 
-/// UNNEEDED by elogind
-#if 0
 static int do_execute(char **directories, usec_t timeout, char *argv[]) {
         _cleanup_hashmap_free_free_ Hashmap *pids = NULL;
         _cleanup_set_free_free_ Set *seen = NULL;
@@ -3031,7 +3039,6 @@ void execute_directories(const char* const* directories, usec_t timeout, char *a
 
         wait_for_terminate_and_warn(name, executor_pid, true);
 }
-#endif // 0
 
 bool nulstr_contains(const char*nulstr, const char *needle) {
         const char *i;
@@ -3682,7 +3689,6 @@ int block_get_whole_disk(dev_t d, dev_t *ret) {
 
         return -ENOENT;
 }
-#endif // 0
 
 static const char *const ioprio_class_table[] = {
         [IOPRIO_CLASS_NONE] = "none",
@@ -3692,6 +3698,7 @@ static const char *const ioprio_class_table[] = {
 };
 
 DEFINE_STRING_TABLE_LOOKUP_WITH_FALLBACK(ioprio_class, int, INT_MAX);
+#endif // 0
 
 static const char *const sigchld_code_table[] = {
         [CLD_EXITED] = "exited",
@@ -6676,7 +6683,6 @@ int rename_noreplace(int olddirfd, const char *oldpath, int newdirfd, const char
 
         return 0;
 }
-#endif // 0
 
 static char *strcpy_backslash_escaped(char *t, const char *s, const char *bad) {
         assert(bad);
@@ -6737,6 +6743,7 @@ char *shell_maybe_quote(const char *s) {
 
         return r;
 }
+#endif // 0
 
 int parse_mode(const char *s, mode_t *ret) {
         char *x;