Fix: sessiond: ODR violation results in memory corruption
[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>
dd95933f 11#include <lttng/constant.h>
5c1f54d1
JG
12#include <stdio.h>
13#include <stdlib.h>
14#include <unistd.h>
c3e9c4c6 15
dd95933f 16static
f46376a1 17int open_pipe_cloexec(void *data __attribute__((unused)), int *fds)
c3e9c4c6 18{
e51dc192 19 return utils_create_pipe_cloexec(fds);
c3e9c4c6
JG
20}
21
dd95933f 22static
f46376a1 23int 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
5c1f54d1
JG
35int fd_tracker_util_pipe_open_cloexec(
36 struct fd_tracker *tracker, const char *name, int *pipe)
c3e9c4c6
JG
37{
38 int ret;
39 const char *name_prefix;
40 char *names[2];
41
42 name_prefix = name ? name : "Unknown pipe";
43 ret = asprintf(&names[0], "%s (read end)", name_prefix);
44 if (ret < 0) {
45 goto end;
46 }
47 ret = asprintf(&names[1], "%s (write end)", name_prefix);
48 if (ret < 0) {
49 goto end;
50 }
51
5c1f54d1 52 ret = fd_tracker_open_unsuspendable_fd(tracker, pipe,
c3e9c4c6
JG
53 (const char **) names, 2, open_pipe_cloexec, NULL);
54 free(names[0]);
55 free(names[1]);
56end:
57 return ret;
58}
59
60int fd_tracker_util_pipe_close(struct fd_tracker *tracker, int *pipe)
61{
5c1f54d1
JG
62 return fd_tracker_close_unsuspendable_fd(
63 tracker, pipe, 2, close_pipe, NULL);
c3e9c4c6 64}
dd95933f 65
f1494934 66namespace {
dd95933f
JG
67struct open_directory_handle_args {
68 const struct lttng_directory_handle *in_handle;
69 struct lttng_directory_handle *ret_handle;
70 const char *path;
71};
f1494934 72} /* namespace */
dd95933f
JG
73
74static
75int open_directory_handle(void *_args, int *out_fds)
76{
77 int ret = 0;
e032c6fd 78 struct open_directory_handle_args *args = (open_directory_handle_args *) _args;
dd95933f
JG
79 struct lttng_directory_handle *new_handle = NULL;
80
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);
85 if (!new_handle) {
86 ret = -errno;
87 goto end;
88 }
89
90 args->ret_handle = new_handle;
91
92 /*
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.
97 *
98 * Calling this a hack is a fair assessment.
99 */
100 if (!lttng_directory_handle_uses_fd(new_handle)) {
101 ret = ENOTSUP;
102 } else {
4fb28dfc 103#ifdef HAVE_DIRFD
dd95933f
JG
104 *out_fds = new_handle->dirfd;
105#else
106 abort();
107#endif
108
109 }
110end:
111 return ret;
112}
113
4fb28dfc 114#ifdef HAVE_DIRFD
dd95933f 115static
f46376a1 116int fd_close(void *unused __attribute__((unused)), int *in_fds)
dd95933f
JG
117{
118 const int ret = close(in_fds[0]);
119
120 in_fds[0] = -1;
121 return ret;
122}
123
124static
125void directory_handle_destroy(
126 struct lttng_directory_handle *handle, void *data)
127{
e032c6fd 128 struct fd_tracker *tracker = (fd_tracker *) data;
dd95933f
JG
129 const int ret = fd_tracker_close_unsuspendable_fd(
130 tracker, &handle->dirfd, 1, fd_close, NULL);
131
132 if (ret) {
133 ERR("Failed to untrack directory handle file descriptor");
134 }
135}
136#endif
137
dd95933f
JG
138struct lttng_directory_handle *fd_tracker_create_directory_handle(
139 struct fd_tracker *tracker, const char *path)
140{
141 return fd_tracker_create_directory_handle_from_handle(
142 tracker, NULL, path);
143}
144
dd95933f
JG
145struct lttng_directory_handle *fd_tracker_create_directory_handle_from_handle(
146 struct fd_tracker *tracker,
147 struct lttng_directory_handle *in_handle,
148 const char *path)
149{
150 int ret;
151 int dirfd = -1;
152 char *handle_name = NULL;
153 char cwd_path[LTTNG_PATH_MAX] = "working directory";
154 struct lttng_directory_handle *new_handle = NULL;
e032c6fd
SM
155 open_directory_handle_args open_args {};
156
157 open_args.in_handle = in_handle;
158 open_args.path = path;
dd95933f
JG
159
160 if (!path) {
161 if (!getcwd(cwd_path, sizeof(cwd_path))) {
162 PERROR("Failed to get current working directory to name directory handle");
163 goto end;
164 }
165 }
166
167 ret = asprintf(&handle_name, "Directory handle to %s",
168 path ? path : cwd_path);
169 if (ret < 0) {
170 PERROR("Failed to format directory handle name");
171 goto end;
172 }
173
174 ret = fd_tracker_open_unsuspendable_fd(tracker, &dirfd,
175 (const char **) &handle_name, 1, open_directory_handle,
176 &open_args);
177 if (ret && ret != ENOTSUP) {
178 ERR("Failed to open directory handle to %s through the fd tracker", path ? path : cwd_path);
179 }
180 new_handle = open_args.ret_handle;
181
4fb28dfc 182#ifdef HAVE_DIRFD
dd95933f
JG
183 new_handle->destroy_cb = directory_handle_destroy;
184 new_handle->destroy_cb_data = tracker;
185#endif
186end:
187 free(handle_name);
188 return new_handle;
189}
This page took 0.046089 seconds and 4 git commands to generate.