Run clang-format on the whole tree
[lttng-tools.git] / src / common / fd-tracker / utils.cpp
CommitLineData
df038819 1/*
ab5be9fa 2 * Copyright (C) 2018 Jérémie Galarneau <jeremie.galarneau@efficios.com>
df038819 3 *
c922647d 4 * SPDX-License-Identifier: LGPL-2.1-only
df038819 5 *
df038819
JG
6 */
7
c9e313bc
SM
8#include <common/error.hpp>
9#include <common/fd-tracker/utils.hpp>
10#include <common/utils.hpp>
28ab034a 11
dd95933f 12#include <lttng/constant.h>
28ab034a 13
5c1f54d1
JG
14#include <stdio.h>
15#include <stdlib.h>
16#include <unistd.h>
c3e9c4c6 17
28ab034a 18static int open_pipe_cloexec(void *data __attribute__((unused)), int *fds)
c3e9c4c6 19{
e51dc192 20 return utils_create_pipe_cloexec(fds);
c3e9c4c6
JG
21}
22
28ab034a 23static int close_pipe(void *data __attribute__((unused)), int *pipe)
c3e9c4c6
JG
24{
25 utils_close_pipe(pipe);
26 pipe[0] = pipe[1] = -1;
27 return 0;
28}
df038819 29
f46376a1 30int fd_tracker_util_close_fd(void *unused __attribute__((unused)), int *fd)
df038819
JG
31{
32 return close(*fd);
33}
c3e9c4c6 34
28ab034a 35int fd_tracker_util_pipe_open_cloexec(struct fd_tracker *tracker, const char *name, int *pipe)
c3e9c4c6
JG
36{
37 int ret;
38 const char *name_prefix;
39 char *names[2];
40
41 name_prefix = name ? name : "Unknown pipe";
42 ret = asprintf(&names[0], "%s (read end)", name_prefix);
43 if (ret < 0) {
44 goto end;
45 }
46 ret = asprintf(&names[1], "%s (write end)", name_prefix);
47 if (ret < 0) {
48 goto end;
49 }
50
28ab034a
JG
51 ret = fd_tracker_open_unsuspendable_fd(
52 tracker, pipe, (const char **) names, 2, open_pipe_cloexec, NULL);
c3e9c4c6
JG
53 free(names[0]);
54 free(names[1]);
55end:
56 return ret;
57}
58
59int fd_tracker_util_pipe_close(struct fd_tracker *tracker, int *pipe)
60{
28ab034a 61 return fd_tracker_close_unsuspendable_fd(tracker, pipe, 2, close_pipe, NULL);
c3e9c4c6 62}
dd95933f 63
f1494934 64namespace {
dd95933f
JG
65struct open_directory_handle_args {
66 const struct lttng_directory_handle *in_handle;
67 struct lttng_directory_handle *ret_handle;
68 const char *path;
69};
f1494934 70} /* namespace */
dd95933f 71
28ab034a 72static int open_directory_handle(void *_args, int *out_fds)
dd95933f
JG
73{
74 int ret = 0;
e032c6fd 75 struct open_directory_handle_args *args = (open_directory_handle_args *) _args;
dd95933f
JG
76 struct lttng_directory_handle *new_handle = NULL;
77
78 new_handle = args->in_handle ?
28ab034a
JG
79 lttng_directory_handle_create_from_handle(args->path, args->in_handle) :
80 lttng_directory_handle_create(args->path);
dd95933f
JG
81 if (!new_handle) {
82 ret = -errno;
83 goto end;
84 }
85
86 args->ret_handle = new_handle;
87
88 /*
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.
93 *
94 * Calling this a hack is a fair assessment.
95 */
96 if (!lttng_directory_handle_uses_fd(new_handle)) {
97 ret = ENOTSUP;
98 } else {
4fb28dfc 99#ifdef HAVE_DIRFD
dd95933f
JG
100 *out_fds = new_handle->dirfd;
101#else
102 abort();
103#endif
dd95933f
JG
104 }
105end:
106 return ret;
107}
108
4fb28dfc 109#ifdef HAVE_DIRFD
28ab034a 110static int fd_close(void *unused __attribute__((unused)), int *in_fds)
dd95933f
JG
111{
112 const int ret = close(in_fds[0]);
113
114 in_fds[0] = -1;
115 return ret;
116}
117
28ab034a 118static void directory_handle_destroy(struct lttng_directory_handle *handle, void *data)
dd95933f 119{
e032c6fd 120 struct fd_tracker *tracker = (fd_tracker *) data;
28ab034a
JG
121 const int ret =
122 fd_tracker_close_unsuspendable_fd(tracker, &handle->dirfd, 1, fd_close, NULL);
dd95933f
JG
123
124 if (ret) {
125 ERR("Failed to untrack directory handle file descriptor");
126 }
127}
128#endif
129
28ab034a
JG
130struct lttng_directory_handle *fd_tracker_create_directory_handle(struct fd_tracker *tracker,
131 const char *path)
dd95933f 132{
28ab034a 133 return fd_tracker_create_directory_handle_from_handle(tracker, NULL, path);
dd95933f
JG
134}
135
dd95933f 136struct lttng_directory_handle *fd_tracker_create_directory_handle_from_handle(
28ab034a 137 struct fd_tracker *tracker, struct lttng_directory_handle *in_handle, const char *path)
dd95933f
JG
138{
139 int ret;
140 int dirfd = -1;
141 char *handle_name = NULL;
142 char cwd_path[LTTNG_PATH_MAX] = "working directory";
143 struct lttng_directory_handle *new_handle = NULL;
28ab034a 144 open_directory_handle_args open_args{};
e032c6fd
SM
145
146 open_args.in_handle = in_handle;
147 open_args.path = path;
dd95933f
JG
148
149 if (!path) {
150 if (!getcwd(cwd_path, sizeof(cwd_path))) {
151 PERROR("Failed to get current working directory to name directory handle");
152 goto end;
153 }
154 }
155
28ab034a 156 ret = asprintf(&handle_name, "Directory handle to %s", path ? path : cwd_path);
dd95933f
JG
157 if (ret < 0) {
158 PERROR("Failed to format directory handle name");
159 goto end;
160 }
161
28ab034a
JG
162 ret = fd_tracker_open_unsuspendable_fd(
163 tracker, &dirfd, (const char **) &handle_name, 1, open_directory_handle, &open_args);
dd95933f 164 if (ret && ret != ENOTSUP) {
28ab034a
JG
165 ERR("Failed to open directory handle to %s through the fd tracker",
166 path ? path : cwd_path);
dd95933f
JG
167 }
168 new_handle = open_args.ret_handle;
169
4fb28dfc 170#ifdef HAVE_DIRFD
dd95933f
JG
171 new_handle->destroy_cb = directory_handle_destroy;
172 new_handle->destroy_cb_data = tracker;
173#endif
174end:
175 free(handle_name);
176 return new_handle;
177}
This page took 0.049784 seconds and 4 git commands to generate.