]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
fileio: make read_virtual_file_at() accept O_PATH file descriptor
authorYu Watanabe <watanabe.yu+github@gmail.com>
Fri, 17 Jan 2025 21:45:03 +0000 (06:45 +0900)
committerYu Watanabe <watanabe.yu+github@gmail.com>
Thu, 23 Jan 2025 13:54:07 +0000 (22:54 +0900)
Then, merge read_virtual_file_at() and read_virtual_file_fd(), and make
the latter inline.

src/basic/fileio.c
src/basic/fileio.h

index b691307f053af49d5d13c20805d977e540fca6e8..622a13495aed55b56050b11a84fea953dbfa94e5 100644 (file)
@@ -482,7 +482,13 @@ int verify_file_at(int dir_fd, const char *fn, const char *blob, bool accept_ext
         return 1;
 }
 
-int read_virtual_file_fd(int fd, size_t max_size, char **ret_contents, size_t *ret_size) {
+int read_virtual_file_at(
+                int dir_fd,
+                const char *filename,
+                size_t max_size,
+                char **ret_contents,
+                size_t *ret_size) {
+
         _cleanup_free_ char *buf = NULL;
         size_t n, size;
         int n_retries;
@@ -501,9 +507,17 @@ int read_virtual_file_fd(int fd, size_t max_size, char **ret_contents, size_t *r
          * contents* may be returned. (Though the read is still done using one syscall.) Returns 0 on
          * partial success, 1 if untruncated contents were read. */
 
-        assert(fd >= 0);
+        assert(dir_fd >= 0 || dir_fd == AT_FDCWD);
         assert(max_size <= READ_VIRTUAL_BYTES_MAX || max_size == SIZE_MAX);
 
+        _cleanup_close_ int fd = -EBADF;
+        if (isempty(filename))
+                fd = fd_reopen(ASSERT_FD(dir_fd), O_RDONLY | O_NOCTTY | O_CLOEXEC);
+        else
+                fd = RET_NERRNO(openat(dir_fd, filename, O_RDONLY | O_NOCTTY | O_CLOEXEC));
+        if (fd < 0)
+                return fd;
+
         /* Limit the number of attempts to read the number of bytes returned by fstat(). */
         n_retries = 3;
 
@@ -627,31 +641,6 @@ int read_virtual_file_fd(int fd, size_t max_size, char **ret_contents, size_t *r
         return !truncated;
 }
 
-int read_virtual_file_at(
-                int dir_fd,
-                const char *filename,
-                size_t max_size,
-                char **ret_contents,
-                size_t *ret_size) {
-
-        _cleanup_close_ int fd = -EBADF;
-
-        assert(dir_fd >= 0 || dir_fd == AT_FDCWD);
-
-        if (!filename) {
-                if (dir_fd == AT_FDCWD)
-                        return -EBADF;
-
-                return read_virtual_file_fd(dir_fd, max_size, ret_contents, ret_size);
-        }
-
-        fd = openat(dir_fd, filename, O_RDONLY | O_NOCTTY | O_CLOEXEC);
-        if (fd < 0)
-                return -errno;
-
-        return read_virtual_file_fd(fd, max_size, ret_contents, ret_size);
-}
-
 int read_full_stream_full(
                 FILE *f,
                 const char *filename,
index 9139c03df4da04961bb9fca8ff8c4afbad56f0bb..49da9a677c594a2272e283d56ab145b6aa4a2032 100644 (file)
@@ -78,8 +78,10 @@ static inline int read_full_file(const char *filename, char **ret_contents, size
         return read_full_file_full(AT_FDCWD, filename, UINT64_MAX, SIZE_MAX, 0, NULL, ret_contents, ret_size);
 }
 
-int read_virtual_file_fd(int fd, size_t max_size, char **ret_contents, size_t *ret_size);
 int read_virtual_file_at(int dir_fd, const char *filename, size_t max_size, char **ret_contents, size_t *ret_size);
+static inline int read_virtual_file_fd(int fd, size_t max_size, char **ret_contents, size_t *ret_size) {
+        return read_virtual_file_at(fd, NULL, max_size, ret_contents, ret_size);
+}
 static inline int read_virtual_file(const char *filename, size_t max_size, char **ret_contents, size_t *ret_size) {
         return read_virtual_file_at(AT_FDCWD, filename, max_size, ret_contents, ret_size);
 }