101263c6cSJonas Devlieghere //===-- IOStream.cpp --------------------------------------------*- C++ -*-===// 201263c6cSJonas Devlieghere // 301263c6cSJonas Devlieghere // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 401263c6cSJonas Devlieghere // See https://llvm.org/LICENSE.txt for license information. 501263c6cSJonas Devlieghere // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 601263c6cSJonas Devlieghere // 701263c6cSJonas Devlieghere //===----------------------------------------------------------------------===// 801263c6cSJonas Devlieghere 901263c6cSJonas Devlieghere #include "IOStream.h" 1001263c6cSJonas Devlieghere 1101263c6cSJonas Devlieghere #if defined(_WIN32) 1201263c6cSJonas Devlieghere #include <io.h> 1301263c6cSJonas Devlieghere #else 1401263c6cSJonas Devlieghere #include <netinet/in.h> 1501263c6cSJonas Devlieghere #include <sys/socket.h> 1601263c6cSJonas Devlieghere #include <unistd.h> 1701263c6cSJonas Devlieghere #endif 1801263c6cSJonas Devlieghere 1901263c6cSJonas Devlieghere #include <fstream> 2001263c6cSJonas Devlieghere #include <string> 2101263c6cSJonas Devlieghere 2201263c6cSJonas Devlieghere using namespace lldb_dap; 2301263c6cSJonas Devlieghere 2401263c6cSJonas Devlieghere StreamDescriptor::StreamDescriptor() = default; 2501263c6cSJonas Devlieghere 2601263c6cSJonas Devlieghere StreamDescriptor::StreamDescriptor(StreamDescriptor &&other) { 2701263c6cSJonas Devlieghere *this = std::move(other); 2801263c6cSJonas Devlieghere } 2901263c6cSJonas Devlieghere 3001263c6cSJonas Devlieghere StreamDescriptor::~StreamDescriptor() { 3101263c6cSJonas Devlieghere if (!m_close) 3201263c6cSJonas Devlieghere return; 3301263c6cSJonas Devlieghere 3401263c6cSJonas Devlieghere if (m_is_socket) 3501263c6cSJonas Devlieghere #if defined(_WIN32) 3601263c6cSJonas Devlieghere ::closesocket(m_socket); 3701263c6cSJonas Devlieghere #else 3801263c6cSJonas Devlieghere ::close(m_socket); 3901263c6cSJonas Devlieghere #endif 4001263c6cSJonas Devlieghere else 4101263c6cSJonas Devlieghere ::close(m_fd); 4201263c6cSJonas Devlieghere } 4301263c6cSJonas Devlieghere 4401263c6cSJonas Devlieghere StreamDescriptor &StreamDescriptor::operator=(StreamDescriptor &&other) { 4501263c6cSJonas Devlieghere m_close = other.m_close; 4601263c6cSJonas Devlieghere other.m_close = false; 4701263c6cSJonas Devlieghere m_is_socket = other.m_is_socket; 4801263c6cSJonas Devlieghere if (m_is_socket) 4901263c6cSJonas Devlieghere m_socket = other.m_socket; 5001263c6cSJonas Devlieghere else 5101263c6cSJonas Devlieghere m_fd = other.m_fd; 5201263c6cSJonas Devlieghere return *this; 5301263c6cSJonas Devlieghere } 5401263c6cSJonas Devlieghere 5501263c6cSJonas Devlieghere StreamDescriptor StreamDescriptor::from_socket(SOCKET s, bool close) { 5601263c6cSJonas Devlieghere StreamDescriptor sd; 5701263c6cSJonas Devlieghere sd.m_is_socket = true; 5801263c6cSJonas Devlieghere sd.m_socket = s; 5901263c6cSJonas Devlieghere sd.m_close = close; 6001263c6cSJonas Devlieghere return sd; 6101263c6cSJonas Devlieghere } 6201263c6cSJonas Devlieghere 6301263c6cSJonas Devlieghere StreamDescriptor StreamDescriptor::from_file(int fd, bool close) { 6401263c6cSJonas Devlieghere StreamDescriptor sd; 6501263c6cSJonas Devlieghere sd.m_is_socket = false; 6601263c6cSJonas Devlieghere sd.m_fd = fd; 6701263c6cSJonas Devlieghere sd.m_close = close; 6801263c6cSJonas Devlieghere return sd; 6901263c6cSJonas Devlieghere } 7001263c6cSJonas Devlieghere 7101263c6cSJonas Devlieghere bool OutputStream::write_full(llvm::StringRef str) { 7201263c6cSJonas Devlieghere while (!str.empty()) { 7301263c6cSJonas Devlieghere int bytes_written = 0; 7401263c6cSJonas Devlieghere if (descriptor.m_is_socket) 7501263c6cSJonas Devlieghere bytes_written = ::send(descriptor.m_socket, str.data(), str.size(), 0); 7601263c6cSJonas Devlieghere else 7701263c6cSJonas Devlieghere bytes_written = ::write(descriptor.m_fd, str.data(), str.size()); 7801263c6cSJonas Devlieghere 7901263c6cSJonas Devlieghere if (bytes_written < 0) { 8001263c6cSJonas Devlieghere if (errno == EINTR || errno == EAGAIN) 8101263c6cSJonas Devlieghere continue; 8201263c6cSJonas Devlieghere return false; 8301263c6cSJonas Devlieghere } 8401263c6cSJonas Devlieghere str = str.drop_front(bytes_written); 8501263c6cSJonas Devlieghere } 8601263c6cSJonas Devlieghere 8701263c6cSJonas Devlieghere return true; 8801263c6cSJonas Devlieghere } 8901263c6cSJonas Devlieghere 9001263c6cSJonas Devlieghere bool InputStream::read_full(std::ofstream *log, size_t length, 9101263c6cSJonas Devlieghere std::string &text) { 9201263c6cSJonas Devlieghere std::string data; 9301263c6cSJonas Devlieghere data.resize(length); 9401263c6cSJonas Devlieghere 9501263c6cSJonas Devlieghere char *ptr = &data[0]; 9601263c6cSJonas Devlieghere while (length != 0) { 9701263c6cSJonas Devlieghere int bytes_read = 0; 9801263c6cSJonas Devlieghere if (descriptor.m_is_socket) 9901263c6cSJonas Devlieghere bytes_read = ::recv(descriptor.m_socket, ptr, length, 0); 10001263c6cSJonas Devlieghere else 10101263c6cSJonas Devlieghere bytes_read = ::read(descriptor.m_fd, ptr, length); 10201263c6cSJonas Devlieghere 10301263c6cSJonas Devlieghere if (bytes_read == 0) { 10401263c6cSJonas Devlieghere if (log) 10501263c6cSJonas Devlieghere *log << "End of file (EOF) reading from input file.\n"; 10601263c6cSJonas Devlieghere return false; 10701263c6cSJonas Devlieghere } 10801263c6cSJonas Devlieghere if (bytes_read < 0) { 10901263c6cSJonas Devlieghere int reason = 0; 11001263c6cSJonas Devlieghere #if defined(_WIN32) 11101263c6cSJonas Devlieghere if (descriptor.m_is_socket) 11201263c6cSJonas Devlieghere reason = WSAGetLastError(); 11301263c6cSJonas Devlieghere else 11401263c6cSJonas Devlieghere reason = errno; 11501263c6cSJonas Devlieghere #else 11601263c6cSJonas Devlieghere reason = errno; 11701263c6cSJonas Devlieghere if (reason == EINTR || reason == EAGAIN) 11801263c6cSJonas Devlieghere continue; 11901263c6cSJonas Devlieghere #endif 12001263c6cSJonas Devlieghere 12101263c6cSJonas Devlieghere if (log) 12201263c6cSJonas Devlieghere *log << "Error " << reason << " reading from input file.\n"; 12301263c6cSJonas Devlieghere return false; 12401263c6cSJonas Devlieghere } 12501263c6cSJonas Devlieghere 12601263c6cSJonas Devlieghere assert(bytes_read >= 0 && (size_t)bytes_read <= length); 12701263c6cSJonas Devlieghere ptr += bytes_read; 12801263c6cSJonas Devlieghere length -= bytes_read; 12901263c6cSJonas Devlieghere } 13001263c6cSJonas Devlieghere text += data; 13101263c6cSJonas Devlieghere return true; 13201263c6cSJonas Devlieghere } 13301263c6cSJonas Devlieghere 13401263c6cSJonas Devlieghere bool InputStream::read_line(std::ofstream *log, std::string &line) { 13501263c6cSJonas Devlieghere line.clear(); 13601263c6cSJonas Devlieghere while (true) { 13701263c6cSJonas Devlieghere if (!read_full(log, 1, line)) 13801263c6cSJonas Devlieghere return false; 13901263c6cSJonas Devlieghere 140*744f3891SKazu Hirata if (llvm::StringRef(line).ends_with("\r\n")) 14101263c6cSJonas Devlieghere break; 14201263c6cSJonas Devlieghere } 14301263c6cSJonas Devlieghere line.erase(line.size() - 2); 14401263c6cSJonas Devlieghere return true; 14501263c6cSJonas Devlieghere } 14601263c6cSJonas Devlieghere 14701263c6cSJonas Devlieghere bool InputStream::read_expected(std::ofstream *log, llvm::StringRef expected) { 14801263c6cSJonas Devlieghere std::string result; 14901263c6cSJonas Devlieghere if (!read_full(log, expected.size(), result)) 15001263c6cSJonas Devlieghere return false; 15101263c6cSJonas Devlieghere if (expected != result) { 15201263c6cSJonas Devlieghere if (log) 15301263c6cSJonas Devlieghere *log << "Warning: Expected '" << expected.str() << "', got '" << result 15401263c6cSJonas Devlieghere << "\n"; 15501263c6cSJonas Devlieghere } 15601263c6cSJonas Devlieghere return true; 15701263c6cSJonas Devlieghere } 158