Coverage Report

Created: 2026-02-09 06:05

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/CMake/Source/cmDebuggerPosixPipeConnection.cxx
Line
Count
Source
1
/* Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
2
   file LICENSE.rst or https://cmake.org/licensing for details.  */
3
#include "cmDebuggerPosixPipeConnection.h"
4
5
#include <cerrno>
6
#include <cstring>
7
#include <stdexcept>
8
#include <utility>
9
10
#include <unistd.h>
11
12
#include <sys/socket.h>
13
14
namespace cmDebugger {
15
16
#ifndef _WIN32
17
18
cmDebuggerPipeConnection_POSIX::cmDebuggerPipeConnection_POSIX(
19
  std::string name)
20
0
  : PipeName(std::move(name))
21
0
{
22
0
  addr.sun_path[0] = '\0';
23
0
}
Unexecuted instantiation: cmDebugger::cmDebuggerPipeConnection_POSIX::cmDebuggerPipeConnection_POSIX(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >)
Unexecuted instantiation: cmDebugger::cmDebuggerPipeConnection_POSIX::cmDebuggerPipeConnection_POSIX(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >)
24
25
cmDebuggerPipeConnection_POSIX::~cmDebuggerPipeConnection_POSIX()
26
0
{
27
0
  if (isOpen()) {
28
0
    close();
29
0
  }
30
0
}
31
32
bool cmDebuggerPipeConnection_POSIX::StartListening(std::string& errorMessage)
33
0
{
34
0
  listen_fd = socket(AF_UNIX, SOCK_STREAM, 0);
35
0
  if (listen_fd < 0) {
36
0
    errorMessage = "Failed to create socket: ";
37
0
    errorMessage += strerror(errno);
38
0
    return false;
39
0
  }
40
41
0
  addr.sun_family = AF_UNIX;
42
0
  strncpy(addr.sun_path, PipeName.c_str(), sizeof(addr.sun_path));
43
0
  addr.sun_path[sizeof(addr.sun_path) - 1] = '\0';
44
0
  if (bind(listen_fd, (sockaddr*)&addr, sizeof(addr)) == -1) {
45
0
    errorMessage = "Failed to bind name '";
46
0
    errorMessage += addr.sun_path;
47
0
    errorMessage += "' to socket: ";
48
0
    errorMessage += strerror(errno);
49
0
    close_listen();
50
0
    return false;
51
0
  }
52
53
0
  if (listen(listen_fd, 1) == -1) {
54
0
    errorMessage = "Failed to listen on socket: ";
55
0
    errorMessage += strerror(errno);
56
0
    close_listen();
57
0
    return false;
58
0
  }
59
60
0
  StartedListening.set_value();
61
0
  return true;
62
0
}
63
64
std::shared_ptr<dap::Reader> cmDebuggerPipeConnection_POSIX::GetReader()
65
0
{
66
0
  return std::static_pointer_cast<dap::Reader>(shared_from_this());
67
0
}
68
69
std::shared_ptr<dap::Writer> cmDebuggerPipeConnection_POSIX::GetWriter()
70
0
{
71
0
  return std::static_pointer_cast<dap::Writer>(shared_from_this());
72
0
}
73
74
bool cmDebuggerPipeConnection_POSIX::isOpen()
75
0
{
76
0
  return rw_pipe >= 0;
77
0
}
78
79
void cmDebuggerPipeConnection_POSIX::close()
80
0
{
81
0
  close_listen();
82
0
  ::close(rw_pipe);
83
0
  rw_pipe = -1;
84
0
}
85
86
void cmDebuggerPipeConnection_POSIX::close_listen()
87
0
{
88
0
  if (strlen(addr.sun_path) > 0) {
89
0
    unlink(addr.sun_path);
90
0
    addr.sun_path[0] = '\0';
91
0
  }
92
0
  ::close(listen_fd);
93
0
  listen_fd = -1;
94
0
}
95
96
void cmDebuggerPipeConnection_POSIX::WaitForConnection()
97
0
{
98
0
  sockaddr_un laddr;
99
0
  socklen_t len = sizeof(laddr);
100
0
  rw_pipe = accept(listen_fd, (sockaddr*)&laddr, &len);
101
0
  if (rw_pipe < 0) {
102
0
    close();
103
0
    return;
104
0
  }
105
106
0
  close_listen(); // no longer need the listen resources
107
0
}
108
109
size_t cmDebuggerPipeConnection_POSIX::read(void* buffer, size_t n)
110
0
{
111
0
  size_t result = 0;
112
0
  if (rw_pipe >= 0) {
113
0
    result = ::read(rw_pipe, buffer, n);
114
0
    if (result == 0) {
115
0
      close();
116
0
    }
117
0
  }
118
119
0
  return result;
120
0
}
121
122
bool cmDebuggerPipeConnection_POSIX::write(void const* buffer, size_t n)
123
0
{
124
0
  bool result = false;
125
0
  if (rw_pipe >= 0) {
126
0
    result = ::write(rw_pipe, buffer, n) >= 0;
127
0
    if (!result) {
128
0
      close();
129
0
    }
130
0
  }
131
132
0
  return result;
133
0
}
134
135
cmDebuggerPipeClient_POSIX::cmDebuggerPipeClient_POSIX(std::string name)
136
0
  : PipeName(std::move(name))
137
0
{
138
0
}
Unexecuted instantiation: cmDebugger::cmDebuggerPipeClient_POSIX::cmDebuggerPipeClient_POSIX(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >)
Unexecuted instantiation: cmDebugger::cmDebuggerPipeClient_POSIX::cmDebuggerPipeClient_POSIX(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >)
139
140
cmDebuggerPipeClient_POSIX::~cmDebuggerPipeClient_POSIX()
141
0
{
142
0
  close();
143
0
}
144
145
void cmDebuggerPipeClient_POSIX::WaitForConnection()
146
0
{
147
0
  rw_pipe = socket(AF_UNIX, SOCK_STREAM, 0);
148
0
  if (rw_pipe < 0) {
149
0
    throw std::runtime_error(std::string("Failed to create socket: ") +
150
0
                             strerror(errno));
151
0
  }
152
153
0
  sockaddr_un addr;
154
0
  addr.sun_family = AF_UNIX;
155
0
  strncpy(addr.sun_path, PipeName.c_str(), sizeof(addr.sun_path));
156
0
  addr.sun_path[sizeof(addr.sun_path) - 1] = '\0';
157
0
  if (connect(rw_pipe, (sockaddr*)&addr, sizeof(addr)) == -1) {
158
0
    close();
159
0
    throw std::runtime_error(
160
0
      std::string("Failed to connect path to socket: ") + strerror(errno));
161
0
  }
162
0
}
163
164
bool cmDebuggerPipeClient_POSIX::isOpen()
165
0
{
166
0
  return rw_pipe >= 0;
167
0
}
168
169
void cmDebuggerPipeClient_POSIX::close()
170
0
{
171
0
  if (isOpen()) {
172
0
    ::close(rw_pipe);
173
0
    rw_pipe = -1;
174
0
  }
175
0
}
176
177
size_t cmDebuggerPipeClient_POSIX::read(void* buffer, size_t n)
178
0
{
179
0
  int count = 0;
180
0
  if (isOpen()) {
181
0
    count = static_cast<int>(::read(rw_pipe, buffer, n));
182
0
    if (count == 0) {
183
0
      close();
184
0
    }
185
0
  }
186
187
0
  return count;
188
0
}
189
190
bool cmDebuggerPipeClient_POSIX::write(void const* buffer, size_t n)
191
0
{
192
0
  int count = 0;
193
0
  if (isOpen()) {
194
0
    count = static_cast<int>(::write(rw_pipe, buffer, n));
195
0
    if (count < 0) {
196
0
      close();
197
0
    }
198
0
  }
199
200
0
  return count > 0;
201
0
}
202
203
#endif // !_WIN32
204
205
} // namespace cmDebugger