xref: /aosp_15_r20/frameworks/rs/rsCppUtils.cpp (revision e1eccf28f96817838ad6867f7f39d2351ec11f56)
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