/* * Copyright (C) 2018 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "adb.h" #include "adb_io.h" #include "shell_service.h" #include "cmd.h" #include namespace { class AdbFdTextOutput : public android::TextOutput { public: explicit AdbFdTextOutput(int fd) : mFD(fd) {} private: android::status_t print(const char* txt, size_t len) override { return WriteFdExactly(mFD, txt, len) ? android::OK : -errno; } void moveIndent(int delta) override { /*not implemented*/ } void pushBundle() override { /*not implemented*/ } void popBundle() override { /*not implemented*/ } private: int mFD; }; std::vector parseCmdArgs(std::string_view args) { std::vector argv; char delim = ABB_ARG_DELIMETER; size_t size = args.size(); size_t base = 0; while (base < size) { size_t found; for (found = base; found < size && args[found] && args[found] != delim; ++found) ; if (found > base) { argv.emplace_back(args.substr(base, found - base)); } base = found + 1; } return argv; } } // namespace static int execCmd(std::string_view args, int in, int out, int err) { AdbFdTextOutput oin(out); AdbFdTextOutput oerr(err); return cmdMain(parseCmdArgs(args), oin, oerr, in, out, err, RunMode::kLibrary); } int main(int argc, char* const argv[]) { signal(SIGPIPE, SIG_IGN); int fd = STDIN_FILENO; std::string data; while (true) { std::string error; if (!ReadProtocolString(fd, &data, &error)) { PLOG(ERROR) << "Failed to read message: " << error; break; } auto result = StartCommandInProcess(std::move(data), &execCmd); if (!SendFileDescriptor(fd, result)) { PLOG(ERROR) << "Failed to send an inprocess fd for command: " << data; break; } } }