10578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato/*
20578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato * Copyright (C) 2016 The Android Open Source Project
30578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato *
40578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato * Licensed under the Apache License, Version 2.0 (the "License");
50578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato * you may not use this file except in compliance with the License.
60578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato * You may obtain a copy of the License at
70578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato *
80578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato *      http://www.apache.org/licenses/LICENSE-2.0
90578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato *
100578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato * Unless required by applicable law or agreed to in writing, software
110578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato * distributed under the License is distributed on an "AS IS" BASIS,
120578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
130578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato * See the License for the specific language governing permissions and
140578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato * limitations under the License.
150578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato */
160578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato
170578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato#include "command.h"
180578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato
190578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato#include "print.h"
200578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato#include "util.h"
210578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato
220578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato#include <errno.h>
230578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato#include <string.h>
240578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato#include <stdlib.h>
250578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato#include <sys/types.h>
2631617e3b8ff01bb016446a0d2cb687b25aee42c6Joe Onorato#include <sys/stat.h>
2731617e3b8ff01bb016446a0d2cb687b25aee42c6Joe Onorato#include <unistd.h>
280578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato#include <sys/wait.h>
290578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato
3031617e3b8ff01bb016446a0d2cb687b25aee42c6Joe Onoratoextern char **environ;
3131617e3b8ff01bb016446a0d2cb687b25aee42c6Joe Onorato
320578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe OnoratoCommand::Command(const string& prog)
330578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato    :prog(prog)
340578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato{
350578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato}
360578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato
370578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe OnoratoCommand::~Command()
380578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato{
390578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato}
400578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato
410578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onoratovoid
420578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe OnoratoCommand::AddArg(const string& arg)
430578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato{
440578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato    args.push_back(arg);
450578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato}
460578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato
470578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onoratovoid
480578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe OnoratoCommand::AddEnv(const string& name, const string& value)
490578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato{
500578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato    env[name] = value;
510578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato}
520578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato
530578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onoratoconst char*
540578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe OnoratoCommand::GetProg() const
550578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato{
560578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato    return prog.c_str();
570578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato}
580578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato
590578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onoratochar *const *
600578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe OnoratoCommand::GetArgv() const
610578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato{
620578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato    const int N = args.size();
630578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato    char** result = (char**)malloc(sizeof(char*)*(N+2));
640578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato    result[0] = strdup(prog.c_str());
650578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato    for (int i=0; i<N; i++) {
660578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato        result[i+1] = strdup(args[i].c_str());
670578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato    }
680578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato    result[N+1] = 0;
690578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato    return result;
700578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato}
710578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato
720578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onoratochar *const *
730578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe OnoratoCommand::GetEnv() const
740578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato{
750578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato    map<string,string> copy;
760578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato    for (const char** p=(const char**)environ; *p != NULL; p++) {
770578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato        char* name = strdup(*p);
780578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato        char* value = strchr(name, '=');
790578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato        *value = '\0';
800578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato        value++;
810578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato        copy[name] = value;
820578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato        free(name);
830578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato    }
840578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato    for (map<string,string>::const_iterator it=env.begin(); it!=env.end(); it++) {
850578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato        copy[it->first] = it->second;
860578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato    }
870578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato    char** result = (char**)malloc(sizeof(char*)*(copy.size()+1));
880578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato    char** row = result;
890578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato    for (map<string,string>::const_iterator it=copy.begin(); it!=copy.end(); it++) {
900578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato        *row = (char*)malloc(it->first.size() + it->second.size() + 2);
910578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato        strcpy(*row, it->first.c_str());
920578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato        strcat(*row, "=");
930578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato        strcat(*row, it->second.c_str());
940578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato        row++;
950578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato    }
960578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato    *row = NULL;
970578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato    return result;
980578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato}
990578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato
1000578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onoratostring
1010578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onoratoget_command_output(const Command& command, int* err, bool quiet)
1020578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato{
1030578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato    if (!quiet) {
1040578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato        print_command(command);
1050578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato    }
1060578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato
1070578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato    int fds[2];
108c7edf078f92c7ce083f8c243a79f8aecdfff4ac1Chih-Hung Hsieh    if (0 != pipe(fds)) {
109c7edf078f92c7ce083f8c243a79f8aecdfff4ac1Chih-Hung Hsieh        return string();
110c7edf078f92c7ce083f8c243a79f8aecdfff4ac1Chih-Hung Hsieh    }
1110578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato
1120578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato    pid_t pid = fork();
1130578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato
1140578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato    if (pid == -1) {
1150578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato        // fork error
1160578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato        *err = errno;
1170578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato        return string();
1180578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato    } else if (pid == 0) {
1190578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato        // child
1200578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato        while ((dup2(fds[1], STDOUT_FILENO) == -1) && (errno == EINTR)) {}
1210578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato        close(fds[1]);
1220578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato        close(fds[0]);
1230578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato        const char* prog = command.GetProg();
1240578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato        char* const* argv = command.GetArgv();
1250578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato        char* const* env = command.GetEnv();
12631617e3b8ff01bb016446a0d2cb687b25aee42c6Joe Onorato        exec_with_path_search(prog, argv, env);
1270578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato        if (!quiet) {
1280578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato            print_error("Unable to run command: %s", prog);
1290578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato        }
1300578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato        exit(1);
1310578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato    } else {
1320578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato        // parent
1330578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato        close(fds[1]);
1340578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato        string result;
1350578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato        const int size = 16*1024;
1360578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato        char* buf = (char*)malloc(size);
1370578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato        while (true) {
1380578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato            ssize_t amt = read(fds[0], buf, size);
1390578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato            if (amt <= 0) {
1400578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato                break;
1410578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato            } else if (amt > 0) {
1420578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato                result.append(buf, amt);
1430578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato            }
1440578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato        }
1450578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato        free(buf);
1460578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato        int status;
1470578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato        waitpid(pid, &status, 0);
1480578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato        if (WIFEXITED(status)) {
1490578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato            *err = WEXITSTATUS(status);
1500578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato            return result;
1510578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato        } else {
1520578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato            *err = -1;
1530578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato            return string();
1540578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato        }
1550578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato    }
1560578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato}
1570578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato
1580578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato
1590578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onoratoint
1600578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onoratorun_command(const Command& command)
1610578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato{
1620578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato    print_command(command);
1630578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato
1640578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato    pid_t pid = fork();
1650578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato
1660578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato    if (pid == -1) {
1670578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato        // fork error
1680578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato        return errno;
1690578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato    } else if (pid == 0) {
1700578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato        // child
1710578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato        const char* prog = command.GetProg();
1720578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato        char* const* argv = command.GetArgv();
1730578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato        char* const* env = command.GetEnv();
17431617e3b8ff01bb016446a0d2cb687b25aee42c6Joe Onorato        exec_with_path_search(prog, argv, env);
1750578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato        print_error("Unable to run command: %s", prog);
1760578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato        exit(1);
1770578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato    } else {
1780578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato        // parent
1790578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato        int status;
1800578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato        waitpid(pid, &status, 0);
1810578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato        if (WIFEXITED(status)) {
1820578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato            return WEXITSTATUS(status);
1830578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato        } else {
1840578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato            return -1;
1850578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato        }
1860578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato    }
1870578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato}
1880578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato
18931617e3b8ff01bb016446a0d2cb687b25aee42c6Joe Onoratoint
19031617e3b8ff01bb016446a0d2cb687b25aee42c6Joe Onoratoexec_with_path_search(const char* prog, char const* const* argv, char const* const* envp)
19131617e3b8ff01bb016446a0d2cb687b25aee42c6Joe Onorato{
192a40118d7b6f70f44eaf4a47a32808088fd039f71Dan Willemsen    if (strchr(prog, '/') != NULL) {
19331617e3b8ff01bb016446a0d2cb687b25aee42c6Joe Onorato        return execve(prog, (char*const*)argv, (char*const*)envp);
19431617e3b8ff01bb016446a0d2cb687b25aee42c6Joe Onorato    } else {
19531617e3b8ff01bb016446a0d2cb687b25aee42c6Joe Onorato        char* pathEnv = strdup(getenv("PATH"));
19631617e3b8ff01bb016446a0d2cb687b25aee42c6Joe Onorato        if (pathEnv == NULL) {
19731617e3b8ff01bb016446a0d2cb687b25aee42c6Joe Onorato            return 1;
19831617e3b8ff01bb016446a0d2cb687b25aee42c6Joe Onorato        }
19931617e3b8ff01bb016446a0d2cb687b25aee42c6Joe Onorato        char* dir = pathEnv;
20031617e3b8ff01bb016446a0d2cb687b25aee42c6Joe Onorato        while (dir) {
20131617e3b8ff01bb016446a0d2cb687b25aee42c6Joe Onorato            char* next = strchr(dir, ':');
20231617e3b8ff01bb016446a0d2cb687b25aee42c6Joe Onorato            if (next != NULL) {
20331617e3b8ff01bb016446a0d2cb687b25aee42c6Joe Onorato                *next = '\0';
20431617e3b8ff01bb016446a0d2cb687b25aee42c6Joe Onorato                next++;
20531617e3b8ff01bb016446a0d2cb687b25aee42c6Joe Onorato            }
20631617e3b8ff01bb016446a0d2cb687b25aee42c6Joe Onorato            if (dir[0] == '/') {
20731617e3b8ff01bb016446a0d2cb687b25aee42c6Joe Onorato                struct stat st;
20831617e3b8ff01bb016446a0d2cb687b25aee42c6Joe Onorato                string executable = string(dir) + "/" + prog;
20931617e3b8ff01bb016446a0d2cb687b25aee42c6Joe Onorato                if (stat(executable.c_str(), &st) == 0) {
21031617e3b8ff01bb016446a0d2cb687b25aee42c6Joe Onorato                    execve(executable.c_str(), (char*const*)argv, (char*const*)envp);
21131617e3b8ff01bb016446a0d2cb687b25aee42c6Joe Onorato                }
21231617e3b8ff01bb016446a0d2cb687b25aee42c6Joe Onorato            }
21331617e3b8ff01bb016446a0d2cb687b25aee42c6Joe Onorato            dir = next;
21431617e3b8ff01bb016446a0d2cb687b25aee42c6Joe Onorato        }
21531617e3b8ff01bb016446a0d2cb687b25aee42c6Joe Onorato        free(pathEnv);
21631617e3b8ff01bb016446a0d2cb687b25aee42c6Joe Onorato        return 1;
21731617e3b8ff01bb016446a0d2cb687b25aee42c6Joe Onorato    }
21831617e3b8ff01bb016446a0d2cb687b25aee42c6Joe Onorato}
21931617e3b8ff01bb016446a0d2cb687b25aee42c6Joe Onorato
220