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