| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205 |
- /* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
- file Copyright.txt or https://cmake.org/licensing for details. */
- #include "cmDebuggerPosixPipeConnection.h"
- #include <cerrno>
- #include <cstring>
- #include <stdexcept>
- #include <utility>
- #include <unistd.h>
- #include <sys/socket.h>
- namespace cmDebugger {
- #ifndef _WIN32
- cmDebuggerPipeConnection_POSIX::cmDebuggerPipeConnection_POSIX(
- std::string name)
- : PipeName(std::move(name))
- {
- addr.sun_path[0] = '\0';
- }
- cmDebuggerPipeConnection_POSIX::~cmDebuggerPipeConnection_POSIX()
- {
- if (isOpen()) {
- close();
- }
- }
- bool cmDebuggerPipeConnection_POSIX::StartListening(std::string& errorMessage)
- {
- listen_fd = socket(AF_UNIX, SOCK_STREAM, 0);
- if (listen_fd < 0) {
- errorMessage = "Failed to create socket: ";
- errorMessage += strerror(errno);
- return false;
- }
- addr.sun_family = AF_UNIX;
- strncpy(addr.sun_path, PipeName.c_str(), sizeof(addr.sun_path));
- addr.sun_path[sizeof(addr.sun_path) - 1] = '\0';
- if (bind(listen_fd, (sockaddr*)&addr, sizeof(addr)) == -1) {
- errorMessage = "Failed to bind name '";
- errorMessage += addr.sun_path;
- errorMessage += "' to socket: ";
- errorMessage += strerror(errno);
- close_listen();
- return false;
- }
- if (listen(listen_fd, 1) == -1) {
- errorMessage = "Failed to listen on socket: ";
- errorMessage += strerror(errno);
- close_listen();
- return false;
- }
- StartedListening.set_value();
- return true;
- }
- std::shared_ptr<dap::Reader> cmDebuggerPipeConnection_POSIX::GetReader()
- {
- return std::static_pointer_cast<dap::Reader>(shared_from_this());
- }
- std::shared_ptr<dap::Writer> cmDebuggerPipeConnection_POSIX::GetWriter()
- {
- return std::static_pointer_cast<dap::Writer>(shared_from_this());
- }
- bool cmDebuggerPipeConnection_POSIX::isOpen()
- {
- return rw_pipe >= 0;
- }
- void cmDebuggerPipeConnection_POSIX::close()
- {
- close_listen();
- ::close(rw_pipe);
- rw_pipe = -1;
- }
- void cmDebuggerPipeConnection_POSIX::close_listen()
- {
- if (strlen(addr.sun_path) > 0) {
- unlink(addr.sun_path);
- addr.sun_path[0] = '\0';
- }
- ::close(listen_fd);
- listen_fd = -1;
- }
- void cmDebuggerPipeConnection_POSIX::WaitForConnection()
- {
- sockaddr_un laddr;
- socklen_t len = sizeof(laddr);
- rw_pipe = accept(listen_fd, (sockaddr*)&laddr, &len);
- if (rw_pipe < 0) {
- close();
- return;
- }
- close_listen(); // no longer need the listen resources
- }
- size_t cmDebuggerPipeConnection_POSIX::read(void* buffer, size_t n)
- {
- size_t result = 0;
- if (rw_pipe >= 0) {
- result = ::read(rw_pipe, buffer, n);
- if (result == 0) {
- close();
- }
- }
- return result;
- }
- bool cmDebuggerPipeConnection_POSIX::write(void const* buffer, size_t n)
- {
- bool result = false;
- if (rw_pipe >= 0) {
- result = ::write(rw_pipe, buffer, n) >= 0;
- if (!result) {
- close();
- }
- }
- return result;
- }
- cmDebuggerPipeClient_POSIX::cmDebuggerPipeClient_POSIX(std::string name)
- : PipeName(std::move(name))
- {
- }
- cmDebuggerPipeClient_POSIX::~cmDebuggerPipeClient_POSIX()
- {
- close();
- }
- void cmDebuggerPipeClient_POSIX::WaitForConnection()
- {
- rw_pipe = socket(AF_UNIX, SOCK_STREAM, 0);
- if (rw_pipe < 0) {
- throw std::runtime_error(std::string("Failed to create socket: ") +
- strerror(errno));
- }
- sockaddr_un addr;
- addr.sun_family = AF_UNIX;
- strncpy(addr.sun_path, PipeName.c_str(), sizeof(addr.sun_path));
- addr.sun_path[sizeof(addr.sun_path) - 1] = '\0';
- if (connect(rw_pipe, (sockaddr*)&addr, sizeof(addr)) == -1) {
- close();
- throw std::runtime_error(
- std::string("Failed to connect path to socket: ") + strerror(errno));
- }
- }
- bool cmDebuggerPipeClient_POSIX::isOpen()
- {
- return rw_pipe >= 0;
- }
- void cmDebuggerPipeClient_POSIX::close()
- {
- if (isOpen()) {
- ::close(rw_pipe);
- rw_pipe = -1;
- }
- }
- size_t cmDebuggerPipeClient_POSIX::read(void* buffer, size_t n)
- {
- int count = 0;
- if (isOpen()) {
- count = static_cast<int>(::read(rw_pipe, buffer, n));
- if (count == 0) {
- close();
- }
- }
- return count;
- }
- bool cmDebuggerPipeClient_POSIX::write(void const* buffer, size_t n)
- {
- int count = 0;
- if (isOpen()) {
- count = static_cast<int>(::write(rw_pipe, buffer, n));
- if (count < 0) {
- close();
- }
- }
- return count > 0;
- }
- #endif // !_WIN32
- } // namespace cmDebugger
|