blob: df0dd7ce463d1e8777d4e56d3d6b4de00126ed3c [file] [log] [blame]
MÃ¥rten Kongstad2503a492018-09-27 13:32:30 +02001/*
2 * Copyright (C) 2018 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#ifdef _WIN32
18// nothing to see here
19#else
20#include <memory>
21#include <string>
22#include <vector>
23
24#include <sys/types.h>
25#include <sys/wait.h>
26#include <unistd.h>
27
28#include "android-base/logging.h"
29
30#include "androidfw/PosixUtils.h"
31
32namespace {
33
34std::unique_ptr<std::string> ReadFile(int fd) {
35 std::unique_ptr<std::string> str(new std::string());
36 char buf[1024];
37 ssize_t r;
38 while ((r = read(fd, buf, sizeof(buf))) > 0) {
39 str->append(buf, r);
40 }
41 if (r != 0) {
42 return nullptr;
43 }
44 return str;
45}
46
47}
48
49namespace android {
50namespace util {
51
52std::unique_ptr<ProcResult> ExecuteBinary(const std::vector<std::string>& argv) {
53 int stdout[2]; // stdout[0] read, stdout[1] write
54 if (pipe(stdout) != 0) {
55 PLOG(ERROR) << "pipe";
56 return nullptr;
57 }
58
59 int stderr[2]; // stdout[0] read, stdout[1] write
60 if (pipe(stderr) != 0) {
61 PLOG(ERROR) << "pipe";
62 close(stdout[0]);
63 close(stdout[1]);
64 return nullptr;
65 }
66
67 char const** argv0 = (char const**)malloc(sizeof(char*) * (argv.size() + 1));
68 for (size_t i = 0; i < argv.size(); i++) {
69 argv0[i] = argv[i].c_str();
70 }
71 argv0[argv.size()] = nullptr;
72 switch (fork()) {
73 case -1: // error
74 free(argv0);
75 PLOG(ERROR) << "fork";
76 return nullptr;
77 case 0: // child
78 close(stdout[0]);
79 if (dup2(stdout[1], STDOUT_FILENO) == -1) {
80 abort();
81 }
82 close(stderr[0]);
83 if (dup2(stderr[1], STDERR_FILENO) == -1) {
84 abort();
85 }
86 execvp(argv0[0], const_cast<char* const*>(argv0));
87 PLOG(ERROR) << "execv";
88 abort();
89 default: // parent
90 free(argv0);
91 close(stdout[1]);
92 close(stderr[1]);
93 int status;
94 wait(&status);
95 if (!WIFEXITED(status)) {
96 return nullptr;
97 }
98 std::unique_ptr<ProcResult> result(new ProcResult());
99 result->status = status;
100 const auto out = ReadFile(stdout[0]);
101 result->stdout = out ? *out : "";
102 close(stdout[0]);
103 const auto err = ReadFile(stderr[0]);
104 result->stderr = err ? *err : "";
105 close(stderr[0]);
106 return result;
107 }
108}
109
110} // namespace util
111} // namespace android
112#endif