From: Jérémie Galarneau Date: Wed, 1 May 2019 14:50:55 +0000 (-0400) Subject: Allow lttng_directory_handle to be moved X-Git-Tag: v2.12.0-rc1~580 X-Git-Url: https://git.lttng.org./?a=commitdiff_plain;h=46307ffe11537f48a43ff90f3b3b048eeea248f1;p=lttng-tools.git Allow lttng_directory_handle to be moved 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 --- diff --git a/src/common/compat/directory-handle.c b/src/common/compat/directory-handle.c index 562a79287..6e04c6a3c 100644 --- a/src/common/compat/directory-handle.c +++ b/src/common/compat/directory-handle.c @@ -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) diff --git a/src/common/compat/directory-handle.h b/src/common/compat/directory-handle.h index ceebc941e..dad4299ca 100644 --- a/src/common/compat/directory-handle.h +++ b/src/common/compat/directory-handle.h @@ -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. */