summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorColin Walters <walters@verbum.org>2017-07-19 09:40:23 -0400
committerColin Walters <walters@verbum.org>2017-07-19 11:35:09 -0400
commit268ae488167617b919b8bb219f555e1f9133e234 (patch)
tree8d5f8d4b4c47b9006175795e95546d8400a84e3a
parent23f7df15006f14ddc3bc2ddee690f7f8604c3ebe (diff)
downloadlibglnx-268ae488167617b919b8bb219f555e1f9133e234.tar.gz
fdio: Introduce glnx_openat_read()
This is kind of long overdue. Reasons are the same as the other wrappers. I debated adding `O_NOFOLLOW` support but the use cases for that are pretty obscure, callers who want that can just use the syscall directly for now.
-rw-r--r--glnx-fdio.c43
-rw-r--r--glnx-fdio.h7
-rw-r--r--tests/test-libglnx-xattrs.c26
3 files changed, 49 insertions, 27 deletions
diff --git a/glnx-fdio.c b/glnx-fdio.c
index 797d939..756248d 100644
--- a/glnx-fdio.c
+++ b/glnx-fdio.c
@@ -387,6 +387,35 @@ glnx_link_tmpfile_at (GLnxTmpfile *tmpf,
return TRUE;
}
+/**
+ * glnx_openat_rdonly:
+ * @dfd: File descriptor for origin directory
+ * @path: Pathname, relative to @dfd
+ * @follow: Whether or not to follow symbolic links in the final component
+ * @out_fd: (out): File descriptor
+ * @error: Error
+ *
+ * Use openat() to open a file, with flags `O_RDONLY | O_CLOEXEC | O_NOCTTY`.
+ * Like the other libglnx wrappers, will use `TEMP_FAILURE_RETRY` and
+ * also includes @path in @error in case of failure.
+ */
+gboolean
+glnx_openat_rdonly (int dfd,
+ const char *path,
+ gboolean follow,
+ int *out_fd,
+ GError **error)
+{
+ int flags = O_RDONLY | O_CLOEXEC | O_NOCTTY;
+ if (!follow)
+ flags |= O_NOFOLLOW;
+ int fd = TEMP_FAILURE_RETRY (openat (dfd, path, flags));
+ if (fd == -1)
+ return glnx_throw_errno_prefix (error, "openat(%s)", path);
+ *out_fd = fd;
+ return TRUE;
+}
+
static guint8*
glnx_fd_readall_malloc (int fd,
gsize *out_len,
@@ -524,9 +553,9 @@ glnx_file_get_contents_utf8_at (int dfd,
{
dfd = glnx_dirfd_canonicalize (dfd);
- glnx_fd_close int fd = TEMP_FAILURE_RETRY (openat (dfd, subpath, O_RDONLY | O_NOCTTY | O_CLOEXEC));
- if (G_UNLIKELY (fd == -1))
- return glnx_null_throw_errno_prefix (error, "open(%s)", subpath);
+ glnx_fd_close int fd = -1;
+ if (!glnx_openat_rdonly (dfd, subpath, TRUE, &fd, error))
+ return NULL;
gsize len;
g_autofree char *buf = glnx_fd_readall_utf8 (fd, &len, cancellable, error);
@@ -822,12 +851,8 @@ glnx_file_copy_at (int src_dfd,
goto out;
}
- src_fd = TEMP_FAILURE_RETRY (openat (src_dfd, src_subpath, O_RDONLY | O_CLOEXEC | O_NOCTTY | O_NOFOLLOW));
- if (src_fd == -1)
- {
- glnx_set_error_from_errno (error);
- goto out;
- }
+ if (!glnx_openat_rdonly (src_dfd, src_subpath, FALSE, &src_fd, error))
+ goto out;
dest_open_flags = O_WRONLY | O_CREAT | O_CLOEXEC | O_NOCTTY;
if (!(copyflags & GLNX_FILE_COPY_OVERWRITE))
diff --git a/glnx-fdio.h b/glnx-fdio.h
index 902f8d2..6b873e9 100644
--- a/glnx-fdio.h
+++ b/glnx-fdio.h
@@ -102,6 +102,13 @@ glnx_link_tmpfile_at (GLnxTmpfile *tmpf,
const char *target,
GError **error);
+gboolean
+glnx_openat_rdonly (int dfd,
+ const char *path,
+ gboolean follow,
+ int *out_fd,
+ GError **error);
+
GBytes *
glnx_fd_readall_bytes (int fd,
GCancellable *cancellable,
diff --git a/tests/test-libglnx-xattrs.c b/tests/test-libglnx-xattrs.c
index b6f0ac6..37c982d 100644
--- a/tests/test-libglnx-xattrs.c
+++ b/tests/test-libglnx-xattrs.c
@@ -107,22 +107,17 @@ do_write_run (GLnxDirFdIterator *dfd_iter, GError **error)
{
while (TRUE)
{
- g_autoptr(GVariant) current_xattrs = NULL;
- glnx_fd_close int fd = -1;
-
struct dirent *dent;
if (!glnx_dirfd_iterator_next_dent (dfd_iter, &dent, NULL, error))
return FALSE;
if (!dent)
break;
- fd = openat (dfd_iter->fd, dent->d_name, O_RDONLY | O_CLOEXEC);
- if (fd < 0)
- {
- glnx_set_error_from_errno (error);
- return FALSE;
- }
+ glnx_fd_close int fd = -1;
+ if (!glnx_openat_rdonly (dfd_iter->fd, dent->d_name, FALSE, &fd, error))
+ return FALSE;
+ g_autoptr(GVariant) current_xattrs = NULL;
if (!glnx_fd_get_all_xattrs (fd, &current_xattrs, NULL, error))
return FALSE;
@@ -156,22 +151,17 @@ do_read_run (GLnxDirFdIterator *dfd_iter,
guint nattrs = 0;
while (TRUE)
{
- g_autoptr(GVariant) current_xattrs = NULL;
- glnx_fd_close int fd = -1;
-
struct dirent *dent;
if (!glnx_dirfd_iterator_next_dent (dfd_iter, &dent, NULL, error))
return FALSE;
if (!dent)
break;
- fd = openat (dfd_iter->fd, dent->d_name, O_RDONLY | O_CLOEXEC);
- if (fd < 0)
- {
- glnx_set_error_from_errno (error);
- return FALSE;
- }
+ glnx_fd_close int fd = -1;
+ if (!glnx_openat_rdonly (dfd_iter->fd, dent->d_name, FALSE, &fd, error))
+ return FALSE;
+ g_autoptr(GVariant) current_xattrs = NULL;
if (!glnx_fd_get_all_xattrs (fd, &current_xattrs, NULL, error))
return FALSE;