diff --git a/src/libostree/ostree-repo-commit.c b/src/libostree/ostree-repo-commit.c index c83c4bd8..ca52704e 100644 --- a/src/libostree/ostree-repo-commit.c +++ b/src/libostree/ostree-repo-commit.c @@ -2112,13 +2112,9 @@ write_directory_content_to_mtree_internal (OstreeRepo *self, } else { - int filefd = openat (dfd_iter->fd, name, O_RDONLY | O_CLOEXEC, 0); - if (filefd == -1) - { - gs_set_error_from_errno (error, errno); - goto out; - } - file_input = (GInputStream*)g_unix_input_stream_new (filefd, TRUE); + if (!ot_openat_read_stream (dfd_iter->fd, name, FALSE, + &file_input, cancellable, error)) + goto out; } } diff --git a/src/libostree/ostree-sysroot-deploy.c b/src/libostree/ostree-sysroot-deploy.c index cdf5e182..d5c6811e 100644 --- a/src/libostree/ostree-sysroot-deploy.c +++ b/src/libostree/ostree-sysroot-deploy.c @@ -52,18 +52,13 @@ copy_one_file_fsync_at (int src_parent_dfd, if (S_ISREG (stbuf->st_mode)) { /* Note the objects take ownership of the fds */ - int src_fd = -1; int dest_fd = -1; gs_unref_object GInputStream *in = NULL; gs_unref_object GOutputStream *out = NULL; - src_fd = openat (src_parent_dfd, name, O_RDONLY | O_NOFOLLOW | O_NOCTTY | O_NOATIME | O_CLOEXEC); - if (src_fd == -1) - { - gs_set_error_from_errno (error, errno); - goto out; - } - in = g_unix_input_stream_new (src_fd, TRUE); + if (!ot_openat_read_stream (src_parent_dfd, name, FALSE, + &in, cancellable, error)) + goto out; dest_fd = openat (dest_parent_dfd, name, O_WRONLY | O_CREAT | O_EXCL | O_CLOEXEC, stbuf->st_mode); diff --git a/src/libotutil/ot-fs-utils.c b/src/libotutil/ot-fs-utils.c index 3ca62352..7137b829 100644 --- a/src/libotutil/ot-fs-utils.c +++ b/src/libotutil/ot-fs-utils.c @@ -23,6 +23,7 @@ #include "ot-fs-utils.h" #include "libgsystem.h" #include +#include int ot_opendirat (int dfd, const char *path, gboolean follow) @@ -143,3 +144,47 @@ ot_readlinkat_gfile_info (int dfd, return ret; } + +/** + * ot_openat_read_stream: + * @dfd: Directory file descriptor + * @path: Subpath + * @follow: Whether or not to follow symbolic links + * @out_istream: (out): Return location for input stream + * @cancellable: Cancellable + * @error: Error + * + * Open a file for reading starting from @dfd for @path. + * The @follow parameter determines whether or not to follow + * if the last element of @path is a symbolic link. Intermediate + * symlink path components are always followed. + */ +gboolean +ot_openat_read_stream (int dfd, + const char *path, + gboolean follow, + GInputStream **out_istream, + GCancellable *cancellable, + GError **error) +{ + gboolean ret = FALSE; + int fd = -1; + int flags = O_RDONLY | O_NOCTTY | O_CLOEXEC; + + if (!follow) + flags |= O_NOFOLLOW; + + do + fd = openat (dfd, path, flags, 0); + while (G_UNLIKELY (fd == -1 && errno == EINTR)); + if (fd == -1) + { + gs_set_error_from_errno (error, errno); + goto out; + } + + *out_istream = g_unix_input_stream_new (fd, TRUE); + ret = TRUE; + out: + return ret; +} diff --git a/src/libotutil/ot-fs-utils.h b/src/libotutil/ot-fs-utils.h index e0bb4003..41389df2 100644 --- a/src/libotutil/ot-fs-utils.h +++ b/src/libotutil/ot-fs-utils.h @@ -50,5 +50,12 @@ gboolean ot_readlinkat_gfile_info (int dfd, GCancellable *cancellable, GError **error); +gboolean ot_openat_read_stream (int dfd, + const char *path, + gboolean follow, + GInputStream **out_istream, + GCancellable *cancellable, + GError **error); + G_END_DECLS