Commit | Line | Data |
---|---|---|
dd1bac00 JG |
1 | /* |
2 | * Copyright (C) 2020 Jérémie Galarneau <jeremie.galarneau@efficios.com> | |
3 | * | |
4 | * SPDX-License-Identifier: LGPL-2.1-only | |
5 | * | |
6 | */ | |
7 | ||
c9e313bc | 8 | #include "fd-handle.hpp" |
28ab034a | 9 | |
c9e313bc | 10 | #include <common/error.hpp> |
dd1bac00 | 11 | |
28ab034a JG |
12 | #include <unistd.h> |
13 | #include <urcu/ref.h> | |
14 | ||
dd1bac00 JG |
15 | struct fd_handle { |
16 | struct urcu_ref ref; | |
17 | int fd; | |
18 | }; | |
19 | ||
20 | static void fd_handle_release(struct urcu_ref *ref) | |
21 | { | |
22 | int ret; | |
0114db0e | 23 | struct fd_handle *handle = lttng::utils::container_of(ref, &fd_handle::ref); |
dd1bac00 | 24 | |
a0377dfe | 25 | LTTNG_ASSERT(handle->fd >= 0); |
dd1bac00 JG |
26 | ret = close(handle->fd); |
27 | if (ret == -1) { | |
28 | PERROR("Failed to close file descriptor of fd_handle upon release: fd = %d", | |
28ab034a | 29 | handle->fd); |
dd1bac00 JG |
30 | } |
31 | ||
32 | free(handle); | |
33 | } | |
34 | ||
dd1bac00 JG |
35 | struct fd_handle *fd_handle_create(int fd) |
36 | { | |
cd9adb8b | 37 | struct fd_handle *handle = nullptr; |
dd1bac00 JG |
38 | |
39 | if (fd < 0) { | |
40 | ERR("Attempted to create an fd_handle from an invalid file descriptor: fd = %d", | |
28ab034a | 41 | fd); |
dd1bac00 JG |
42 | goto end; |
43 | } | |
44 | ||
64803277 | 45 | handle = zmalloc<fd_handle>(); |
dd1bac00 JG |
46 | if (!handle) { |
47 | PERROR("Failed to allocate fd_handle"); | |
48 | goto end; | |
49 | } | |
50 | ||
51 | urcu_ref_init(&handle->ref); | |
52 | handle->fd = fd; | |
53 | ||
54 | end: | |
55 | return handle; | |
56 | } | |
57 | ||
dd1bac00 JG |
58 | void fd_handle_get(struct fd_handle *handle) |
59 | { | |
fe489250 JG |
60 | if (!handle) { |
61 | return; | |
62 | } | |
63 | ||
dd1bac00 JG |
64 | urcu_ref_get(&handle->ref); |
65 | } | |
66 | ||
dd1bac00 JG |
67 | void fd_handle_put(struct fd_handle *handle) |
68 | { | |
fe489250 JG |
69 | if (!handle) { |
70 | return; | |
71 | } | |
72 | ||
dd1bac00 JG |
73 | urcu_ref_put(&handle->ref, fd_handle_release); |
74 | } | |
75 | ||
dd1bac00 JG |
76 | int fd_handle_get_fd(struct fd_handle *handle) |
77 | { | |
a0377dfe | 78 | LTTNG_ASSERT(handle); |
dd1bac00 JG |
79 | return handle->fd; |
80 | } | |
81 | ||
dd1bac00 JG |
82 | struct fd_handle *fd_handle_copy(const struct fd_handle *handle) |
83 | { | |
cd9adb8b | 84 | struct fd_handle *new_handle = nullptr; |
dd1bac00 JG |
85 | const int new_fd = dup(handle->fd); |
86 | ||
87 | if (new_fd < 0) { | |
28ab034a JG |
88 | PERROR("Failed to duplicate file descriptor while copying fd_handle: fd = %d", |
89 | handle->fd); | |
dd1bac00 JG |
90 | goto end; |
91 | } | |
92 | ||
93 | new_handle = fd_handle_create(new_fd); | |
94 | end: | |
95 | return new_handle; | |
96 | } |