2 * Copyright (C) 2018 Jérémie Galarneau <jeremie.galarneau@efficios.com>
4 * SPDX-License-Identifier: GPL-2.0-only
8 #include <common/error.h>
9 #include <common/fd-tracker/utils.h>
10 #include <common/utils.h>
11 #include <lttng/constant.h>
17 int open_pipe_cloexec(void *data
, int *fds
)
19 return utils_create_pipe_cloexec(fds
);
23 int close_pipe(void *data
, int *pipe
)
25 utils_close_pipe(pipe
);
26 pipe
[0] = pipe
[1] = -1;
30 int fd_tracker_util_close_fd(void *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
);
66 struct open_directory_handle_args
{
67 const struct lttng_directory_handle
*in_handle
;
68 struct lttng_directory_handle
*ret_handle
;
73 int open_directory_handle(void *_args
, int *out_fds
)
76 struct open_directory_handle_args
*args
= (open_directory_handle_args
*) _args
;
77 struct lttng_directory_handle
*new_handle
= NULL
;
79 new_handle
= args
->in_handle
?
80 lttng_directory_handle_create_from_handle(
81 args
->path
, args
->in_handle
) :
82 lttng_directory_handle_create(args
->path
);
88 args
->ret_handle
= new_handle
;
91 * Reserved to indicate that the handle does not use a handle; there is
92 * nothing to track. We want to indicate an error to the fd-tracker so
93 * that it doesn't attempt to track the file descriptor, but also want
94 * the caller to retrieve the newly-created handle.
96 * Calling this a hack is a fair assessment.
98 if (!lttng_directory_handle_uses_fd(new_handle
)) {
102 *out_fds
= new_handle
->dirfd
;
114 int fd_close(void *unused
, int *in_fds
)
116 const int ret
= close(in_fds
[0]);
123 void directory_handle_destroy(
124 struct lttng_directory_handle
*handle
, void *data
)
126 struct fd_tracker
*tracker
= (fd_tracker
*) data
;
127 const int ret
= fd_tracker_close_unsuspendable_fd(
128 tracker
, &handle
->dirfd
, 1, fd_close
, NULL
);
131 ERR("Failed to untrack directory handle file descriptor");
136 struct lttng_directory_handle
*fd_tracker_create_directory_handle(
137 struct fd_tracker
*tracker
, const char *path
)
139 return fd_tracker_create_directory_handle_from_handle(
140 tracker
, NULL
, path
);
143 struct lttng_directory_handle
*fd_tracker_create_directory_handle_from_handle(
144 struct fd_tracker
*tracker
,
145 struct lttng_directory_handle
*in_handle
,
150 char *handle_name
= NULL
;
151 char cwd_path
[LTTNG_PATH_MAX
] = "working directory";
152 struct lttng_directory_handle
*new_handle
= NULL
;
153 open_directory_handle_args open_args
{};
155 open_args
.in_handle
= in_handle
;
156 open_args
.path
= path
;
159 if (!getcwd(cwd_path
, sizeof(cwd_path
))) {
160 PERROR("Failed to get current working directory to name directory handle");
165 ret
= asprintf(&handle_name
, "Directory handle to %s",
166 path
? path
: cwd_path
);
168 PERROR("Failed to format directory handle name");
172 ret
= fd_tracker_open_unsuspendable_fd(tracker
, &dirfd
,
173 (const char **) &handle_name
, 1, open_directory_handle
,
175 if (ret
&& ret
!= ENOTSUP
) {
176 ERR("Failed to open directory handle to %s through the fd tracker", path
? path
: cwd_path
);
178 new_handle
= open_args
.ret_handle
;
181 new_handle
->destroy_cb
= directory_handle_destroy
;
182 new_handle
->destroy_cb_data
= tracker
;