Branch data Line data Source code
# 1 : : // Copyright (c) 2021 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> # 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 : 668 : { # 17 : 668 : TokenPipeEnd res(m_fds[0]); # 18 : 668 : m_fds[0] = -1; # 19 : 668 : return res; # 20 : 668 : } # 21 : : # 22 : : TokenPipeEnd TokenPipe::TakeWriteEnd() # 23 : 668 : { # 24 : 668 : TokenPipeEnd res(m_fds[1]); # 25 : 668 : m_fds[1] = -1; # 26 : 668 : return res; # 27 : 668 : } # 28 : : # 29 : : TokenPipeEnd::TokenPipeEnd(int fd) : m_fd(fd) # 30 : 3395 : { # 31 : 3395 : } # 32 : : # 33 : : TokenPipeEnd::~TokenPipeEnd() # 34 : 2015 : { # 35 : 2015 : Close(); # 36 : 2015 : } # 37 : : # 38 : : int TokenPipeEnd::TokenWrite(uint8_t token) # 39 : 618 : { # 40 : 618 : while (true) { # 41 : 618 : ssize_t result = write(m_fd, &token, 1); # 42 [ - + ]: 618 : if (result < 0) { # 43 : : // Failure. It's possible that the write was interrupted by a signal, # 44 : : // in that case retry. # 45 [ # # ]: 0 : if (errno != EINTR) { # 46 : 0 : return TS_ERR; # 47 : 0 : } # 48 [ - + ]: 618 : } else if (result == 0) { # 49 : 0 : return TS_EOS; # 50 : 618 : } else { // ==1 # 51 : 618 : return 0; # 52 : 618 : } # 53 : 618 : } # 54 : 618 : } # 55 : : # 56 : : int TokenPipeEnd::TokenRead() # 57 : 618 : { # 58 : 618 : uint8_t token; # 59 : 618 : while (true) { # 60 : 618 : ssize_t result = read(m_fd, &token, 1); # 61 [ - + ]: 618 : if (result < 0) { # 62 : : // Failure. Check if the read was interrupted by a signal, # 63 : : // in that case retry. # 64 [ # # ]: 0 : if (errno != EINTR) { # 65 : 0 : return TS_ERR; # 66 : 0 : } # 67 [ - + ]: 618 : } else if (result == 0) { # 68 : 0 : return TS_EOS; # 69 : 618 : } else { // ==1 # 70 : 618 : return token; # 71 : 618 : } # 72 : 618 : } # 73 : 618 : return token; # 74 : 618 : } # 75 : : # 76 : : void TokenPipeEnd::Close() # 77 : 3351 : { # 78 [ - + ]: 3351 : if (m_fd != -1) close(m_fd); # 79 : 3351 : m_fd = -1; # 80 : 3351 : } # 81 : : # 82 : : std::optional<TokenPipe> TokenPipe::Make() # 83 : 668 : { # 84 : 668 : int fds[2] = {-1, -1}; # 85 : 668 : #if HAVE_O_CLOEXEC && HAVE_DECL_PIPE2 # 86 [ - + ]: 668 : if (pipe2(fds, O_CLOEXEC) != 0) { # 87 : 0 : return std::nullopt; # 88 : 0 : } # 89 : : #else # 90 : : if (pipe(fds) != 0) { # 91 : : return std::nullopt; # 92 : : } # 93 : : #endif # 94 : 668 : return TokenPipe(fds); # 95 : 668 : } # 96 : : # 97 : : TokenPipe::~TokenPipe() # 98 : 1336 : { # 99 : 1336 : Close(); # 100 : 1336 : } # 101 : : # 102 : : void TokenPipe::Close() # 103 : 1336 : { # 104 [ - + ]: 1336 : if (m_fds[0] != -1) close(m_fds[0]); # 105 [ - + ]: 1336 : if (m_fds[1] != -1) close(m_fds[1]); # 106 : 1336 : m_fds[0] = m_fds[1] = -1; # 107 : 1336 : } # 108 : : # 109 : : #endif // WIN32