]> git.ipfire.org Git - thirdparty/kmod.git/commitdiff
libkmod: Use pread where appropriate
authorTobias Stoeckmann <tobias@stoeckmann.org>
Thu, 17 Oct 2024 21:55:06 +0000 (23:55 +0200)
committerLucas De Marchi <lucas.de.marchi@gmail.com>
Fri, 18 Oct 2024 18:45:23 +0000 (13:45 -0500)
Since we do not want to modify the current position in file, use pread
instead of read + lseek. Removes one lseek call per module, which for
depmod on Arch Linux means 6143 calls.

Signed-off-by: Tobias Stoeckmann <tobias@stoeckmann.org>
Link: https://github.com/kmod-project/kmod/pull/189
Signed-off-by: Lucas De Marchi <lucas.de.marchi@gmail.com>
libkmod/libkmod-file.c
shared/util.c
shared/util.h

index fe2bd05d43a89938c748b3d0c426fed6878434f0..828522ec7f06a45a4b70fc35ac008b778c66fb8f 100644 (file)
@@ -95,8 +95,7 @@ struct kmod_file *kmod_file_open(const struct kmod_ctx *ctx, const char *filenam
                return NULL;
        }
 
-       sz = read_str_safe(file->fd, buf, sizeof(buf));
-       lseek(file->fd, 0, SEEK_SET);
+       sz = pread_str_safe(file->fd, buf, sizeof(buf), 0);
        if (sz != (sizeof(buf) - 1)) {
                if (sz < 0)
                        errno = -sz;
index 5102879fb77dff4028cb3bfa73b831631f319cd6..6d1cf420f615eb49d838f8bebf5a6069252309be 100644 (file)
@@ -183,6 +183,33 @@ bool path_ends_with_kmod_ext(const char *path, size_t len)
 
 /* read-like and fread-like functions                                       */
 /* ************************************************************************ */
+ssize_t pread_str_safe(int fd, char *buf, size_t buflen, off_t off)
+{
+       size_t todo = buflen - 1;
+       size_t done = 0;
+
+       assert_cc(EAGAIN == EWOULDBLOCK);
+
+       do {
+               ssize_t r = pread(fd, buf + done, todo, off + done);
+
+               if (r == 0)
+                       break;
+               else if (r > 0) {
+                       todo -= r;
+                       done += r;
+               } else {
+                       if (errno == EAGAIN || errno == EINTR)
+                               continue;
+                       else
+                               return -errno;
+               }
+       } while (todo > 0);
+
+       buf[done] = '\0';
+       return done;
+}
+
 ssize_t read_str_safe(int fd, char *buf, size_t buflen)
 {
        size_t todo = buflen - 1;
index 974f1ddbc8b28ab8e73e2db60c39bafadf16ccb7..579217f30f6ed5103a161ecf0c7c0356f59747b7 100644 (file)
@@ -35,6 +35,8 @@ _nonnull_all_ bool path_ends_with_kmod_ext(const char *path, size_t len);
 
 /* read-like and fread-like functions                                       */
 /* ************************************************************************ */
+_must_check_ _nonnull_(2) ssize_t pread_str_safe(int fd, char *buf, size_t buflen,
+                                                off_t off);
 _must_check_ _nonnull_(2) ssize_t read_str_safe(int fd, char *buf, size_t buflen);
 _nonnull_(2) ssize_t write_str_safe(int fd, const char *buf, size_t buflen);
 _must_check_ _nonnull_(2) int read_str_long(int fd, long *value, int base);