Bitcoin Core  27.99.0
P2P Digital Currency
tokenpipe.cpp
Go to the documentation of this file.
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 <config/bitcoin-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 
16 {
17  TokenPipeEnd res(m_fds[0]);
18  m_fds[0] = -1;
19  return res;
20 }
21 
23 {
24  TokenPipeEnd res(m_fds[1]);
25  m_fds[1] = -1;
26  return res;
27 }
28 
29 TokenPipeEnd::TokenPipeEnd(int fd) : m_fd(fd)
30 {
31 }
32 
34 {
35  Close();
36 }
37 
38 int TokenPipeEnd::TokenWrite(uint8_t token)
39 {
40  while (true) {
41  ssize_t result = write(m_fd, &token, 1);
42  if (result < 0) {
43  // Failure. It's possible that the write was interrupted by a signal,
44  // in that case retry.
45  if (errno != EINTR) {
46  return TS_ERR;
47  }
48  } else if (result == 0) {
49  return TS_EOS;
50  } else { // ==1
51  return 0;
52  }
53  }
54 }
55 
57 {
58  uint8_t token;
59  while (true) {
60  ssize_t result = read(m_fd, &token, 1);
61  if (result < 0) {
62  // Failure. Check if the read was interrupted by a signal,
63  // in that case retry.
64  if (errno != EINTR) {
65  return TS_ERR;
66  }
67  } else if (result == 0) {
68  return TS_EOS;
69  } else { // ==1
70  return token;
71  }
72  }
73  return token;
74 }
75 
77 {
78  if (m_fd != -1) close(m_fd);
79  m_fd = -1;
80 }
81 
82 std::optional<TokenPipe> TokenPipe::Make()
83 {
84  int fds[2] = {-1, -1};
85 #if HAVE_O_CLOEXEC && HAVE_DECL_PIPE2
86  if (pipe2(fds, O_CLOEXEC) != 0) {
87  return std::nullopt;
88  }
89 #else
90  if (pipe(fds) != 0) {
91  return std::nullopt;
92  }
93 #endif
94  return TokenPipe(fds);
95 }
96 
98 {
99  Close();
100 }
101 
103 {
104  if (m_fds[0] != -1) close(m_fds[0]);
105  if (m_fds[1] != -1) close(m_fds[1]);
106  m_fds[0] = m_fds[1] = -1;
107 }
108 
109 #endif // WIN32
One end of a token pipe.
Definition: tokenpipe.h:15
TokenPipeEnd(int fd=-1)
Definition: tokenpipe.cpp:29
@ TS_ERR
I/O error.
Definition: tokenpipe.h:25
@ TS_EOS
Unexpected end of stream.
Definition: tokenpipe.h:26
int TokenWrite(uint8_t token)
Write token to endpoint.
Definition: tokenpipe.cpp:38
void Close()
Explicit close function.
Definition: tokenpipe.cpp:76
int TokenRead()
Read token from endpoint.
Definition: tokenpipe.cpp:56
void Close()
Close and end of the pipe that hasn't been moved out.
Definition: tokenpipe.cpp:102
TokenPipeEnd TakeReadEnd()
Take the read end of this pipe.
Definition: tokenpipe.cpp:15
TokenPipeEnd TakeWriteEnd()
Take the write end of this pipe.
Definition: tokenpipe.cpp:22
int m_fds[2]
Definition: tokenpipe.h:78
static std::optional< TokenPipe > Make()
Create a new pipe.
Definition: tokenpipe.cpp:82
TokenPipe(int fds[2])
Definition: tokenpipe.h:80