1*e1eccf28SAndroid Build Coastguard Worker /* 2*e1eccf28SAndroid Build Coastguard Worker * Copyright (C) 2013 The Android Open Source Project 3*e1eccf28SAndroid Build Coastguard Worker * 4*e1eccf28SAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License"); 5*e1eccf28SAndroid Build Coastguard Worker * you may not use this file except in compliance with the License. 6*e1eccf28SAndroid Build Coastguard Worker * You may obtain a copy of the License at 7*e1eccf28SAndroid Build Coastguard Worker * 8*e1eccf28SAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0 9*e1eccf28SAndroid Build Coastguard Worker * 10*e1eccf28SAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software 11*e1eccf28SAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS, 12*e1eccf28SAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13*e1eccf28SAndroid Build Coastguard Worker * See the License for the specific language governing permissions and 14*e1eccf28SAndroid Build Coastguard Worker * limitations under the License. 15*e1eccf28SAndroid Build Coastguard Worker */ 16*e1eccf28SAndroid Build Coastguard Worker 17*e1eccf28SAndroid Build Coastguard Worker #include "rsUtils.h" 18*e1eccf28SAndroid Build Coastguard Worker #include "rsCppUtils.h" 19*e1eccf28SAndroid Build Coastguard Worker 20*e1eccf28SAndroid Build Coastguard Worker #include <errno.h> 21*e1eccf28SAndroid Build Coastguard Worker #include <string.h> 22*e1eccf28SAndroid Build Coastguard Worker #include <unistd.h> 23*e1eccf28SAndroid Build Coastguard Worker 24*e1eccf28SAndroid Build Coastguard Worker #include <string> 25*e1eccf28SAndroid Build Coastguard Worker 26*e1eccf28SAndroid Build Coastguard Worker #ifndef RS_COMPATIBILITY_LIB 27*e1eccf28SAndroid Build Coastguard Worker #include <sys/wait.h> 28*e1eccf28SAndroid Build Coastguard Worker #endif 29*e1eccf28SAndroid Build Coastguard Worker 30*e1eccf28SAndroid Build Coastguard Worker 31*e1eccf28SAndroid Build Coastguard Worker namespace android { 32*e1eccf28SAndroid Build Coastguard Worker namespace renderscript { 33*e1eccf28SAndroid Build Coastguard Worker 34*e1eccf28SAndroid Build Coastguard Worker const char * rsuCopyString(const char *name) { 35*e1eccf28SAndroid Build Coastguard Worker return rsuCopyString(name, strlen(name)); 36*e1eccf28SAndroid Build Coastguard Worker } 37*e1eccf28SAndroid Build Coastguard Worker 38*e1eccf28SAndroid Build Coastguard Worker const char * rsuCopyString(const char *name, size_t len) { 39*e1eccf28SAndroid Build Coastguard Worker char *n = new char[len+1]; 40*e1eccf28SAndroid Build Coastguard Worker memcpy(n, name, len); 41*e1eccf28SAndroid Build Coastguard Worker n[len] = 0; 42*e1eccf28SAndroid Build Coastguard Worker return n; 43*e1eccf28SAndroid Build Coastguard Worker } 44*e1eccf28SAndroid Build Coastguard Worker 45*e1eccf28SAndroid Build Coastguard Worker const char* rsuJoinStrings(int n, const char* const* strs) { 46*e1eccf28SAndroid Build Coastguard Worker std::string tmp; 47*e1eccf28SAndroid Build Coastguard Worker for (int i = 0; i < n; i++) { 48*e1eccf28SAndroid Build Coastguard Worker if (i > 0) { 49*e1eccf28SAndroid Build Coastguard Worker tmp.append(" "); 50*e1eccf28SAndroid Build Coastguard Worker } 51*e1eccf28SAndroid Build Coastguard Worker tmp.append(strs[i]); 52*e1eccf28SAndroid Build Coastguard Worker } 53*e1eccf28SAndroid Build Coastguard Worker return strndup(tmp.c_str(), tmp.size()); 54*e1eccf28SAndroid Build Coastguard Worker } 55*e1eccf28SAndroid Build Coastguard Worker 56*e1eccf28SAndroid Build Coastguard Worker #ifndef RS_COMPATIBILITY_LIB 57*e1eccf28SAndroid Build Coastguard Worker bool rsuExecuteCommand(const char *exe, int nArgs, const char * const *args) { 58*e1eccf28SAndroid Build Coastguard Worker std::unique_ptr<const char> joined(rsuJoinStrings(nArgs, args)); 59*e1eccf28SAndroid Build Coastguard Worker ALOGV("Invoking %s with args '%s'", exe, joined.get()); 60*e1eccf28SAndroid Build Coastguard Worker 61*e1eccf28SAndroid Build Coastguard Worker pid_t pid = fork(); 62*e1eccf28SAndroid Build Coastguard Worker 63*e1eccf28SAndroid Build Coastguard Worker switch (pid) { 64*e1eccf28SAndroid Build Coastguard Worker case -1: { // Error occurred (we attempt no recovery) 65*e1eccf28SAndroid Build Coastguard Worker ALOGE("Fork of \"%s\" failed with error %s", exe, strerror(errno)); 66*e1eccf28SAndroid Build Coastguard Worker return false; 67*e1eccf28SAndroid Build Coastguard Worker } 68*e1eccf28SAndroid Build Coastguard Worker case 0: { // Child process 69*e1eccf28SAndroid Build Coastguard Worker // No (direct or indirect) call to malloc between fork and exec. It is 70*e1eccf28SAndroid Build Coastguard Worker // possible that a different thread holds the heap lock before the fork. 71*e1eccf28SAndroid Build Coastguard Worker 72*e1eccf28SAndroid Build Coastguard Worker // ProcessManager in libcore can reap unclaimed SIGCHLDs in its process 73*e1eccf28SAndroid Build Coastguard Worker // group. To ensure that the exit signal is not caught by 74*e1eccf28SAndroid Build Coastguard Worker // ProcessManager and instead sent to libRS, set the child's PGID to its 75*e1eccf28SAndroid Build Coastguard Worker // PID. 76*e1eccf28SAndroid Build Coastguard Worker setpgid(0, 0); 77*e1eccf28SAndroid Build Coastguard Worker 78*e1eccf28SAndroid Build Coastguard Worker execv(exe, (char * const *)args); 79*e1eccf28SAndroid Build Coastguard Worker 80*e1eccf28SAndroid Build Coastguard Worker ALOGE("execv() failed: %s", strerror(errno)); 81*e1eccf28SAndroid Build Coastguard Worker abort(); 82*e1eccf28SAndroid Build Coastguard Worker return false; 83*e1eccf28SAndroid Build Coastguard Worker } 84*e1eccf28SAndroid Build Coastguard Worker default: { // Parent process (actual driver) 85*e1eccf28SAndroid Build Coastguard Worker // Wait on child process to finish execution. 86*e1eccf28SAndroid Build Coastguard Worker int status = 0; 87*e1eccf28SAndroid Build Coastguard Worker pid_t w = TEMP_FAILURE_RETRY(waitpid(pid, &status, 0)); 88*e1eccf28SAndroid Build Coastguard Worker if (w == -1) { 89*e1eccf28SAndroid Build Coastguard Worker ALOGE("Waitpid of \"%s\" failed with error %s", exe, 90*e1eccf28SAndroid Build Coastguard Worker strerror(errno)); 91*e1eccf28SAndroid Build Coastguard Worker return false; 92*e1eccf28SAndroid Build Coastguard Worker } 93*e1eccf28SAndroid Build Coastguard Worker 94*e1eccf28SAndroid Build Coastguard Worker if (WIFEXITED(status) && WEXITSTATUS(status) == 0) { 95*e1eccf28SAndroid Build Coastguard Worker return true; 96*e1eccf28SAndroid Build Coastguard Worker } 97*e1eccf28SAndroid Build Coastguard Worker 98*e1eccf28SAndroid Build Coastguard Worker ALOGE("Child process \"%s\" terminated with status %d", exe, status); 99*e1eccf28SAndroid Build Coastguard Worker return false; 100*e1eccf28SAndroid Build Coastguard Worker } 101*e1eccf28SAndroid Build Coastguard Worker } 102*e1eccf28SAndroid Build Coastguard Worker } 103*e1eccf28SAndroid Build Coastguard Worker #endif // RS_COMPATIBILITY_LIB 104*e1eccf28SAndroid Build Coastguard Worker 105*e1eccf28SAndroid Build Coastguard Worker // Implementation of property_get from libcutils 106*e1eccf28SAndroid Build Coastguard Worker int property_get(const char *key, char *value, const char *default_value) { 107*e1eccf28SAndroid Build Coastguard Worker int len; 108*e1eccf28SAndroid Build Coastguard Worker len = __system_property_get(key, value); 109*e1eccf28SAndroid Build Coastguard Worker if (len > 0) { 110*e1eccf28SAndroid Build Coastguard Worker return len; 111*e1eccf28SAndroid Build Coastguard Worker } 112*e1eccf28SAndroid Build Coastguard Worker 113*e1eccf28SAndroid Build Coastguard Worker if (default_value) { 114*e1eccf28SAndroid Build Coastguard Worker len = strlen(default_value); 115*e1eccf28SAndroid Build Coastguard Worker memcpy(value, default_value, len + 1); 116*e1eccf28SAndroid Build Coastguard Worker } 117*e1eccf28SAndroid Build Coastguard Worker return len; 118*e1eccf28SAndroid Build Coastguard Worker } 119*e1eccf28SAndroid Build Coastguard Worker 120*e1eccf28SAndroid Build Coastguard Worker } // namespace renderscript 121*e1eccf28SAndroid Build Coastguard Worker } // namespace android 122