• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

mendersoftware / mender / 1001210836

12 Sep 2023 01:20PM UTC coverage: 79.201% (+0.09%) from 79.112%
1001210836

push

gitlab-ci

vpodzime
feat: Add support for signals delivering two strings

Ticket: MEN-6651
Changelog: none
Signed-off-by: Vratislav Podzimek <v.podzimek@mykolab.com>

5731 of 7236 relevant lines covered (79.2%)

256.26 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

75.56
/common/events/platform/boost/events_io.cpp
1
// Copyright 2023 Northern.tech AS
2
//
3
//    Licensed under the Apache License, Version 2.0 (the "License");
4
//    you may not use this file except in compliance with the License.
5
//    You may obtain a copy of the License at
6
//
7
//        http://www.apache.org/licenses/LICENSE-2.0
8
//
9
//    Unless required by applicable law or agreed to in writing, software
10
//    distributed under the License is distributed on an "AS IS" BASIS,
11
//    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
//    See the License for the specific language governing permissions and
13
//    limitations under the License.
14

15
#include <common/events_io.hpp>
16

17
#include <vector>
18

19
namespace mender {
20
namespace common {
21
namespace events {
22
namespace io {
23

24
AsyncFileDescriptorReader::AsyncFileDescriptorReader(events::EventLoop &loop, int fd) :
×
25
        pipe_(GetAsioIoContext(loop), fd),
26
        cancelled_ {make_shared<bool>(false)} {
×
27
}
×
28

29
AsyncFileDescriptorReader::AsyncFileDescriptorReader(events::EventLoop &loop) :
×
30
        pipe_(GetAsioIoContext(loop)),
31
        cancelled_ {make_shared<bool>(false)} {
×
32
}
×
33

34
AsyncFileDescriptorReader::~AsyncFileDescriptorReader() {
×
35
        Cancel();
×
36
}
×
37

38
error::Error AsyncFileDescriptorReader::Open(const string &path) {
2✔
39
        int fd = open(path.c_str(), O_RDONLY);
2✔
40
        if (fd < 0) {
2✔
41
                int err = errno;
1✔
42
                return error::Error(generic_category().default_error_condition(err), "Cannot open " + path);
2✔
43
        }
44
        pipe_.close();
1✔
45
        pipe_.assign(fd);
1✔
46
        return error::NoError;
1✔
47
}
48

49
error::Error AsyncFileDescriptorReader::AsyncRead(
21✔
50
        vector<uint8_t>::iterator start,
51
        vector<uint8_t>::iterator end,
52
        mender::common::io::AsyncIoHandler handler) {
53
        if (end < start) {
21✔
54
                return error::Error(
55
                        make_error_condition(errc::invalid_argument), "AsyncRead: end cannot precede start");
2✔
56
        }
57
        if (!handler) {
20✔
58
                return error::Error(
59
                        make_error_condition(errc::invalid_argument), "AsyncRead: handler cannot be nullptr");
2✔
60
        }
61

62
        *cancelled_ = false;
19✔
63
        auto cancelled {cancelled_};
38✔
64

65
        asio::mutable_buffer buf {&start[0], size_t(end - start)};
19✔
66
        pipe_.async_read_some(buf, [cancelled, handler](error_code ec, size_t n) {
19✔
67
                if (*cancelled || ec == make_error_code(asio::error::operation_aborted)) {
19✔
68
                        return;
2✔
69
                } else if (ec == make_error_code(asio::error::eof)) {
17✔
70
                        // n should always be zero. Handling this properly is possible, but tricky,
71
                        // so just relying on assert for now.
72
                        assert(n == 0);
3✔
73
                        handler(0);
3✔
74
                } else if (ec) {
14✔
75
                        handler(expected::unexpected(
×
76
                                error::Error(ec.default_error_condition(), "AsyncRead failed")));
×
77
                } else {
78
                        handler(n);
14✔
79
                }
80
        });
81

82
        return error::NoError;
19✔
83
}
84

85
void AsyncFileDescriptorReader::Cancel() {
16✔
86
        if (pipe_.is_open()) {
16✔
87
                pipe_.cancel();
15✔
88
        }
89
        *cancelled_ = true;
16✔
90
}
16✔
91

92
AsyncFileDescriptorWriter::AsyncFileDescriptorWriter(events::EventLoop &loop, int fd) :
×
93
        pipe_(GetAsioIoContext(loop), fd),
94
        cancelled_ {make_shared<bool>(false)} {
×
95
}
×
96

97
AsyncFileDescriptorWriter::AsyncFileDescriptorWriter(events::EventLoop &loop) :
×
98
        pipe_(GetAsioIoContext(loop)),
99
        cancelled_ {make_shared<bool>(false)} {
×
100
}
×
101

102
AsyncFileDescriptorWriter::~AsyncFileDescriptorWriter() {
×
103
        Cancel();
×
104
}
×
105

106
error::Error AsyncFileDescriptorWriter::Open(const string &path, Append append) {
131✔
107
        int flags = O_WRONLY | O_CREAT;
131✔
108
        switch (append) {
131✔
109
        case Append::Disabled:
130✔
110
                flags |= O_TRUNC;
130✔
111
                break;
130✔
112
        case Append::Enabled:
1✔
113
                flags |= O_APPEND;
1✔
114
                break;
1✔
115
        }
116
        int fd = open(path.c_str(), flags, 0644);
131✔
117
        if (fd < 0) {
131✔
118
                int err = errno;
2✔
119
                return error::Error(generic_category().default_error_condition(err), "Cannot open " + path);
4✔
120
        }
121
        pipe_.close();
129✔
122
        pipe_.assign(fd);
129✔
123
        return error::NoError;
129✔
124
}
125

126
error::Error AsyncFileDescriptorWriter::AsyncWrite(
510✔
127
        vector<uint8_t>::const_iterator start,
128
        vector<uint8_t>::const_iterator end,
129
        mender::common::io::AsyncIoHandler handler) {
130
        if (end < start) {
510✔
131
                return error::Error(
132
                        make_error_condition(errc::invalid_argument), "AsyncWrite: end cannot precede start");
2✔
133
        }
134
        if (!handler) {
509✔
135
                return error::Error(
136
                        make_error_condition(errc::invalid_argument), "AsyncWrite: handler cannot be nullptr");
2✔
137
        }
138

139
        *cancelled_ = false;
508✔
140
        auto cancelled {cancelled_};
1,016✔
141

142
        asio::const_buffer buf {&start[0], size_t(end - start)};
508✔
143
        pipe_.async_write_some(buf, [cancelled, handler](error_code ec, size_t n) {
508✔
144
                if (*cancelled || ec == make_error_code(asio::error::operation_aborted)) {
508✔
145
                        return;
2✔
146
                } else if (ec == make_error_code(asio::error::broken_pipe)) {
506✔
147
                        // Let's translate broken_pipe. It's a common error, and we don't want to
148
                        // require the caller to match with Boost ASIO errors.
149
                        handler(expected::unexpected(
3✔
150
                                error::Error(make_error_condition(errc::broken_pipe), "AsyncWrite failed")));
6✔
151
                } else if (ec) {
503✔
152
                        handler(expected::unexpected(
×
153
                                error::Error(ec.default_error_condition(), "AsyncWrite failed")));
×
154
                } else {
155
                        handler(n);
503✔
156
                }
157
        });
158

159
        return error::NoError;
508✔
160
}
161

162
void AsyncFileDescriptorWriter::Cancel() {
141✔
163
        if (pipe_.is_open()) {
141✔
164
                pipe_.cancel();
139✔
165
        }
166
        *cancelled_ = true;
141✔
167
}
141✔
168

169
} // namespace io
170
} // namespace events
171
} // namespace common
172
} // namespace mender
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc