summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorColin Walters <walters@verbum.org>2015-03-17 13:40:35 -0400
committerColin Walters <walters@verbum.org>2015-03-17 13:41:57 -0400
commitcf2a89f50633df330858efe963263b0577010718 (patch)
treea812290d0d793243ed3cbdec45378b6d736cdbe2
parentc92adab47af5d3e75f4e4e73c50e02637f226ba8 (diff)
downloadlibglnx-cf2a89f50633df330858efe963263b0577010718.tar.gz
Add glnx_dirfd_canonicalize()
We want to honor `-1 == AT_FDCWD`.
-rw-r--r--glnx-dirfd.c3
-rw-r--r--glnx-dirfd.h17
-rw-r--r--glnx-fdio.c8
-rw-r--r--glnx-shutil.c4
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);