1f313dc32d5ea68a7c48fb4ec6e131ec2fb97ce2dJason Sams/*
2f313dc32d5ea68a7c48fb4ec6e131ec2fb97ce2dJason Sams * Copyright (C) 2013 The Android Open Source Project
3f313dc32d5ea68a7c48fb4ec6e131ec2fb97ce2dJason Sams *
4f313dc32d5ea68a7c48fb4ec6e131ec2fb97ce2dJason Sams * Licensed under the Apache License, Version 2.0 (the "License");
5f313dc32d5ea68a7c48fb4ec6e131ec2fb97ce2dJason Sams * you may not use this file except in compliance with the License.
6f313dc32d5ea68a7c48fb4ec6e131ec2fb97ce2dJason Sams * You may obtain a copy of the License at
7f313dc32d5ea68a7c48fb4ec6e131ec2fb97ce2dJason Sams *
8f313dc32d5ea68a7c48fb4ec6e131ec2fb97ce2dJason Sams *      http://www.apache.org/licenses/LICENSE-2.0
9f313dc32d5ea68a7c48fb4ec6e131ec2fb97ce2dJason Sams *
10f313dc32d5ea68a7c48fb4ec6e131ec2fb97ce2dJason Sams * Unless required by applicable law or agreed to in writing, software
11f313dc32d5ea68a7c48fb4ec6e131ec2fb97ce2dJason Sams * distributed under the License is distributed on an "AS IS" BASIS,
12f313dc32d5ea68a7c48fb4ec6e131ec2fb97ce2dJason Sams * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13f313dc32d5ea68a7c48fb4ec6e131ec2fb97ce2dJason Sams * See the License for the specific language governing permissions and
14f313dc32d5ea68a7c48fb4ec6e131ec2fb97ce2dJason Sams * limitations under the License.
15f313dc32d5ea68a7c48fb4ec6e131ec2fb97ce2dJason Sams */
16f313dc32d5ea68a7c48fb4ec6e131ec2fb97ce2dJason Sams
17574854bcb2eb25a85b9b52faf2fb3e743fa7aa14Stephen Hines#include "rsUtils.h"
18f313dc32d5ea68a7c48fb4ec6e131ec2fb97ce2dJason Sams#include "rsCppUtils.h"
19f313dc32d5ea68a7c48fb4ec6e131ec2fb97ce2dJason Sams
208c1177be9bd7175979e970a066474bc6f258ba48Dan Albert#include <errno.h>
218c1177be9bd7175979e970a066474bc6f258ba48Dan Albert#include <string.h>
222a61168a777ee434ce2c28945aa74f6a6bcf2820Miao Wang#include <unistd.h>
232abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni
248c1177be9bd7175979e970a066474bc6f258ba48Dan Albert#include <string>
258c1177be9bd7175979e970a066474bc6f258ba48Dan Albert
262fa8a238dd69afebdeb757adcb1d674043d78e32Pirama Arumuga Nainar#ifndef RS_COMPATIBILITY_LIB
272fa8a238dd69afebdeb757adcb1d674043d78e32Pirama Arumuga Nainar#include <sys/wait.h>
282fa8a238dd69afebdeb757adcb1d674043d78e32Pirama Arumuga Nainar#endif
292fa8a238dd69afebdeb757adcb1d674043d78e32Pirama Arumuga Nainar
30f5ffbf2b8c885a4fc7c34812ab33ddb16dc56325Mark Salyzyn
31f313dc32d5ea68a7c48fb4ec6e131ec2fb97ce2dJason Samsnamespace android {
32f313dc32d5ea68a7c48fb4ec6e131ec2fb97ce2dJason Samsnamespace renderscript {
33f313dc32d5ea68a7c48fb4ec6e131ec2fb97ce2dJason Sams
34f313dc32d5ea68a7c48fb4ec6e131ec2fb97ce2dJason Samsconst char * rsuCopyString(const char *name) {
35f313dc32d5ea68a7c48fb4ec6e131ec2fb97ce2dJason Sams    return rsuCopyString(name, strlen(name));
36f313dc32d5ea68a7c48fb4ec6e131ec2fb97ce2dJason Sams}
37f313dc32d5ea68a7c48fb4ec6e131ec2fb97ce2dJason Sams
38f313dc32d5ea68a7c48fb4ec6e131ec2fb97ce2dJason Samsconst char * rsuCopyString(const char *name, size_t len) {
39f313dc32d5ea68a7c48fb4ec6e131ec2fb97ce2dJason Sams    char *n = new char[len+1];
40f313dc32d5ea68a7c48fb4ec6e131ec2fb97ce2dJason Sams    memcpy(n, name, len);
41f313dc32d5ea68a7c48fb4ec6e131ec2fb97ce2dJason Sams    n[len] = 0;
42f313dc32d5ea68a7c48fb4ec6e131ec2fb97ce2dJason Sams    return n;
43f313dc32d5ea68a7c48fb4ec6e131ec2fb97ce2dJason Sams}
44f313dc32d5ea68a7c48fb4ec6e131ec2fb97ce2dJason Sams
452abfcc6d129fe3defddef4540aa95cc445c03a7aYang Niconst char* rsuJoinStrings(int n, const char* const* strs) {
462abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni    std::string tmp;
472abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni    for (int i = 0; i < n; i++) {
482abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni        if (i > 0) {
492abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni            tmp.append(" ");
502abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni        }
512abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni        tmp.append(strs[i]);
522abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni    }
532abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni    return strndup(tmp.c_str(), tmp.size());
542abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni}
55f313dc32d5ea68a7c48fb4ec6e131ec2fb97ce2dJason Sams
562fa8a238dd69afebdeb757adcb1d674043d78e32Pirama Arumuga Nainar#ifndef RS_COMPATIBILITY_LIB
572fa8a238dd69afebdeb757adcb1d674043d78e32Pirama Arumuga Nainarbool rsuExecuteCommand(const char *exe, int nArgs, const char * const *args) {
582fa8a238dd69afebdeb757adcb1d674043d78e32Pirama Arumuga Nainar    std::unique_ptr<const char> joined(rsuJoinStrings(nArgs, args));
597b29f5a5f75b1a8d830a14c6c5ae9bcb7d0b3ca4Pirama Arumuga Nainar    ALOGV("Invoking %s with args '%s'", exe, joined.get());
602fa8a238dd69afebdeb757adcb1d674043d78e32Pirama Arumuga Nainar
612fa8a238dd69afebdeb757adcb1d674043d78e32Pirama Arumuga Nainar    pid_t pid = fork();
622fa8a238dd69afebdeb757adcb1d674043d78e32Pirama Arumuga Nainar
632fa8a238dd69afebdeb757adcb1d674043d78e32Pirama Arumuga Nainar    switch (pid) {
642fa8a238dd69afebdeb757adcb1d674043d78e32Pirama Arumuga Nainar    case -1: {  // Error occurred (we attempt no recovery)
652fa8a238dd69afebdeb757adcb1d674043d78e32Pirama Arumuga Nainar        ALOGE("Fork of \"%s\" failed with error %s", exe, strerror(errno));
662fa8a238dd69afebdeb757adcb1d674043d78e32Pirama Arumuga Nainar        return false;
672fa8a238dd69afebdeb757adcb1d674043d78e32Pirama Arumuga Nainar    }
682fa8a238dd69afebdeb757adcb1d674043d78e32Pirama Arumuga Nainar    case 0: {  // Child process
697b29f5a5f75b1a8d830a14c6c5ae9bcb7d0b3ca4Pirama Arumuga Nainar        // No (direct or indirect) call to malloc between fork and exec.  It is
707b29f5a5f75b1a8d830a14c6c5ae9bcb7d0b3ca4Pirama Arumuga Nainar        // possible that a different thread holds the heap lock before the fork.
7190ea8d33a7fd9a64dd68ef7ebccf595b8eb1dd68Pirama Arumuga Nainar
7290ea8d33a7fd9a64dd68ef7ebccf595b8eb1dd68Pirama Arumuga Nainar        // ProcessManager in libcore can reap unclaimed SIGCHLDs in its process
7390ea8d33a7fd9a64dd68ef7ebccf595b8eb1dd68Pirama Arumuga Nainar        // group.  To ensure that the exit signal is not caught by
7490ea8d33a7fd9a64dd68ef7ebccf595b8eb1dd68Pirama Arumuga Nainar        // ProcessManager and instead sent to libRS, set the child's PGID to its
7590ea8d33a7fd9a64dd68ef7ebccf595b8eb1dd68Pirama Arumuga Nainar        // PID.
7690ea8d33a7fd9a64dd68ef7ebccf595b8eb1dd68Pirama Arumuga Nainar        setpgid(0, 0);
7790ea8d33a7fd9a64dd68ef7ebccf595b8eb1dd68Pirama Arumuga Nainar
782fa8a238dd69afebdeb757adcb1d674043d78e32Pirama Arumuga Nainar        execv(exe, (char * const *)args);
792fa8a238dd69afebdeb757adcb1d674043d78e32Pirama Arumuga Nainar
802fa8a238dd69afebdeb757adcb1d674043d78e32Pirama Arumuga Nainar        ALOGE("execv() failed: %s", strerror(errno));
812fa8a238dd69afebdeb757adcb1d674043d78e32Pirama Arumuga Nainar        abort();
822fa8a238dd69afebdeb757adcb1d674043d78e32Pirama Arumuga Nainar        return false;
832fa8a238dd69afebdeb757adcb1d674043d78e32Pirama Arumuga Nainar    }
842fa8a238dd69afebdeb757adcb1d674043d78e32Pirama Arumuga Nainar    default: {  // Parent process (actual driver)
852fa8a238dd69afebdeb757adcb1d674043d78e32Pirama Arumuga Nainar        // Wait on child process to finish execution.
862fa8a238dd69afebdeb757adcb1d674043d78e32Pirama Arumuga Nainar        int status = 0;
872fa8a238dd69afebdeb757adcb1d674043d78e32Pirama Arumuga Nainar        pid_t w = TEMP_FAILURE_RETRY(waitpid(pid, &status, 0));
882fa8a238dd69afebdeb757adcb1d674043d78e32Pirama Arumuga Nainar        if (w == -1) {
892fa8a238dd69afebdeb757adcb1d674043d78e32Pirama Arumuga Nainar            ALOGE("Waitpid of \"%s\" failed with error %s", exe,
902fa8a238dd69afebdeb757adcb1d674043d78e32Pirama Arumuga Nainar                  strerror(errno));
912fa8a238dd69afebdeb757adcb1d674043d78e32Pirama Arumuga Nainar            return false;
922fa8a238dd69afebdeb757adcb1d674043d78e32Pirama Arumuga Nainar        }
932fa8a238dd69afebdeb757adcb1d674043d78e32Pirama Arumuga Nainar
942fa8a238dd69afebdeb757adcb1d674043d78e32Pirama Arumuga Nainar        if (WIFEXITED(status) && WEXITSTATUS(status) == 0) {
952fa8a238dd69afebdeb757adcb1d674043d78e32Pirama Arumuga Nainar            return true;
962fa8a238dd69afebdeb757adcb1d674043d78e32Pirama Arumuga Nainar        }
972fa8a238dd69afebdeb757adcb1d674043d78e32Pirama Arumuga Nainar
982fa8a238dd69afebdeb757adcb1d674043d78e32Pirama Arumuga Nainar        ALOGE("Child process \"%s\" terminated with status %d", exe, status);
992fa8a238dd69afebdeb757adcb1d674043d78e32Pirama Arumuga Nainar        return false;
1002fa8a238dd69afebdeb757adcb1d674043d78e32Pirama Arumuga Nainar    }
1012fa8a238dd69afebdeb757adcb1d674043d78e32Pirama Arumuga Nainar    }
1022fa8a238dd69afebdeb757adcb1d674043d78e32Pirama Arumuga Nainar}
1032fa8a238dd69afebdeb757adcb1d674043d78e32Pirama Arumuga Nainar#endif // RS_COMPATIBILITY_LIB
1042fa8a238dd69afebdeb757adcb1d674043d78e32Pirama Arumuga Nainar
1052a61168a777ee434ce2c28945aa74f6a6bcf2820Miao Wang// Implementation of property_get from libcutils
1062a61168a777ee434ce2c28945aa74f6a6bcf2820Miao Wangint property_get(const char *key, char *value, const char *default_value) {
1072a61168a777ee434ce2c28945aa74f6a6bcf2820Miao Wang    int len;
1082a61168a777ee434ce2c28945aa74f6a6bcf2820Miao Wang    len = __system_property_get(key, value);
1092a61168a777ee434ce2c28945aa74f6a6bcf2820Miao Wang    if (len > 0) {
1102a61168a777ee434ce2c28945aa74f6a6bcf2820Miao Wang        return len;
1112a61168a777ee434ce2c28945aa74f6a6bcf2820Miao Wang    }
1122a61168a777ee434ce2c28945aa74f6a6bcf2820Miao Wang
1132a61168a777ee434ce2c28945aa74f6a6bcf2820Miao Wang    if (default_value) {
1142a61168a777ee434ce2c28945aa74f6a6bcf2820Miao Wang        len = strlen(default_value);
1152a61168a777ee434ce2c28945aa74f6a6bcf2820Miao Wang        memcpy(value, default_value, len + 1);
1162a61168a777ee434ce2c28945aa74f6a6bcf2820Miao Wang    }
1172a61168a777ee434ce2c28945aa74f6a6bcf2820Miao Wang    return len;
1182a61168a777ee434ce2c28945aa74f6a6bcf2820Miao Wang}
1192a61168a777ee434ce2c28945aa74f6a6bcf2820Miao Wang
1207974fc03e11f3a8dd40f794f3b33b4889483090cRahul Chaudhry} // namespace renderscript
1217974fc03e11f3a8dd40f794f3b33b4889483090cRahul Chaudhry} // namespace android
122