brintos

brintos / llvm-project-archived public Read only

0
0
Text · 6.7 KiB · 1a95089 Raw
188 lines · cpp
1//===-- CommandObjectProtocolServer.cpp -----------------------------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8 9#include "CommandObjectProtocolServer.h"10#include "lldb/Core/PluginManager.h"11#include "lldb/Core/ProtocolServer.h"12#include "lldb/Host/Socket.h"13#include "lldb/Interpreter/CommandInterpreter.h"14#include "lldb/Interpreter/CommandReturnObject.h"15#include "lldb/Utility/UriParser.h"16#include "llvm/ADT/STLExtras.h"17#include "llvm/Support/FormatAdapters.h"18#include <string>19 20using namespace llvm;21using namespace lldb;22using namespace lldb_private;23 24#define LLDB_OPTIONS_mcp25#include "CommandOptions.inc"26 27class CommandObjectProtocolServerStart : public CommandObjectParsed {28public:29  CommandObjectProtocolServerStart(CommandInterpreter &interpreter)30      : CommandObjectParsed(interpreter, "protocol-server start",31                            "start protocol server",32                            "protocol-server start <protocol> [<connection>]") {33    AddSimpleArgumentList(lldb::eArgTypeProtocol, eArgRepeatPlain);34    AddSimpleArgumentList(lldb::eArgTypeConnectURL, eArgRepeatPlain);35  }36 37  ~CommandObjectProtocolServerStart() override = default;38 39protected:40  void DoExecute(Args &args, CommandReturnObject &result) override {41    if (args.GetArgumentCount() < 1) {42      result.AppendError("no protocol specified");43      return;44    }45 46    llvm::StringRef protocol = args.GetArgumentAtIndex(0);47    ProtocolServer *server = ProtocolServer::GetOrCreate(protocol);48    if (!server) {49      result.AppendErrorWithFormatv(50          "unsupported protocol: {0}. Supported protocols are: {1}", protocol,51          llvm::join(ProtocolServer::GetSupportedProtocols(), ", "));52      return;53    }54 55    std::string connection_uri = "listen://[localhost]:0";56    if (args.GetArgumentCount() >= 2)57      connection_uri = args.GetArgumentAtIndex(1);58 59    const char *connection_error =60        "unsupported connection specifier, expected 'accept:///path' "61        "or 'listen://[host]:port', got '{0}'.";62    auto uri = lldb_private::URI::Parse(connection_uri);63    if (!uri) {64      result.AppendErrorWithFormatv(connection_error, connection_uri);65      return;66    }67 68    std::optional<Socket::ProtocolModePair> protocol_and_mode =69        Socket::GetProtocolAndMode(uri->scheme);70    if (!protocol_and_mode || protocol_and_mode->second != Socket::ModeAccept) {71      result.AppendErrorWithFormatv(connection_error, connection_uri);72      return;73    }74 75    ProtocolServer::Connection connection;76    connection.protocol = protocol_and_mode->first;77    if (connection.protocol == Socket::SocketProtocol::ProtocolUnixDomain)78      connection.name = uri->path;79    else80      connection.name = formatv(81          "[{0}]:{1}", uri->hostname.empty() ? "0.0.0.0" : uri->hostname,82          uri->port.value_or(0));83 84    if (llvm::Error error = server->Start(connection)) {85      result.AppendErrorWithFormatv("{0}", llvm::fmt_consume(std::move(error)));86      return;87    }88 89    if (Socket *socket = server->GetSocket()) {90      std::string address =91          llvm::join(socket->GetListeningConnectionURI(), ", ");92      result.AppendMessageWithFormatv(93          "{0} server started with connection listeners: {1}", protocol,94          address);95      result.SetStatus(eReturnStatusSuccessFinishNoResult);96    }97  }98};99 100class CommandObjectProtocolServerStop : public CommandObjectParsed {101public:102  CommandObjectProtocolServerStop(CommandInterpreter &interpreter)103      : CommandObjectParsed(interpreter, "protocol-server stop",104                            "stop protocol server",105                            "protocol-server stop <protocol>") {106    AddSimpleArgumentList(lldb::eArgTypeProtocol, eArgRepeatPlain);107  }108 109  ~CommandObjectProtocolServerStop() override = default;110 111protected:112  void DoExecute(Args &args, CommandReturnObject &result) override {113    if (args.GetArgumentCount() < 1) {114      result.AppendError("no protocol specified");115      return;116    }117 118    llvm::StringRef protocol = args.GetArgumentAtIndex(0);119    ProtocolServer *server = ProtocolServer::GetOrCreate(protocol);120    if (!server) {121      result.AppendErrorWithFormatv(122          "unsupported protocol: {0}. Supported protocols are: {1}", protocol,123          llvm::join(ProtocolServer::GetSupportedProtocols(), ", "));124      return;125    }126 127    if (llvm::Error error = server->Stop()) {128      result.AppendErrorWithFormatv("{0}", llvm::fmt_consume(std::move(error)));129      return;130    }131  }132};133 134class CommandObjectProtocolServerGet : public CommandObjectParsed {135public:136  CommandObjectProtocolServerGet(CommandInterpreter &interpreter)137      : CommandObjectParsed(interpreter, "protocol-server get",138                            "get protocol server connection information",139                            "protocol-server get <protocol>") {140    AddSimpleArgumentList(lldb::eArgTypeProtocol, eArgRepeatPlain);141  }142 143  ~CommandObjectProtocolServerGet() override = default;144 145protected:146  void DoExecute(Args &args, CommandReturnObject &result) override {147    if (args.GetArgumentCount() < 1) {148      result.AppendError("no protocol specified");149      return;150    }151 152    llvm::StringRef protocol = args.GetArgumentAtIndex(0);153    ProtocolServer *server = ProtocolServer::GetOrCreate(protocol);154    if (!server) {155      result.AppendErrorWithFormatv(156          "unsupported protocol: {0}. Supported protocols are: {1}", protocol,157          llvm::join(ProtocolServer::GetSupportedProtocols(), ", "));158      return;159    }160 161    Socket *socket = server->GetSocket();162    if (!socket) {163      result.AppendErrorWithFormatv("{0} server is not running", protocol);164      return;165    }166 167    std::string address = llvm::join(socket->GetListeningConnectionURI(), ", ");168    result.AppendMessageWithFormatv("{0} server connection listeners: {1}",169                                    protocol, address);170    result.SetStatus(eReturnStatusSuccessFinishNoResult);171  }172};173 174CommandObjectProtocolServer::CommandObjectProtocolServer(175    CommandInterpreter &interpreter)176    : CommandObjectMultiword(interpreter, "protocol-server",177                             "Start, stop, and query protocol servers.",178                             "protocol-server") {179  LoadSubCommand("start", CommandObjectSP(new CommandObjectProtocolServerStart(180                              interpreter)));181  LoadSubCommand("stop", CommandObjectSP(182                             new CommandObjectProtocolServerStop(interpreter)));183  LoadSubCommand(184      "get", CommandObjectSP(new CommandObjectProtocolServerGet(interpreter)));185}186 187CommandObjectProtocolServer::~CommandObjectProtocolServer() = default;188