================ @@ -137,42 +141,232 @@ lldb::SBValueList *GetTopLevelScope(DAP &dap, int64_t variablesReference) { } } -SOCKET AcceptConnection(DAP &dap, int portno) { - // Accept a socket connection from any host on "portno". - SOCKET newsockfd = -1; - struct sockaddr_in serv_addr, cli_addr; +/// Redirect stdout and stderr fo the IDE's console output. +/// +/// Errors in this operation will be printed to the log file and the IDE's +/// console output as well. +/// +/// \return +/// A fd pointing to the original stdout. +void SetupRedirection(DAP &dap, int stdoutfd = -1, int stderrfd = -1) { + auto output_callback_stderr = [&dap](llvm::StringRef data) { + dap.SendOutput(OutputType::Stderr, data); + }; + auto output_callback_stdout = [&dap](llvm::StringRef data) { + dap.SendOutput(OutputType::Stdout, data); + }; + + llvm::Expected<int> new_stdout_fd = + RedirectFd(stdoutfd, output_callback_stdout); + if (auto err = new_stdout_fd.takeError()) { + std::string error_message = llvm::toString(std::move(err)); + if (dap.log) + *dap.log << error_message << std::endl; + output_callback_stderr(error_message); + } + dap.out = lldb::SBFile(new_stdout_fd.get(), "w", false); + + llvm::Expected<int> new_stderr_fd = + RedirectFd(stderrfd, output_callback_stderr); + if (auto err = new_stderr_fd.takeError()) { + std::string error_message = llvm::toString(std::move(err)); + if (dap.log) + *dap.log << error_message << std::endl; + output_callback_stderr(error_message); + } + dap.err = lldb::SBFile(new_stderr_fd.get(), "w", false); +} + +void HandleClient(int clientfd, llvm::StringRef program_path, + const std::vector<std::string> &pre_init_commands, + std::shared_ptr<std::ofstream> log, + ReplMode default_repl_mode) { + if (log) + *log << "client[" << clientfd << "] connected\n"; + DAP dap = DAP(program_path, log, default_repl_mode, pre_init_commands); + dap.debug_adaptor_path = program_path; + + SetupRedirection(dap); + RegisterRequestCallbacks(dap); + + dap.input.descriptor = StreamDescriptor::from_socket(clientfd, false); + dap.output.descriptor = StreamDescriptor::from_socket(clientfd, false); + + for (const std::string &arg : pre_init_commands) { + dap.pre_init_commands.push_back(arg); + } + + if (auto Err = dap.Loop()) { + if (log) + *log << "Transport Error: " << llvm::toString(std::move(Err)) << "\n"; + } + + if (log) + *log << "client[" << clientfd << "] connection closed\n"; +#if defined(_WIN32) + closesocket(clientfd); +#else + close(clientfd); +#endif +} + +std::error_code getLastSocketErrorCode() { +#ifdef _WIN32 + return std::error_code(::WSAGetLastError(), std::system_category()); +#else + return llvm::errnoAsErrorCode(); +#endif +} + +llvm::Expected<int> getSocketFD(llvm::StringRef path) { + if (llvm::sys::fs::exists(path) && (::remove(path.str().c_str()) == -1)) { + return llvm::make_error<llvm::StringError>(getLastSocketErrorCode(), + "Remove existing socket failed"); + } + + SOCKET sockfd = socket(AF_UNIX, SOCK_STREAM, 0); + if (sockfd == -1) { + return llvm::make_error<llvm::StringError>(getLastSocketErrorCode(), + "Create socket failed"); + } + + struct sockaddr_un addr; + bzero(&addr, sizeof(addr)); + addr.sun_family = AF_UNIX; + strncpy(addr.sun_path, path.str().c_str(), sizeof(addr.sun_path) - 1); + + if (::bind(sockfd, (struct sockaddr *)&addr, sizeof(addr)) == -1) { +#if defined(_WIN32) + closesocket(sockfd); +#else + close(sockfd); +#endif + return llvm::make_error<llvm::StringError>(getLastSocketErrorCode(), + "Socket bind() failed"); + } + + if (listen(sockfd, llvm::hardware_concurrency().compute_thread_count()) < 0) { +#if defined(_WIN32) + closesocket(sockfd); +#else + close(sockfd); +#endif + return llvm::make_error<llvm::StringError>(getLastSocketErrorCode(), + "Socket listen() failed"); + } + + return sockfd; +} + +llvm::Expected<int> getSocketFD(int portno) { SOCKET sockfd = socket(AF_INET, SOCK_STREAM, 0); if (sockfd < 0) { - if (dap.log) - *dap.log << "error: opening socket (" << strerror(errno) << ")" - << std::endl; - } else { - memset((char *)&serv_addr, 0, sizeof(serv_addr)); - serv_addr.sin_family = AF_INET; - // serv_addr.sin_addr.s_addr = htonl(INADDR_ANY); - serv_addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK); - serv_addr.sin_port = htons(portno); - if (bind(sockfd, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0) { - if (dap.log) - *dap.log << "error: binding socket (" << strerror(errno) << ")" - << std::endl; - } else { - listen(sockfd, 5); - socklen_t clilen = sizeof(cli_addr); - newsockfd = - llvm::sys::RetryAfterSignal(static_cast<SOCKET>(-1), accept, sockfd, - (struct sockaddr *)&cli_addr, &clilen); - if (newsockfd < 0) - if (dap.log) - *dap.log << "error: accept (" << strerror(errno) << ")" << std::endl; - } + return llvm::make_error<llvm::StringError>(getLastSocketErrorCode(), + "Create socket failed"); + } + + struct sockaddr_in serv_addr; + bzero(&serv_addr, sizeof(serv_addr)); + serv_addr.sin_family = AF_INET; + // serv_addr.sin_addr.s_addr = htonl(INADDR_ANY); ---------------- vogelsgesang wrote:
remove commented out code? https://github.com/llvm/llvm-project/pull/116392 _______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits