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