/bitcoin/src/util/tokenpipe.cpp
Line | Count | Source |
1 | | // Copyright (c) 2021-2022 The Bitcoin Core developers |
2 | | // Distributed under the MIT software license, see the accompanying |
3 | | // file COPYING or http://www.opensource.org/licenses/mit-license.php. |
4 | | #include <util/tokenpipe.h> |
5 | | |
6 | | #include <bitcoin-build-config.h> // IWYU pragma: keep |
7 | | |
8 | | #ifndef WIN32 |
9 | | |
10 | | #include <errno.h> |
11 | | #include <fcntl.h> |
12 | | #include <optional> |
13 | | #include <unistd.h> |
14 | | |
15 | | TokenPipeEnd TokenPipe::TakeReadEnd() |
16 | 11.0k | { |
17 | 11.0k | TokenPipeEnd res(m_fds[0]); |
18 | 11.0k | m_fds[0] = -1; |
19 | 11.0k | return res; |
20 | 11.0k | } |
21 | | |
22 | | TokenPipeEnd TokenPipe::TakeWriteEnd() |
23 | 11.0k | { |
24 | 11.0k | TokenPipeEnd res(m_fds[1]); |
25 | 11.0k | m_fds[1] = -1; |
26 | 11.0k | return res; |
27 | 11.0k | } |
28 | | |
29 | 55.4k | TokenPipeEnd::TokenPipeEnd(int fd) : m_fd(fd) |
30 | 55.4k | { |
31 | 55.4k | } |
32 | | |
33 | | TokenPipeEnd::~TokenPipeEnd() |
34 | 33.2k | { |
35 | 33.2k | Close(); |
36 | 33.2k | } |
37 | | |
38 | | int TokenPipeEnd::TokenWrite(uint8_t token) |
39 | 11.0k | { |
40 | 11.0k | while (true) { Branch (40:12): [Folded - Ignored]
|
41 | 11.0k | ssize_t result = write(m_fd, &token, 1); |
42 | 11.0k | if (result < 0) { Branch (42:13): [True: 0, False: 11.0k]
|
43 | | // Failure. It's possible that the write was interrupted by a signal, |
44 | | // in that case retry. |
45 | 0 | if (errno != EINTR) { Branch (45:17): [True: 0, False: 0]
|
46 | 0 | return TS_ERR; |
47 | 0 | } |
48 | 11.0k | } else if (result == 0) { Branch (48:20): [True: 0, False: 11.0k]
|
49 | 0 | return TS_EOS; |
50 | 11.0k | } else { // ==1 |
51 | 11.0k | return 0; |
52 | 11.0k | } |
53 | 11.0k | } |
54 | 11.0k | } |
55 | | |
56 | | int TokenPipeEnd::TokenRead() |
57 | 11.0k | { |
58 | 11.0k | uint8_t token; |
59 | 11.0k | while (true) { Branch (59:12): [Folded - Ignored]
|
60 | 11.0k | ssize_t result = read(m_fd, &token, 1); |
61 | 11.0k | if (result < 0) { Branch (61:13): [True: 0, False: 11.0k]
|
62 | | // Failure. Check if the read was interrupted by a signal, |
63 | | // in that case retry. |
64 | 0 | if (errno != EINTR) { Branch (64:17): [True: 0, False: 0]
|
65 | 0 | return TS_ERR; |
66 | 0 | } |
67 | 11.0k | } else if (result == 0) { Branch (67:20): [True: 0, False: 11.0k]
|
68 | 0 | return TS_EOS; |
69 | 11.0k | } else { // ==1 |
70 | 11.0k | return token; |
71 | 11.0k | } |
72 | 11.0k | } |
73 | 0 | return token; |
74 | 11.0k | } |
75 | | |
76 | | void TokenPipeEnd::Close() |
77 | 55.4k | { |
78 | 55.4k | if (m_fd != -1) close(m_fd); Branch (78:9): [True: 0, False: 55.4k]
|
79 | 55.4k | m_fd = -1; |
80 | 55.4k | } |
81 | | |
82 | | std::optional<TokenPipe> TokenPipe::Make() |
83 | 11.0k | { |
84 | 11.0k | int fds[2] = {-1, -1}; |
85 | 11.0k | #if HAVE_O_CLOEXEC && HAVE_DECL_PIPE2 |
86 | 11.0k | if (pipe2(fds, O_CLOEXEC) != 0) { Branch (86:9): [True: 0, False: 11.0k]
|
87 | 0 | return std::nullopt; |
88 | 0 | } |
89 | | #else |
90 | | if (pipe(fds) != 0) { |
91 | | return std::nullopt; |
92 | | } |
93 | | #endif |
94 | 11.0k | return TokenPipe(fds); |
95 | 11.0k | } |
96 | | |
97 | | TokenPipe::~TokenPipe() |
98 | 22.1k | { |
99 | 22.1k | Close(); |
100 | 22.1k | } |
101 | | |
102 | | void TokenPipe::Close() |
103 | 22.1k | { |
104 | 22.1k | if (m_fds[0] != -1) close(m_fds[0]); Branch (104:9): [True: 0, False: 22.1k]
|
105 | 22.1k | if (m_fds[1] != -1) close(m_fds[1]); Branch (105:9): [True: 0, False: 22.1k]
|
106 | 22.1k | m_fds[0] = m_fds[1] = -1; |
107 | 22.1k | } |
108 | | |
109 | | #endif // WIN32 |