Coverage Report

Created: 2025-02-21 14:37

/root/bitcoin/src/util/tokenpipe.cpp
Line
Count
Source (jump to first uncovered line)
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
0
{
17
0
    TokenPipeEnd res(m_fds[0]);
18
0
    m_fds[0] = -1;
19
0
    return res;
20
0
}
21
22
TokenPipeEnd TokenPipe::TakeWriteEnd()
23
0
{
24
0
    TokenPipeEnd res(m_fds[1]);
25
0
    m_fds[1] = -1;
26
0
    return res;
27
0
}
28
29
0
TokenPipeEnd::TokenPipeEnd(int fd) : m_fd(fd)
30
0
{
31
0
}
32
33
TokenPipeEnd::~TokenPipeEnd()
34
0
{
35
0
    Close();
36
0
}
37
38
int TokenPipeEnd::TokenWrite(uint8_t token)
39
0
{
40
0
    while (true) {
41
0
        ssize_t result = write(m_fd, &token, 1);
42
0
        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
0
        } else if (result == 0) {
49
0
            return TS_EOS;
50
0
        } else { // ==1
51
0
            return 0;
52
0
        }
53
0
    }
54
0
}
55
56
int TokenPipeEnd::TokenRead()
57
0
{
58
0
    uint8_t token;
59
0
    while (true) {
60
0
        ssize_t result = read(m_fd, &token, 1);
61
0
        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
0
        } else if (result == 0) {
68
0
            return TS_EOS;
69
0
        } else { // ==1
70
0
            return token;
71
0
        }
72
0
    }
73
0
    return token;
74
0
}
75
76
void TokenPipeEnd::Close()
77
0
{
78
0
    if (m_fd != -1) close(m_fd);
79
0
    m_fd = -1;
80
0
}
81
82
std::optional<TokenPipe> TokenPipe::Make()
83
0
{
84
0
    int fds[2] = {-1, -1};
85
0
#if HAVE_O_CLOEXEC && HAVE_DECL_PIPE2
86
0
    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
0
    return TokenPipe(fds);
95
0
}
96
97
TokenPipe::~TokenPipe()
98
0
{
99
0
    Close();
100
0
}
101
102
void TokenPipe::Close()
103
0
{
104
0
    if (m_fds[0] != -1) close(m_fds[0]);
105
0
    if (m_fds[1] != -1) close(m_fds[1]);
106
0
    m_fds[0] = m_fds[1] = -1;
107
0
}
108
109
#endif // WIN32