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>
11 #include <lttng/constant.h>
17 int open_pipe_cloexec(void *data
__attribute__((unused
)), int *fds
)
19 return utils_create_pipe_cloexec(fds
);
23 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(
36 struct fd_tracker
*tracker
, const char *name
, int *pipe
)
39 const char *name_prefix
;
42 name_prefix
= name
? name
: "Unknown pipe";
43 ret
= asprintf(&names
[0], "%s (read end)", name_prefix
);
47 ret
= asprintf(&names
[1], "%s (write end)", name_prefix
);
52 ret
= fd_tracker_open_unsuspendable_fd(tracker
, pipe
,
53 (const char **) names
, 2, open_pipe_cloexec
, NULL
);
60 int fd_tracker_util_pipe_close(struct fd_tracker
*tracker
, int *pipe
)
62 return fd_tracker_close_unsuspendable_fd(
63 tracker
, pipe
, 2, close_pipe
, NULL
);
67 struct open_directory_handle_args
{
68 const struct lttng_directory_handle
*in_handle
;
69 struct lttng_directory_handle
*ret_handle
;
75 int open_directory_handle(void *_args
, int *out_fds
)
78 struct open_directory_handle_args
*args
= (open_directory_handle_args
*) _args
;
79 struct lttng_directory_handle
*new_handle
= NULL
;
81 new_handle
= args
->in_handle
?
82 lttng_directory_handle_create_from_handle(
83 args
->path
, args
->in_handle
) :
84 lttng_directory_handle_create(args
->path
);
90 args
->ret_handle
= new_handle
;
93 * Reserved to indicate that the handle does not use a handle; there is
94 * nothing to track. We want to indicate an error to the fd-tracker so
95 * that it doesn't attempt to track the file descriptor, but also want
96 * the caller to retrieve the newly-created handle.
98 * Calling this a hack is a fair assessment.
100 if (!lttng_directory_handle_uses_fd(new_handle
)) {
104 *out_fds
= new_handle
->dirfd
;
116 int fd_close(void *unused
__attribute__((unused
)), int *in_fds
)
118 const int ret
= close(in_fds
[0]);
125 void directory_handle_destroy(
126 struct lttng_directory_handle
*handle
, void *data
)
128 struct fd_tracker
*tracker
= (fd_tracker
*) data
;
129 const int ret
= fd_tracker_close_unsuspendable_fd(
130 tracker
, &handle
->dirfd
, 1, fd_close
, NULL
);
133 ERR("Failed to untrack directory handle file descriptor");
138 struct lttng_directory_handle
*fd_tracker_create_directory_handle(
139 struct fd_tracker
*tracker
, const char *path
)
141 return fd_tracker_create_directory_handle_from_handle(
142 tracker
, NULL
, path
);
145 struct lttng_directory_handle
*fd_tracker_create_directory_handle_from_handle(
146 struct fd_tracker
*tracker
,
147 struct lttng_directory_handle
*in_handle
,
152 char *handle_name
= NULL
;
153 char cwd_path
[LTTNG_PATH_MAX
] = "working directory";
154 struct lttng_directory_handle
*new_handle
= NULL
;
155 open_directory_handle_args open_args
{};
157 open_args
.in_handle
= in_handle
;
158 open_args
.path
= path
;
161 if (!getcwd(cwd_path
, sizeof(cwd_path
))) {
162 PERROR("Failed to get current working directory to name directory handle");
167 ret
= asprintf(&handle_name
, "Directory handle to %s",
168 path
? path
: cwd_path
);
170 PERROR("Failed to format directory handle name");
174 ret
= fd_tracker_open_unsuspendable_fd(tracker
, &dirfd
,
175 (const char **) &handle_name
, 1, open_directory_handle
,
177 if (ret
&& ret
!= ENOTSUP
) {
178 ERR("Failed to open directory handle to %s through the fd tracker", path
? path
: cwd_path
);
180 new_handle
= open_args
.ret_handle
;
183 new_handle
->destroy_cb
= directory_handle_destroy
;
184 new_handle
->destroy_cb_data
= tracker
;