123eb1e20cf59e1238b65cc108f31dfbfd85b2337Dianne Hackborn/* 223eb1e20cf59e1238b65cc108f31dfbfd85b2337Dianne Hackborn * Copyright (C) 2015 The Android Open Source Project 323eb1e20cf59e1238b65cc108f31dfbfd85b2337Dianne Hackborn * 423eb1e20cf59e1238b65cc108f31dfbfd85b2337Dianne Hackborn * Licensed under the Apache License, Version 2.0 (the "License"); 523eb1e20cf59e1238b65cc108f31dfbfd85b2337Dianne Hackborn * you may not use this file except in compliance with the License. 623eb1e20cf59e1238b65cc108f31dfbfd85b2337Dianne Hackborn * You may obtain a copy of the License at 723eb1e20cf59e1238b65cc108f31dfbfd85b2337Dianne Hackborn * 823eb1e20cf59e1238b65cc108f31dfbfd85b2337Dianne Hackborn * http://www.apache.org/licenses/LICENSE-2.0 923eb1e20cf59e1238b65cc108f31dfbfd85b2337Dianne Hackborn * 1023eb1e20cf59e1238b65cc108f31dfbfd85b2337Dianne Hackborn * Unless required by applicable law or agreed to in writing, software 1123eb1e20cf59e1238b65cc108f31dfbfd85b2337Dianne Hackborn * distributed under the License is distributed on an "AS IS" BASIS, 1223eb1e20cf59e1238b65cc108f31dfbfd85b2337Dianne Hackborn * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1323eb1e20cf59e1238b65cc108f31dfbfd85b2337Dianne Hackborn * See the License for the specific language governing permissions and 1423eb1e20cf59e1238b65cc108f31dfbfd85b2337Dianne Hackborn * limitations under the License. 1523eb1e20cf59e1238b65cc108f31dfbfd85b2337Dianne Hackborn */ 1623eb1e20cf59e1238b65cc108f31dfbfd85b2337Dianne Hackborn 1723eb1e20cf59e1238b65cc108f31dfbfd85b2337Dianne Hackborn#define LOG_TAG "cmd" 1823eb1e20cf59e1238b65cc108f31dfbfd85b2337Dianne Hackborn 1923eb1e20cf59e1238b65cc108f31dfbfd85b2337Dianne Hackborn#include <utils/Log.h> 2023eb1e20cf59e1238b65cc108f31dfbfd85b2337Dianne Hackborn#include <binder/Parcel.h> 2123eb1e20cf59e1238b65cc108f31dfbfd85b2337Dianne Hackborn#include <binder/ProcessState.h> 2223eb1e20cf59e1238b65cc108f31dfbfd85b2337Dianne Hackborn#include <binder/IResultReceiver.h> 2323eb1e20cf59e1238b65cc108f31dfbfd85b2337Dianne Hackborn#include <binder/IServiceManager.h> 241941a404d642b3dfaac365ba494f1e9912876f00Dianne Hackborn#include <binder/IShellCallback.h> 2523eb1e20cf59e1238b65cc108f31dfbfd85b2337Dianne Hackborn#include <binder/TextOutput.h> 263d9eb950b14ee6527a5a85d669bd03ce2bdcff32Dianne Hackborn#include <utils/Condition.h> 273d9eb950b14ee6527a5a85d669bd03ce2bdcff32Dianne Hackborn#include <utils/Mutex.h> 2823eb1e20cf59e1238b65cc108f31dfbfd85b2337Dianne Hackborn#include <utils/Vector.h> 2923eb1e20cf59e1238b65cc108f31dfbfd85b2337Dianne Hackborn 3023eb1e20cf59e1238b65cc108f31dfbfd85b2337Dianne Hackborn#include <getopt.h> 3123eb1e20cf59e1238b65cc108f31dfbfd85b2337Dianne Hackborn#include <stdlib.h> 3223eb1e20cf59e1238b65cc108f31dfbfd85b2337Dianne Hackborn#include <stdio.h> 3323eb1e20cf59e1238b65cc108f31dfbfd85b2337Dianne Hackborn#include <string.h> 3423eb1e20cf59e1238b65cc108f31dfbfd85b2337Dianne Hackborn#include <unistd.h> 351941a404d642b3dfaac365ba494f1e9912876f00Dianne Hackborn#include <fcntl.h> 3623eb1e20cf59e1238b65cc108f31dfbfd85b2337Dianne Hackborn#include <sys/time.h> 371941a404d642b3dfaac365ba494f1e9912876f00Dianne Hackborn#include <errno.h> 384e7d18a72f72967a881bcdf78167011a836538efJiyong Park#include <memory> 391941a404d642b3dfaac365ba494f1e9912876f00Dianne Hackborn 401941a404d642b3dfaac365ba494f1e9912876f00Dianne Hackborn#include "selinux/selinux.h" 411941a404d642b3dfaac365ba494f1e9912876f00Dianne Hackborn#include "selinux/android.h" 421941a404d642b3dfaac365ba494f1e9912876f00Dianne Hackborn 433d9eb950b14ee6527a5a85d669bd03ce2bdcff32Dianne Hackborn#define DEBUG 0 443d9eb950b14ee6527a5a85d669bd03ce2bdcff32Dianne Hackborn 4523eb1e20cf59e1238b65cc108f31dfbfd85b2337Dianne Hackbornusing namespace android; 4623eb1e20cf59e1238b65cc108f31dfbfd85b2337Dianne Hackborn 4723eb1e20cf59e1238b65cc108f31dfbfd85b2337Dianne Hackbornstatic int sort_func(const String16* lhs, const String16* rhs) 4823eb1e20cf59e1238b65cc108f31dfbfd85b2337Dianne Hackborn{ 4923eb1e20cf59e1238b65cc108f31dfbfd85b2337Dianne Hackborn return lhs->compare(*rhs); 5023eb1e20cf59e1238b65cc108f31dfbfd85b2337Dianne Hackborn} 5123eb1e20cf59e1238b65cc108f31dfbfd85b2337Dianne Hackborn 521941a404d642b3dfaac365ba494f1e9912876f00Dianne Hackbornstruct SecurityContext_Delete { 531941a404d642b3dfaac365ba494f1e9912876f00Dianne Hackborn void operator()(security_context_t p) const { 541941a404d642b3dfaac365ba494f1e9912876f00Dianne Hackborn freecon(p); 551941a404d642b3dfaac365ba494f1e9912876f00Dianne Hackborn } 561941a404d642b3dfaac365ba494f1e9912876f00Dianne Hackborn}; 574e7d18a72f72967a881bcdf78167011a836538efJiyong Parktypedef std::unique_ptr<char[], SecurityContext_Delete> Unique_SecurityContext; 581941a404d642b3dfaac365ba494f1e9912876f00Dianne Hackborn 591941a404d642b3dfaac365ba494f1e9912876f00Dianne Hackbornclass MyShellCallback : public BnShellCallback 601941a404d642b3dfaac365ba494f1e9912876f00Dianne Hackborn{ 611941a404d642b3dfaac365ba494f1e9912876f00Dianne Hackbornpublic: 62e5ed19999d724b6f5131803ff56b3536349b58deDianne Hackborn bool mActive = true; 63e5ed19999d724b6f5131803ff56b3536349b58deDianne Hackborn 644217f8ecfe8f884288104262000275c1633b983eDianne Hackborn virtual int openFile(const String16& path, const String16& seLinuxContext, 654217f8ecfe8f884288104262000275c1633b983eDianne Hackborn const String16& mode) { 661941a404d642b3dfaac365ba494f1e9912876f00Dianne Hackborn String8 path8(path); 671941a404d642b3dfaac365ba494f1e9912876f00Dianne Hackborn char cwd[256]; 681941a404d642b3dfaac365ba494f1e9912876f00Dianne Hackborn getcwd(cwd, 256); 691941a404d642b3dfaac365ba494f1e9912876f00Dianne Hackborn String8 fullPath(cwd); 701941a404d642b3dfaac365ba494f1e9912876f00Dianne Hackborn fullPath.appendPath(path8); 71e5ed19999d724b6f5131803ff56b3536349b58deDianne Hackborn if (!mActive) { 72e5ed19999d724b6f5131803ff56b3536349b58deDianne Hackborn aerr << "Open attempt after active for: " << fullPath << endl; 73e5ed19999d724b6f5131803ff56b3536349b58deDianne Hackborn return -EPERM; 74e5ed19999d724b6f5131803ff56b3536349b58deDianne Hackborn } 75228f2f66318e97da7c9d13fdc9f28ebddaa1fb46Dianne Hackborn#if DEBUG 76228f2f66318e97da7c9d13fdc9f28ebddaa1fb46Dianne Hackborn ALOGD("openFile: %s, full=%s", path8.string(), fullPath.string()); 77228f2f66318e97da7c9d13fdc9f28ebddaa1fb46Dianne Hackborn#endif 784217f8ecfe8f884288104262000275c1633b983eDianne Hackborn int flags = 0; 794217f8ecfe8f884288104262000275c1633b983eDianne Hackborn bool checkRead = false; 804217f8ecfe8f884288104262000275c1633b983eDianne Hackborn bool checkWrite = false; 814217f8ecfe8f884288104262000275c1633b983eDianne Hackborn if (mode == String16("w")) { 824217f8ecfe8f884288104262000275c1633b983eDianne Hackborn flags = O_WRONLY|O_CREAT|O_TRUNC; 834217f8ecfe8f884288104262000275c1633b983eDianne Hackborn checkWrite = true; 844217f8ecfe8f884288104262000275c1633b983eDianne Hackborn } else if (mode == String16("w+")) { 854217f8ecfe8f884288104262000275c1633b983eDianne Hackborn flags = O_RDWR|O_CREAT|O_TRUNC; 864217f8ecfe8f884288104262000275c1633b983eDianne Hackborn checkRead = checkWrite = true; 874217f8ecfe8f884288104262000275c1633b983eDianne Hackborn } else if (mode == String16("r")) { 884217f8ecfe8f884288104262000275c1633b983eDianne Hackborn flags = O_RDONLY; 894217f8ecfe8f884288104262000275c1633b983eDianne Hackborn checkRead = true; 904217f8ecfe8f884288104262000275c1633b983eDianne Hackborn } else if (mode == String16("r+")) { 914217f8ecfe8f884288104262000275c1633b983eDianne Hackborn flags = O_RDWR; 924217f8ecfe8f884288104262000275c1633b983eDianne Hackborn checkRead = checkWrite = true; 934217f8ecfe8f884288104262000275c1633b983eDianne Hackborn } else { 944217f8ecfe8f884288104262000275c1633b983eDianne Hackborn aerr << "Invalid mode requested: " << mode.string() << endl; 954217f8ecfe8f884288104262000275c1633b983eDianne Hackborn return -EINVAL; 964217f8ecfe8f884288104262000275c1633b983eDianne Hackborn } 974217f8ecfe8f884288104262000275c1633b983eDianne Hackborn int fd = open(fullPath.string(), flags, S_IRWXU|S_IRWXG); 98228f2f66318e97da7c9d13fdc9f28ebddaa1fb46Dianne Hackborn#if DEBUG 99228f2f66318e97da7c9d13fdc9f28ebddaa1fb46Dianne Hackborn ALOGD("openFile: fd=%d", fd); 100228f2f66318e97da7c9d13fdc9f28ebddaa1fb46Dianne Hackborn#endif 1011941a404d642b3dfaac365ba494f1e9912876f00Dianne Hackborn if (fd < 0) { 1021941a404d642b3dfaac365ba494f1e9912876f00Dianne Hackborn return fd; 1031941a404d642b3dfaac365ba494f1e9912876f00Dianne Hackborn } 1041941a404d642b3dfaac365ba494f1e9912876f00Dianne Hackborn if (is_selinux_enabled() && seLinuxContext.size() > 0) { 1051941a404d642b3dfaac365ba494f1e9912876f00Dianne Hackborn String8 seLinuxContext8(seLinuxContext); 1061941a404d642b3dfaac365ba494f1e9912876f00Dianne Hackborn security_context_t tmp = NULL; 107f463e180e5a69b4a43acd41c41c8518fa8c22b2dChih-Hung Hsieh getfilecon(fullPath.string(), &tmp); 1081941a404d642b3dfaac365ba494f1e9912876f00Dianne Hackborn Unique_SecurityContext context(tmp); 1094217f8ecfe8f884288104262000275c1633b983eDianne Hackborn if (checkWrite) { 1104217f8ecfe8f884288104262000275c1633b983eDianne Hackborn int accessGranted = selinux_check_access(seLinuxContext8.string(), context.get(), 1114217f8ecfe8f884288104262000275c1633b983eDianne Hackborn "file", "write", NULL); 1124217f8ecfe8f884288104262000275c1633b983eDianne Hackborn if (accessGranted != 0) { 113228f2f66318e97da7c9d13fdc9f28ebddaa1fb46Dianne Hackborn#if DEBUG 114228f2f66318e97da7c9d13fdc9f28ebddaa1fb46Dianne Hackborn ALOGD("openFile: failed selinux write check!"); 115228f2f66318e97da7c9d13fdc9f28ebddaa1fb46Dianne Hackborn#endif 1164217f8ecfe8f884288104262000275c1633b983eDianne Hackborn close(fd); 1174217f8ecfe8f884288104262000275c1633b983eDianne Hackborn aerr << "System server has no access to write file context " << context.get() 1184217f8ecfe8f884288104262000275c1633b983eDianne Hackborn << " (from path " << fullPath.string() << ", context " 1194217f8ecfe8f884288104262000275c1633b983eDianne Hackborn << seLinuxContext8.string() << ")" << endl; 1204217f8ecfe8f884288104262000275c1633b983eDianne Hackborn return -EPERM; 1214217f8ecfe8f884288104262000275c1633b983eDianne Hackborn } 1224217f8ecfe8f884288104262000275c1633b983eDianne Hackborn } 1234217f8ecfe8f884288104262000275c1633b983eDianne Hackborn if (checkRead) { 1244217f8ecfe8f884288104262000275c1633b983eDianne Hackborn int accessGranted = selinux_check_access(seLinuxContext8.string(), context.get(), 1254217f8ecfe8f884288104262000275c1633b983eDianne Hackborn "file", "read", NULL); 1264217f8ecfe8f884288104262000275c1633b983eDianne Hackborn if (accessGranted != 0) { 127228f2f66318e97da7c9d13fdc9f28ebddaa1fb46Dianne Hackborn#if DEBUG 128228f2f66318e97da7c9d13fdc9f28ebddaa1fb46Dianne Hackborn ALOGD("openFile: failed selinux read check!"); 129228f2f66318e97da7c9d13fdc9f28ebddaa1fb46Dianne Hackborn#endif 1304217f8ecfe8f884288104262000275c1633b983eDianne Hackborn close(fd); 1314217f8ecfe8f884288104262000275c1633b983eDianne Hackborn aerr << "System server has no access to read file context " << context.get() 1324217f8ecfe8f884288104262000275c1633b983eDianne Hackborn << " (from path " << fullPath.string() << ", context " 1334217f8ecfe8f884288104262000275c1633b983eDianne Hackborn << seLinuxContext8.string() << ")" << endl; 1344217f8ecfe8f884288104262000275c1633b983eDianne Hackborn return -EPERM; 1354217f8ecfe8f884288104262000275c1633b983eDianne Hackborn } 1361941a404d642b3dfaac365ba494f1e9912876f00Dianne Hackborn } 1371941a404d642b3dfaac365ba494f1e9912876f00Dianne Hackborn } 1381941a404d642b3dfaac365ba494f1e9912876f00Dianne Hackborn return fd; 1391941a404d642b3dfaac365ba494f1e9912876f00Dianne Hackborn } 1401941a404d642b3dfaac365ba494f1e9912876f00Dianne Hackborn}; 1411941a404d642b3dfaac365ba494f1e9912876f00Dianne Hackborn 14223eb1e20cf59e1238b65cc108f31dfbfd85b2337Dianne Hackbornclass MyResultReceiver : public BnResultReceiver 14323eb1e20cf59e1238b65cc108f31dfbfd85b2337Dianne Hackborn{ 14423eb1e20cf59e1238b65cc108f31dfbfd85b2337Dianne Hackbornpublic: 1453d9eb950b14ee6527a5a85d669bd03ce2bdcff32Dianne Hackborn Mutex mMutex; 1463d9eb950b14ee6527a5a85d669bd03ce2bdcff32Dianne Hackborn Condition mCondition; 1473d9eb950b14ee6527a5a85d669bd03ce2bdcff32Dianne Hackborn bool mHaveResult = false; 1483d9eb950b14ee6527a5a85d669bd03ce2bdcff32Dianne Hackborn int32_t mResult = 0; 1493d9eb950b14ee6527a5a85d669bd03ce2bdcff32Dianne Hackborn 1503d9eb950b14ee6527a5a85d669bd03ce2bdcff32Dianne Hackborn virtual void send(int32_t resultCode) { 1513d9eb950b14ee6527a5a85d669bd03ce2bdcff32Dianne Hackborn AutoMutex _l(mMutex); 1523d9eb950b14ee6527a5a85d669bd03ce2bdcff32Dianne Hackborn mResult = resultCode; 1533d9eb950b14ee6527a5a85d669bd03ce2bdcff32Dianne Hackborn mHaveResult = true; 1543d9eb950b14ee6527a5a85d669bd03ce2bdcff32Dianne Hackborn mCondition.signal(); 1553d9eb950b14ee6527a5a85d669bd03ce2bdcff32Dianne Hackborn } 1563d9eb950b14ee6527a5a85d669bd03ce2bdcff32Dianne Hackborn 1573d9eb950b14ee6527a5a85d669bd03ce2bdcff32Dianne Hackborn int32_t waitForResult() { 1583d9eb950b14ee6527a5a85d669bd03ce2bdcff32Dianne Hackborn AutoMutex _l(mMutex); 1593d9eb950b14ee6527a5a85d669bd03ce2bdcff32Dianne Hackborn while (!mHaveResult) { 1603d9eb950b14ee6527a5a85d669bd03ce2bdcff32Dianne Hackborn mCondition.wait(mMutex); 1613d9eb950b14ee6527a5a85d669bd03ce2bdcff32Dianne Hackborn } 1623d9eb950b14ee6527a5a85d669bd03ce2bdcff32Dianne Hackborn return mResult; 16323eb1e20cf59e1238b65cc108f31dfbfd85b2337Dianne Hackborn } 16423eb1e20cf59e1238b65cc108f31dfbfd85b2337Dianne Hackborn}; 16523eb1e20cf59e1238b65cc108f31dfbfd85b2337Dianne Hackborn 16623eb1e20cf59e1238b65cc108f31dfbfd85b2337Dianne Hackbornint main(int argc, char* const argv[]) 16723eb1e20cf59e1238b65cc108f31dfbfd85b2337Dianne Hackborn{ 16823eb1e20cf59e1238b65cc108f31dfbfd85b2337Dianne Hackborn signal(SIGPIPE, SIG_IGN); 16923eb1e20cf59e1238b65cc108f31dfbfd85b2337Dianne Hackborn sp<ProcessState> proc = ProcessState::self(); 170c21bc9afe403f52c189d2d6b79dedaf9dce6217bMartijn Coenen // setThreadPoolMaxThreadCount(0) actually tells the kernel it's 171c21bc9afe403f52c189d2d6b79dedaf9dce6217bMartijn Coenen // not allowed to spawn any additional threads, but we still spawn 172c21bc9afe403f52c189d2d6b79dedaf9dce6217bMartijn Coenen // a binder thread from userspace when we call startThreadPool(). 173c21bc9afe403f52c189d2d6b79dedaf9dce6217bMartijn Coenen // This is safe because we only have 2 callbacks, neither of which 174c21bc9afe403f52c189d2d6b79dedaf9dce6217bMartijn Coenen // block. 175c21bc9afe403f52c189d2d6b79dedaf9dce6217bMartijn Coenen // See b/36066697 for rationale 176c21bc9afe403f52c189d2d6b79dedaf9dce6217bMartijn Coenen proc->setThreadPoolMaxThreadCount(0); 17723eb1e20cf59e1238b65cc108f31dfbfd85b2337Dianne Hackborn proc->startThreadPool(); 17823eb1e20cf59e1238b65cc108f31dfbfd85b2337Dianne Hackborn 179228f2f66318e97da7c9d13fdc9f28ebddaa1fb46Dianne Hackborn#if DEBUG 180228f2f66318e97da7c9d13fdc9f28ebddaa1fb46Dianne Hackborn ALOGD("cmd: starting"); 181228f2f66318e97da7c9d13fdc9f28ebddaa1fb46Dianne Hackborn#endif 18223eb1e20cf59e1238b65cc108f31dfbfd85b2337Dianne Hackborn sp<IServiceManager> sm = defaultServiceManager(); 18323eb1e20cf59e1238b65cc108f31dfbfd85b2337Dianne Hackborn fflush(stdout); 18423eb1e20cf59e1238b65cc108f31dfbfd85b2337Dianne Hackborn if (sm == NULL) { 1853d9eb950b14ee6527a5a85d669bd03ce2bdcff32Dianne Hackborn ALOGW("Unable to get default service manager!"); 18623eb1e20cf59e1238b65cc108f31dfbfd85b2337Dianne Hackborn aerr << "cmd: Unable to get default service manager!" << endl; 18723eb1e20cf59e1238b65cc108f31dfbfd85b2337Dianne Hackborn return 20; 18823eb1e20cf59e1238b65cc108f31dfbfd85b2337Dianne Hackborn } 18923eb1e20cf59e1238b65cc108f31dfbfd85b2337Dianne Hackborn 19023eb1e20cf59e1238b65cc108f31dfbfd85b2337Dianne Hackborn if (argc == 1) { 1913d9eb950b14ee6527a5a85d669bd03ce2bdcff32Dianne Hackborn aerr << "cmd: No service specified; use -l to list all services" << endl; 19223eb1e20cf59e1238b65cc108f31dfbfd85b2337Dianne Hackborn return 20; 19323eb1e20cf59e1238b65cc108f31dfbfd85b2337Dianne Hackborn } 19423eb1e20cf59e1238b65cc108f31dfbfd85b2337Dianne Hackborn 19523eb1e20cf59e1238b65cc108f31dfbfd85b2337Dianne Hackborn if ((argc == 2) && (strcmp(argv[1], "-l") == 0)) { 19623eb1e20cf59e1238b65cc108f31dfbfd85b2337Dianne Hackborn Vector<String16> services = sm->listServices(); 19723eb1e20cf59e1238b65cc108f31dfbfd85b2337Dianne Hackborn services.sort(sort_func); 19823eb1e20cf59e1238b65cc108f31dfbfd85b2337Dianne Hackborn aout << "Currently running services:" << endl; 19923eb1e20cf59e1238b65cc108f31dfbfd85b2337Dianne Hackborn 20023eb1e20cf59e1238b65cc108f31dfbfd85b2337Dianne Hackborn for (size_t i=0; i<services.size(); i++) { 20123eb1e20cf59e1238b65cc108f31dfbfd85b2337Dianne Hackborn sp<IBinder> service = sm->checkService(services[i]); 20223eb1e20cf59e1238b65cc108f31dfbfd85b2337Dianne Hackborn if (service != NULL) { 20323eb1e20cf59e1238b65cc108f31dfbfd85b2337Dianne Hackborn aout << " " << services[i] << endl; 20423eb1e20cf59e1238b65cc108f31dfbfd85b2337Dianne Hackborn } 20523eb1e20cf59e1238b65cc108f31dfbfd85b2337Dianne Hackborn } 20623eb1e20cf59e1238b65cc108f31dfbfd85b2337Dianne Hackborn return 0; 20723eb1e20cf59e1238b65cc108f31dfbfd85b2337Dianne Hackborn } 20823eb1e20cf59e1238b65cc108f31dfbfd85b2337Dianne Hackborn 20923eb1e20cf59e1238b65cc108f31dfbfd85b2337Dianne Hackborn Vector<String16> args; 21023eb1e20cf59e1238b65cc108f31dfbfd85b2337Dianne Hackborn for (int i=2; i<argc; i++) { 21123eb1e20cf59e1238b65cc108f31dfbfd85b2337Dianne Hackborn args.add(String16(argv[i])); 21223eb1e20cf59e1238b65cc108f31dfbfd85b2337Dianne Hackborn } 21323eb1e20cf59e1238b65cc108f31dfbfd85b2337Dianne Hackborn String16 cmd = String16(argv[1]); 21423eb1e20cf59e1238b65cc108f31dfbfd85b2337Dianne Hackborn sp<IBinder> service = sm->checkService(cmd); 21523eb1e20cf59e1238b65cc108f31dfbfd85b2337Dianne Hackborn if (service == NULL) { 2163d9eb950b14ee6527a5a85d669bd03ce2bdcff32Dianne Hackborn ALOGW("Can't find service %s", argv[1]); 2173d9eb950b14ee6527a5a85d669bd03ce2bdcff32Dianne Hackborn aerr << "cmd: Can't find service: " << argv[1] << endl; 21823eb1e20cf59e1238b65cc108f31dfbfd85b2337Dianne Hackborn return 20; 21923eb1e20cf59e1238b65cc108f31dfbfd85b2337Dianne Hackborn } 22023eb1e20cf59e1238b65cc108f31dfbfd85b2337Dianne Hackborn 221e5ed19999d724b6f5131803ff56b3536349b58deDianne Hackborn sp<MyShellCallback> cb = new MyShellCallback(); 2223d9eb950b14ee6527a5a85d669bd03ce2bdcff32Dianne Hackborn sp<MyResultReceiver> result = new MyResultReceiver(); 2233d9eb950b14ee6527a5a85d669bd03ce2bdcff32Dianne Hackborn 2243d9eb950b14ee6527a5a85d669bd03ce2bdcff32Dianne Hackborn#if DEBUG 2253d9eb950b14ee6527a5a85d669bd03ce2bdcff32Dianne Hackborn ALOGD("cmd: Invoking %s in=%d, out=%d, err=%d", argv[1], STDIN_FILENO, STDOUT_FILENO, 2263d9eb950b14ee6527a5a85d669bd03ce2bdcff32Dianne Hackborn STDERR_FILENO); 2273d9eb950b14ee6527a5a85d669bd03ce2bdcff32Dianne Hackborn#endif 228e5ed19999d724b6f5131803ff56b3536349b58deDianne Hackborn 22923eb1e20cf59e1238b65cc108f31dfbfd85b2337Dianne Hackborn // TODO: block until a result is returned to MyResultReceiver. 2303d9eb950b14ee6527a5a85d669bd03ce2bdcff32Dianne Hackborn status_t err = IBinder::shellCommand(service, STDIN_FILENO, STDOUT_FILENO, STDERR_FILENO, args, 2313d9eb950b14ee6527a5a85d669bd03ce2bdcff32Dianne Hackborn cb, result); 2323d9eb950b14ee6527a5a85d669bd03ce2bdcff32Dianne Hackborn if (err < 0) { 2333d9eb950b14ee6527a5a85d669bd03ce2bdcff32Dianne Hackborn const char* errstr; 2343d9eb950b14ee6527a5a85d669bd03ce2bdcff32Dianne Hackborn switch (err) { 2353d9eb950b14ee6527a5a85d669bd03ce2bdcff32Dianne Hackborn case BAD_TYPE: errstr = "Bad type"; break; 2363d9eb950b14ee6527a5a85d669bd03ce2bdcff32Dianne Hackborn case FAILED_TRANSACTION: errstr = "Failed transaction"; break; 2373d9eb950b14ee6527a5a85d669bd03ce2bdcff32Dianne Hackborn case FDS_NOT_ALLOWED: errstr = "File descriptors not allowed"; break; 2383d9eb950b14ee6527a5a85d669bd03ce2bdcff32Dianne Hackborn case UNEXPECTED_NULL: errstr = "Unexpected null"; break; 2393d9eb950b14ee6527a5a85d669bd03ce2bdcff32Dianne Hackborn default: errstr = strerror(-err); break; 2403d9eb950b14ee6527a5a85d669bd03ce2bdcff32Dianne Hackborn } 2413d9eb950b14ee6527a5a85d669bd03ce2bdcff32Dianne Hackborn ALOGW("Failure calling service %s: %s (%d)", argv[1], errstr, -err); 2423d9eb950b14ee6527a5a85d669bd03ce2bdcff32Dianne Hackborn aout << "cmd: Failure calling service " << argv[1] << ": " << errstr << " (" 2433d9eb950b14ee6527a5a85d669bd03ce2bdcff32Dianne Hackborn << (-err) << ")" << endl; 2443d9eb950b14ee6527a5a85d669bd03ce2bdcff32Dianne Hackborn return err; 2453d9eb950b14ee6527a5a85d669bd03ce2bdcff32Dianne Hackborn } 246e5ed19999d724b6f5131803ff56b3536349b58deDianne Hackborn 247e5ed19999d724b6f5131803ff56b3536349b58deDianne Hackborn cb->mActive = false; 2483d9eb950b14ee6527a5a85d669bd03ce2bdcff32Dianne Hackborn status_t res = result->waitForResult(); 2493d9eb950b14ee6527a5a85d669bd03ce2bdcff32Dianne Hackborn#if DEBUG 2503d9eb950b14ee6527a5a85d669bd03ce2bdcff32Dianne Hackborn ALOGD("result=%d", (int)res); 2513d9eb950b14ee6527a5a85d669bd03ce2bdcff32Dianne Hackborn#endif 2523d9eb950b14ee6527a5a85d669bd03ce2bdcff32Dianne Hackborn return res; 25323eb1e20cf59e1238b65cc108f31dfbfd85b2337Dianne Hackborn} 254