[libglnx] fdio: Introduce glnx_openat_read()



commit 268ae488167617b919b8bb219f555e1f9133e234
Author: Colin Walters <walters verbum org>
Date:   Wed Jul 19 09:40:23 2017 -0400

    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.

 glnx-fdio.c                 |   43 ++++++++++++++++++++++++++++++++++---------
 glnx-fdio.h                 |    7 +++++++
 tests/test-libglnx-xattrs.c |   26 ++++++++------------------
 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;
 


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]