LCOV - code coverage report
Current view: top level - src/util - tokenpipe.cpp (source / functions) Hit Total Coverage
Test: fuzz_coverage.info Lines: 32 53 60.4 %
Date: 2023-09-26 12:08:55 Functions: 8 10 80.0 %

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

Generated by: LCOV version 1.14