2 * Copyright (C) 2018 Jérémie Galarneau <jeremie.galarneau@efficios.com>
4 * SPDX-License-Identifier: LGPL-2.1-only
8 #include <common/error.hpp>
9 #include <common/fd-tracker/utils.hpp>
10 #include <common/utils.hpp>
12 #include <lttng/constant.h>
18 static int open_pipe_cloexec(void *data
__attribute__((unused
)), int *fds
)
20 return utils_create_pipe_cloexec(fds
);
23 static int close_pipe(void *data
__attribute__((unused
)), int *pipe
)
25 utils_close_pipe(pipe
);
26 pipe
[0] = pipe
[1] = -1;
30 int fd_tracker_util_close_fd(void *unused
__attribute__((unused
)), int *fd
)
35 int fd_tracker_util_pipe_open_cloexec(struct fd_tracker
*tracker
, const char *name
, int *pipe
)
38 const char *name_prefix
;
41 name_prefix
= name
? name
: "Unknown pipe";
42 ret
= asprintf(&names
[0], "%s (read end)", name_prefix
);
46 ret
= asprintf(&names
[1], "%s (write end)", name_prefix
);
51 ret
= fd_tracker_open_unsuspendable_fd(
52 tracker
, pipe
, (const char **) names
, 2, open_pipe_cloexec
, nullptr);
59 int fd_tracker_util_pipe_close(struct fd_tracker
*tracker
, int *pipe
)
61 return fd_tracker_close_unsuspendable_fd(tracker
, pipe
, 2, close_pipe
, nullptr);
65 struct open_directory_handle_args
{
66 const struct lttng_directory_handle
*in_handle
;
67 struct lttng_directory_handle
*ret_handle
;
72 static int open_directory_handle(void *_args
, int *out_fds
)
75 struct open_directory_handle_args
*args
= (open_directory_handle_args
*) _args
;
76 struct lttng_directory_handle
*new_handle
= nullptr;
78 new_handle
= args
->in_handle
?
79 lttng_directory_handle_create_from_handle(args
->path
, args
->in_handle
) :
80 lttng_directory_handle_create(args
->path
);
86 args
->ret_handle
= new_handle
;
89 * Reserved to indicate that the handle does not use a handle; there is
90 * nothing to track. We want to indicate an error to the fd-tracker so
91 * that it doesn't attempt to track the file descriptor, but also want
92 * the caller to retrieve the newly-created handle.
94 * Calling this a hack is a fair assessment.
96 if (!lttng_directory_handle_uses_fd(new_handle
)) {
100 *out_fds
= new_handle
->dirfd
;
110 static int fd_close(void *unused
__attribute__((unused
)), int *in_fds
)
112 const int ret
= close(in_fds
[0]);
118 static void directory_handle_destroy(struct lttng_directory_handle
*handle
, void *data
)
120 struct fd_tracker
*tracker
= (fd_tracker
*) data
;
122 fd_tracker_close_unsuspendable_fd(tracker
, &handle
->dirfd
, 1, fd_close
, nullptr);
125 ERR("Failed to untrack directory handle file descriptor");
130 struct lttng_directory_handle
*fd_tracker_create_directory_handle(struct fd_tracker
*tracker
,
133 return fd_tracker_create_directory_handle_from_handle(tracker
, nullptr, path
);
136 struct lttng_directory_handle
*fd_tracker_create_directory_handle_from_handle(
137 struct fd_tracker
*tracker
, struct lttng_directory_handle
*in_handle
, const char *path
)
141 char *handle_name
= nullptr;
142 char cwd_path
[LTTNG_PATH_MAX
] = "working directory";
143 struct lttng_directory_handle
*new_handle
= nullptr;
144 open_directory_handle_args open_args
{};
146 open_args
.in_handle
= in_handle
;
147 open_args
.path
= path
;
150 if (!getcwd(cwd_path
, sizeof(cwd_path
))) {
151 PERROR("Failed to get current working directory to name directory handle");
156 ret
= asprintf(&handle_name
, "Directory handle to %s", path
? path
: cwd_path
);
158 PERROR("Failed to format directory handle name");
162 ret
= fd_tracker_open_unsuspendable_fd(
163 tracker
, &dirfd
, (const char **) &handle_name
, 1, open_directory_handle
, &open_args
);
164 if (ret
&& ret
!= ENOTSUP
) {
165 ERR("Failed to open directory handle to %s through the fd tracker",
166 path
? path
: cwd_path
);
168 new_handle
= open_args
.ret_handle
;
171 new_handle
->destroy_cb
= directory_handle_destroy
;
172 new_handle
->destroy_cb_data
= tracker
;