Allow lttng_directory_handle to be moved
authorJérémie Galarneau <jeremie.galarneau@efficios.com>
Wed, 1 May 2019 14:50:55 +0000 (10:50 -0400)
committerJérémie Galarneau <jeremie.galarneau@efficios.com>
Thu, 5 Sep 2019 20:39:13 +0000 (16:39 -0400)
Implement a "move" method (akin to C++'s move semantics) which allows
the transfer of the contents/ownership of a stack-allocated directory
handle to another object.

A moved directory handle must no longer be used after the "move"
operation. The original moved handle is invalidated in the hope
of catching erroneous uses of this API quickly.

Signed-off-by: Jérémie Galarneau <jeremie.galarneau@efficios.com>
src/common/compat/directory-handle.c
src/common/compat/directory-handle.h

index 562a7928719031856164f5a7fb2333fe30bcfc75..6e04c6a3c250bf20530656ab8bb9d336ecaa4036 100644 (file)
@@ -41,6 +41,8 @@ int _run_as_mkdir(const struct lttng_directory_handle *handle, const char *path,
 static
 int _run_as_mkdir_recursive(const struct lttng_directory_handle *handle,
                const char *path, mode_t mode, uid_t uid, gid_t gid);
+static
+void lttng_directory_handle_invalidate(struct lttng_directory_handle *handle);
 
 #ifdef COMPAT_DIRFD
 
@@ -79,13 +81,15 @@ void lttng_directory_handle_fini(struct lttng_directory_handle *handle)
 {
        int ret;
 
-       if (handle->dirfd == AT_FDCWD) {
-               return;
+       if (handle->dirfd == AT_FDCWD || handle->dirfd == -1) {
+               goto end;
        }
        ret = close(handle->dirfd);
        if (ret == -1) {
                PERROR("Failed to close directory file descriptor of directory handle");
        }
+end:
+       lttng_directory_handle_invalidate(handle);
 }
 
 LTTNG_HIDDEN
@@ -106,6 +110,12 @@ int lttng_directory_handle_copy(const struct lttng_directory_handle *handle,
        return ret;
 }
 
+static
+void lttng_directory_handle_invalidate(struct lttng_directory_handle *handle)
+{
+       handle->dirfd = -1;
+}
+
 static
 int lttng_directory_handle_stat(const struct lttng_directory_handle *handle,
                const char *path, struct stat *st)
@@ -241,6 +251,7 @@ LTTNG_HIDDEN
 void lttng_directory_handle_fini(struct lttng_directory_handle *handle)
 {
        free(handle->base_path);
+       lttng_directory_handle_invalidate(handle);
 }
 
 LTTNG_HIDDEN
@@ -251,6 +262,12 @@ int lttng_directory_handle_copy(const struct lttng_directory_handle *handle,
        return new_copy->base_path ? 0 : -1;
 }
 
+static
+void lttng_directory_handle_invalidate(struct lttng_directory_handle *handle)
+{
+       handle->base_path = NULL;
+}
+
 static
 int get_full_path(const struct lttng_directory_handle *handle,
                const char *subdirectory, char *fullpath, size_t size)
@@ -385,6 +402,16 @@ end:
 }
 
 /* Common implementation. */
+LTTNG_HIDDEN
+struct lttng_directory_handle
+lttng_directory_handle_move(struct lttng_directory_handle *original)
+{
+       const struct lttng_directory_handle tmp = *original;
+
+       lttng_directory_handle_invalidate(original);
+       return tmp;
+}
+
 static
 int create_directory_recursive(const struct lttng_directory_handle *handle,
                const char *path, mode_t mode)
index ceebc941e724ea690003698eb7c469789f3f2dba..dad4299ca96c615c66dcf1ec7334a6b69f8d685b 100644 (file)
@@ -62,6 +62,18 @@ LTTNG_HIDDEN
 int lttng_directory_handle_copy(const struct lttng_directory_handle *handle,
                struct lttng_directory_handle *new_copy);
 
+/*
+ * Move a directory handle. The original directory handle may no longer be
+ * used after this call. This call cannot fail; directly assign the
+ * return value to the new directory handle.
+ *
+ * It is safe (but unnecessary) to call lttng_directory_handle_fini on the
+ * original handle.
+ */
+LTTNG_HIDDEN
+struct lttng_directory_handle
+lttng_directory_handle_move(struct lttng_directory_handle *original);
+
 /*
  * Release the resources of a directory handle.
  */
This page took 0.028725 seconds and 4 git commands to generate.