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 | ||
24 | assert(handle->fd >= 0); | |
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 | ||
34 | LTTNG_HIDDEN | |
35 | struct fd_handle *fd_handle_create(int fd) | |
36 | { | |
37 | struct fd_handle *handle = NULL; | |
38 | ||
39 | if (fd < 0) { | |
40 | ERR("Attempted to create an fd_handle from an invalid file descriptor: fd = %d", | |
41 | fd); | |
42 | goto end; | |
43 | } | |
44 | ||
45 | handle = zmalloc(sizeof(*handle)); | |
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 | ||
58 | LTTNG_HIDDEN | |
59 | void fd_handle_get(struct fd_handle *handle) | |
60 | { | |
fe489250 JG |
61 | if (!handle) { |
62 | return; | |
63 | } | |
64 | ||
dd1bac00 JG |
65 | urcu_ref_get(&handle->ref); |
66 | } | |
67 | ||
68 | LTTNG_HIDDEN | |
69 | void fd_handle_put(struct fd_handle *handle) | |
70 | { | |
fe489250 JG |
71 | if (!handle) { |
72 | return; | |
73 | } | |
74 | ||
dd1bac00 JG |
75 | urcu_ref_put(&handle->ref, fd_handle_release); |
76 | } | |
77 | ||
78 | LTTNG_HIDDEN | |
79 | int fd_handle_get_fd(struct fd_handle *handle) | |
80 | { | |
81 | assert(handle); | |
82 | return handle->fd; | |
83 | } | |
84 | ||
85 | LTTNG_HIDDEN | |
86 | struct fd_handle *fd_handle_copy(const struct fd_handle *handle) | |
87 | { | |
88 | struct fd_handle *new_handle = NULL; | |
89 | const int new_fd = dup(handle->fd); | |
90 | ||
91 | if (new_fd < 0) { | |
92 | PERROR("Failed to duplicate file descriptor while copying fd_handle: fd = %d", handle->fd); | |
93 | goto end; | |
94 | } | |
95 | ||
96 | new_handle = fd_handle_create(new_fd); | |
97 | end: | |
98 | return new_handle; | |
99 | } |