|  | /* | 
|  | * 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 <sys/wait.h> | 
|  |  | 
|  | 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<std::string_view> parseCmdArgs(std::string_view args) { | 
|  | std::vector<std::string_view> 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; | 
|  | } | 
|  | } | 
|  | } |