summaryrefslogtreecommitdiff
path: root/src/libotutil/ot-fs-utils.c
diff options
context:
space:
mode:
authorColin Walters <walters@verbum.org>2015-01-07 08:41:45 -0500
committerColin Walters <walters@verbum.org>2015-01-07 08:41:45 -0500
commit687a6f8314acf62b4434302a9269cd7a5d2d97a1 (patch)
tree26ea378a213d7337fe1a268cf5d9e59343628f8f /src/libotutil/ot-fs-utils.c
parent026c5c60d3aa5ffc529e64f136aa5e468a315d62 (diff)
downloadostree-687a6f8314acf62b4434302a9269cd7a5d2d97a1.tar.gz
Add internal ot_openat_read_stream() helper
We had two cases which were creating an input stream using openat().
Diffstat (limited to 'src/libotutil/ot-fs-utils.c')
-rw-r--r--src/libotutil/ot-fs-utils.c45
1 files changed, 45 insertions, 0 deletions
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 <attr/xattr.h>
+#include <gio/gunixinputstream.h>
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;
+}