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 | ||
8 | #include <unistd.h> | |
9 | #include <urcu/ref.h> | |
10 | ||
11 | #include "fd-handle.h" | |
12 | #include <common/error.h> | |
13 | ||
14 | struct fd_handle { | |
15 | struct urcu_ref ref; | |
16 | int fd; | |
17 | }; | |
18 | ||
19 | static void fd_handle_release(struct urcu_ref *ref) | |
20 | { | |
21 | int ret; | |
22 | struct fd_handle *handle = container_of(ref, struct fd_handle, ref); | |
23 | ||
a0377dfe | 24 | LTTNG_ASSERT(handle->fd >= 0); |
dd1bac00 JG |
25 | ret = close(handle->fd); |
26 | if (ret == -1) { | |
27 | PERROR("Failed to close file descriptor of fd_handle upon release: fd = %d", | |
28 | handle->fd); | |
29 | } | |
30 | ||
31 | free(handle); | |
32 | } | |
33 | ||
dd1bac00 JG |
34 | struct fd_handle *fd_handle_create(int fd) |
35 | { | |
36 | struct fd_handle *handle = NULL; | |
37 | ||
38 | if (fd < 0) { | |
39 | ERR("Attempted to create an fd_handle from an invalid file descriptor: fd = %d", | |
40 | fd); | |
41 | goto end; | |
42 | } | |
43 | ||
a6bc4ca9 | 44 | handle = (fd_handle *) zmalloc(sizeof(*handle)); |
dd1bac00 JG |
45 | if (!handle) { |
46 | PERROR("Failed to allocate fd_handle"); | |
47 | goto end; | |
48 | } | |
49 | ||
50 | urcu_ref_init(&handle->ref); | |
51 | handle->fd = fd; | |
52 | ||
53 | end: | |
54 | return handle; | |
55 | } | |
56 | ||
dd1bac00 JG |
57 | void fd_handle_get(struct fd_handle *handle) |
58 | { | |
fe489250 JG |
59 | if (!handle) { |
60 | return; | |
61 | } | |
62 | ||
dd1bac00 JG |
63 | urcu_ref_get(&handle->ref); |
64 | } | |
65 | ||
dd1bac00 JG |
66 | void fd_handle_put(struct fd_handle *handle) |
67 | { | |
fe489250 JG |
68 | if (!handle) { |
69 | return; | |
70 | } | |
71 | ||
dd1bac00 JG |
72 | urcu_ref_put(&handle->ref, fd_handle_release); |
73 | } | |
74 | ||
dd1bac00 JG |
75 | int fd_handle_get_fd(struct fd_handle *handle) |
76 | { | |
a0377dfe | 77 | LTTNG_ASSERT(handle); |
dd1bac00 JG |
78 | return handle->fd; |
79 | } | |
80 | ||
dd1bac00 JG |
81 | struct fd_handle *fd_handle_copy(const struct fd_handle *handle) |
82 | { | |
83 | struct fd_handle *new_handle = NULL; | |
84 | const int new_fd = dup(handle->fd); | |
85 | ||
86 | if (new_fd < 0) { | |
87 | PERROR("Failed to duplicate file descriptor while copying fd_handle: fd = %d", handle->fd); | |
88 | goto end; | |
89 | } | |
90 | ||
91 | new_handle = fd_handle_create(new_fd); | |
92 | end: | |
93 | return new_handle; | |
94 | } |