From: Tobias Stoeckmann Date: Thu, 17 Oct 2024 21:55:06 +0000 (+0200) Subject: libkmod: Use pread where appropriate X-Git-Tag: v34~208 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=8d03b6c7d990af301950d3ecdc4b5c69fa525928;p=thirdparty%2Fkmod.git libkmod: Use pread where appropriate 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 Link: https://github.com/kmod-project/kmod/pull/189 Signed-off-by: Lucas De Marchi --- diff --git a/libkmod/libkmod-file.c b/libkmod/libkmod-file.c index fe2bd05d..828522ec 100644 --- a/libkmod/libkmod-file.c +++ b/libkmod/libkmod-file.c @@ -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; diff --git a/shared/util.c b/shared/util.c index 5102879f..6d1cf420 100644 --- a/shared/util.c +++ b/shared/util.c @@ -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; diff --git a/shared/util.h b/shared/util.h index 974f1ddb..579217f3 100644 --- a/shared/util.h +++ b/shared/util.h @@ -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);