[libglnx] Add glnx_dirfd_canonicalize()



commit cf2a89f50633df330858efe963263b0577010718
Author: Colin Walters <walters verbum org>
Date:   Tue Mar 17 13:40:35 2015 -0400

    Add glnx_dirfd_canonicalize()
    
    We want to honor `-1 == AT_FDCWD`.

 glnx-dirfd.c  |    3 +++
 glnx-dirfd.h  |   17 +++++++++++++++++
 glnx-fdio.c   |    8 ++++++++
 glnx-shutil.c |    4 +++-
 4 files changed, 31 insertions(+), 1 deletions(-)
---
diff --git a/glnx-dirfd.c b/glnx-dirfd.c
index af4cab8..4b7d5a0 100644
--- a/glnx-dirfd.c
+++ b/glnx-dirfd.c
@@ -43,6 +43,9 @@ glnx_opendirat_with_errno (int           dfd,
   int flags = O_RDONLY | O_NONBLOCK | O_DIRECTORY | O_CLOEXEC | O_NOCTTY;
   if (!follow)
     flags |= O_NOFOLLOW;
+
+  dfd = glnx_dirfd_canonicalize (dfd);
+
   return openat (dfd, path, flags);
 }
 
diff --git a/glnx-dirfd.h b/glnx-dirfd.h
index 27cd03b..585d16a 100644
--- a/glnx-dirfd.h
+++ b/glnx-dirfd.h
@@ -27,6 +27,23 @@
 #include <fcntl.h>
 
 G_BEGIN_DECLS
+ 
+/**
+ * glnx_dirfd_canonicalize:
+ * @fd: A directory file descriptor
+ *
+ * It's often convenient in programs to use `-1` for "unassigned fd",
+ * and also because gobject-introspection doesn't support `AT_FDCWD`,
+ * libglnx honors `-1` to mean `AT_FDCWD`.  This small inline function
+ * canonicalizes `-1 -> AT_FDCWD`.
+ */
+static inline int
+glnx_dirfd_canonicalize (int fd)
+{
+  if (fd == -1)
+    return AT_FDCWD;
+  return fd;
+}
 
 struct GLnxDirFdIterator {
   gboolean initialized;
diff --git a/glnx-fdio.c b/glnx-fdio.c
index 77be6e1..63dea2b 100644
--- a/glnx-fdio.c
+++ b/glnx-fdio.c
@@ -35,6 +35,7 @@
 #define BTRFS_IOC_CLONE _IOW(BTRFS_IOCTL_MAGIC, 9, int)
 
 #include <glnx-fdio.h>
+#include <glnx-dirfd.h>
 #include <glnx-errors.h>
 #include <glnx-xattrs.h>
 #include <glnx-backport-autoptr.h>
@@ -212,6 +213,8 @@ glnx_file_get_contents_utf8_at (int                   dfd,
   char *buf;
   gsize len;
 
+  dfd = glnx_dirfd_canonicalize (dfd);
+
   do
     fd = openat (dfd, subpath, O_RDONLY | O_NOCTTY | O_CLOEXEC);
   while (G_UNLIKELY (fd == -1 && errno == EINTR));
@@ -255,6 +258,8 @@ glnx_readlinkat_malloc (int            dfd,
 {
   size_t l = 100;
 
+  dfd = glnx_dirfd_canonicalize (dfd);
+
   for (;;)
     {
       char *c;
@@ -482,6 +487,9 @@ glnx_file_copy_at (int                   src_dfd,
   if (g_cancellable_set_error_if_cancelled (cancellable, error))
     goto out;
 
+  src_dfd = glnx_dirfd_canonicalize (src_dfd);
+  dest_dfd = glnx_dirfd_canonicalize (dest_dfd);
+
   if (S_ISLNK (src_stbuf->st_mode))
     {
       return copy_symlink_at (src_dfd, src_subpath, src_stbuf,
diff --git a/glnx-shutil.c b/glnx-shutil.c
index 9fcb65a..967e364 100644
--- a/glnx-shutil.c
+++ b/glnx-shutil.c
@@ -118,7 +118,7 @@ glnx_shutil_rm_rf_children (GLnxDirFdIterator    *dfd_iter,
 
 /**
  * glnx_shutil_rm_rf_at:
- * @dfd: A directory file descriptor, or -1 for current
+ * @dfd: A directory file descriptor, or `AT_FDCWD` or `-1` for current
  * @path: Path
  * @cancellable: Cancellable
  * @error: Error
@@ -137,6 +137,8 @@ glnx_shutil_rm_rf_at (int                   dfd,
   glnx_fd_close int target_dfd = -1;
   g_auto(GLnxDirFdIterator) dfd_iter = { 0, };
 
+  dfd = glnx_dirfd_canonicalize (dfd);
+
   /* With O_NOFOLLOW first */
   target_dfd = openat (dfd, path,
                        O_RDONLY | O_NONBLOCK | O_DIRECTORY | O_CLOEXEC | O_NOFOLLOW);


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