TEST_F(GDBRemoteClientBaseTest, SendContinueDelegateStructuredDataReceipt) { // Build the plain-text version of the JSON data we will have the // server send. const std::string json_payload = "{ \"type\": \"MyFeatureType\", " " \"elements\": [ \"entry1\", \"entry2\" ] }"; const std::string json_packet = "JSON-async:" + json_payload; // Escape it properly for transit. StreamGDBRemote stream; stream.PutEscapedBytes(json_packet.c_str(), json_packet.length()); stream.Flush(); StringExtractorGDBRemote response; // Send async structured data packet, then stop. ASSERT_EQ(PacketResult::Success, server.SendPacket(stream.GetData())); ASSERT_EQ(PacketResult::Success, server.SendPacket("T01")); ASSERT_EQ(eStateStopped, SendCPacket(response)); ASSERT_EQ("T01", response.GetStringRef()); ASSERT_EQ(1ul, delegate.structured_data_packets.size()); // Verify the packet contents. It should have been unescaped upon packet // reception. ASSERT_EQ(json_packet, delegate.structured_data_packets[0]); }
GDBRemoteCommunication::PacketResult GDBRemoteCommunicationServer::Handle_qPlatform_shell (StringExtractorGDBRemote &packet) { packet.SetFilePos(::strlen("qPlatform_shell:")); std::string path; std::string working_dir; packet.GetHexByteStringTerminatedBy(path,','); if (!path.empty()) { if (packet.GetChar() == ',') { // FIXME: add timeout to qPlatform_shell packet // uint32_t timeout = packet.GetHexMaxU32(false, 32); uint32_t timeout = 10; if (packet.GetChar() == ',') packet.GetHexByteString(working_dir); int status, signo; std::string output; Error err = Host::RunShellCommand(path.c_str(), working_dir.empty() ? NULL : working_dir.c_str(), &status, &signo, &output, timeout); StreamGDBRemote response; if (err.Fail()) { response.PutCString("F,"); response.PutHex32(UINT32_MAX); } else { response.PutCString("F,"); response.PutHex32(status); response.PutChar(','); response.PutHex32(signo); response.PutChar(','); response.PutEscapedBytes(output.c_str(), output.size()); } return SendPacketNoLock(response.GetData(), response.GetSize()); } } return SendErrorResponse(24); }
GDBRemoteCommunication::PacketResult GDBRemoteCommunicationServer::Handle_vFile_pRead (StringExtractorGDBRemote &packet) { #ifdef _WIN32 // Not implemented on Windows return SendUnimplementedResponse("GDBRemoteCommunicationServer::Handle_vFile_pRead() unimplemented"); #else StreamGDBRemote response; packet.SetFilePos(::strlen("vFile:pread:")); int fd = packet.GetS32(-1); if (packet.GetChar() == ',') { uint64_t count = packet.GetU64(UINT64_MAX); if (packet.GetChar() == ',') { uint64_t offset = packet.GetU64(UINT32_MAX); if (count == UINT64_MAX) { response.Printf("F-1:%i", EINVAL); return SendPacketNoLock(response.GetData(), response.GetSize()); } std::string buffer(count, 0); const ssize_t bytes_read = ::pread (fd, &buffer[0], buffer.size(), offset); const int save_errno = bytes_read == -1 ? errno : 0; response.PutChar('F'); response.Printf("%zi", bytes_read); if (save_errno) response.Printf(",%i", save_errno); else { response.PutChar(';'); response.PutEscapedBytes(&buffer[0], bytes_read); } return SendPacketNoLock(response.GetData(), response.GetSize()); } } return SendErrorResponse(21); #endif }