Allow lttng_directory_handle to be moved
[lttng-tools.git] / src / common / compat / directory-handle.c
index 7077378e0a3e8aa40911eee665c6b972c4ef9168..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,39 @@ 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
+int lttng_directory_handle_copy(const struct lttng_directory_handle *handle,
+               struct lttng_directory_handle *new_copy)
+{
+       int ret = 0;
+
+       if (handle->dirfd == AT_FDCWD) {
+               new_copy->dirfd = handle->dirfd;
+       } else {
+               new_copy->dirfd = dup(handle->dirfd);
+               if (new_copy->dirfd == -1) {
+                       PERROR("Failed to duplicate directory fd of directory handle");
+                       ret = -1;
+               }
+       }
+       return ret;
+}
+
+static
+void lttng_directory_handle_invalidate(struct lttng_directory_handle *handle)
+{
+       handle->dirfd = -1;
 }
 
 static
@@ -223,6 +251,21 @@ LTTNG_HIDDEN
 void lttng_directory_handle_fini(struct lttng_directory_handle *handle)
 {
        free(handle->base_path);
+       lttng_directory_handle_invalidate(handle);
+}
+
+LTTNG_HIDDEN
+int lttng_directory_handle_copy(const struct lttng_directory_handle *handle,
+               struct lttng_directory_handle *new_copy)
+{
+       new_copy->base_path = strdup(handle->base_path);
+       return new_copy->base_path ? 0 : -1;
+}
+
+static
+void lttng_directory_handle_invalidate(struct lttng_directory_handle *handle)
+{
+       handle->base_path = NULL;
 }
 
 static
@@ -359,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)
@@ -418,7 +471,7 @@ LTTNG_HIDDEN
 int lttng_directory_handle_create_subdirectory_as_user(
                const struct lttng_directory_handle *handle,
                const char *subdirectory,
-               mode_t mode, struct lttng_credentials *creds)
+               mode_t mode, const struct lttng_credentials *creds)
 {
        int ret;
 
@@ -438,7 +491,7 @@ LTTNG_HIDDEN
 int lttng_directory_handle_create_subdirectory_recursive_as_user(
                const struct lttng_directory_handle *handle,
                const char *subdirectory_path,
-               mode_t mode, struct lttng_credentials *creds)
+               mode_t mode, const struct lttng_credentials *creds)
 {
        int ret;
 
This page took 0.039086 seconds and 4 git commands to generate.