rsCppUtils.cpp revision f5ffbf2b8c885a4fc7c34812ab33ddb16dc56325
172961230a5890071bcca436eb5630172ce84ec41Andreas Huber/*
272961230a5890071bcca436eb5630172ce84ec41Andreas Huber * Copyright (C) 2013 The Android Open Source Project
372961230a5890071bcca436eb5630172ce84ec41Andreas Huber *
472961230a5890071bcca436eb5630172ce84ec41Andreas Huber * Licensed under the Apache License, Version 2.0 (the "License");
572961230a5890071bcca436eb5630172ce84ec41Andreas Huber * you may not use this file except in compliance with the License.
672961230a5890071bcca436eb5630172ce84ec41Andreas Huber * You may obtain a copy of the License at
772961230a5890071bcca436eb5630172ce84ec41Andreas Huber *
872961230a5890071bcca436eb5630172ce84ec41Andreas Huber *      http://www.apache.org/licenses/LICENSE-2.0
972961230a5890071bcca436eb5630172ce84ec41Andreas Huber *
1072961230a5890071bcca436eb5630172ce84ec41Andreas Huber * Unless required by applicable law or agreed to in writing, software
1172961230a5890071bcca436eb5630172ce84ec41Andreas Huber * distributed under the License is distributed on an "AS IS" BASIS,
1272961230a5890071bcca436eb5630172ce84ec41Andreas Huber * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1372961230a5890071bcca436eb5630172ce84ec41Andreas Huber * See the License for the specific language governing permissions and
1472961230a5890071bcca436eb5630172ce84ec41Andreas Huber * limitations under the License.
1572961230a5890071bcca436eb5630172ce84ec41Andreas Huber */
1672961230a5890071bcca436eb5630172ce84ec41Andreas Huber
1772961230a5890071bcca436eb5630172ce84ec41Andreas Huber#include "rsUtils.h"
1872961230a5890071bcca436eb5630172ce84ec41Andreas Huber#include "rsCppUtils.h"
1972961230a5890071bcca436eb5630172ce84ec41Andreas Huber
2072961230a5890071bcca436eb5630172ce84ec41Andreas Huber#include <string>
2172961230a5890071bcca436eb5630172ce84ec41Andreas Huber
2272961230a5890071bcca436eb5630172ce84ec41Andreas Huber#include <string.h>
23f09611f2f33752afc28141e1bbaa897651c05d6fMarco Nelissen
2472961230a5890071bcca436eb5630172ce84ec41Andreas Huber#ifndef RS_COMPATIBILITY_LIB
2572961230a5890071bcca436eb5630172ce84ec41Andreas Huber#include <sys/wait.h>
2672961230a5890071bcca436eb5630172ce84ec41Andreas Huber#endif
2772961230a5890071bcca436eb5630172ce84ec41Andreas Huber
2872961230a5890071bcca436eb5630172ce84ec41Andreas Huber#include <unistd.h>
2972961230a5890071bcca436eb5630172ce84ec41Andreas Huber
3072961230a5890071bcca436eb5630172ce84ec41Andreas Hubernamespace android {
3140d8899f60c5212af9d727ba0ffaaecf676ebd1dChih-Hung Hsiehnamespace renderscript {
3272961230a5890071bcca436eb5630172ce84ec41Andreas Huber
3372961230a5890071bcca436eb5630172ce84ec41Andreas Huberconst char * rsuCopyString(const char *name) {
3430873bfd08255e2c4e98ff5732ffff2838772617Andreas Huber    return rsuCopyString(name, strlen(name));
3572961230a5890071bcca436eb5630172ce84ec41Andreas Huber}
36f09611f2f33752afc28141e1bbaa897651c05d6fMarco Nelissen
37f09611f2f33752afc28141e1bbaa897651c05d6fMarco Nelissenconst char * rsuCopyString(const char *name, size_t len) {
3872961230a5890071bcca436eb5630172ce84ec41Andreas Huber    char *n = new char[len+1];
3972961230a5890071bcca436eb5630172ce84ec41Andreas Huber    memcpy(n, name, len);
4011cc270ac5fd522c9e6491a7933516a96da4f62eAndreas Huber    n[len] = 0;
4111cc270ac5fd522c9e6491a7933516a96da4f62eAndreas Huber    return n;
4272961230a5890071bcca436eb5630172ce84ec41Andreas Huber}
4372961230a5890071bcca436eb5630172ce84ec41Andreas Huber
4472961230a5890071bcca436eb5630172ce84ec41Andreas Huberconst char* rsuJoinStrings(int n, const char* const* strs) {
4572961230a5890071bcca436eb5630172ce84ec41Andreas Huber    std::string tmp;
4672961230a5890071bcca436eb5630172ce84ec41Andreas Huber    for (int i = 0; i < n; i++) {
475df775d2f509c76e76a46615fca83dba95299f6eAndreas Huber        if (i > 0) {
4872961230a5890071bcca436eb5630172ce84ec41Andreas Huber            tmp.append(" ");
4972961230a5890071bcca436eb5630172ce84ec41Andreas Huber        }
5072961230a5890071bcca436eb5630172ce84ec41Andreas Huber        tmp.append(strs[i]);
5172961230a5890071bcca436eb5630172ce84ec41Andreas Huber    }
5272961230a5890071bcca436eb5630172ce84ec41Andreas Huber    return strndup(tmp.c_str(), tmp.size());
5372961230a5890071bcca436eb5630172ce84ec41Andreas Huber}
54
55#ifndef RS_COMPATIBILITY_LIB
56bool rsuExecuteCommand(const char *exe, int nArgs, const char * const *args) {
57    std::unique_ptr<const char> joined(rsuJoinStrings(nArgs, args));
58    ALOGV("Invoking %s with args '%s'", exe, joined.get());
59
60    pid_t pid = fork();
61
62    switch (pid) {
63    case -1: {  // Error occurred (we attempt no recovery)
64        ALOGE("Fork of \"%s\" failed with error %s", exe, strerror(errno));
65        return false;
66    }
67    case 0: {  // Child process
68        // No (direct or indirect) call to malloc between fork and exec.  It is
69        // possible that a different thread holds the heap lock before the fork.
70
71        // ProcessManager in libcore can reap unclaimed SIGCHLDs in its process
72        // group.  To ensure that the exit signal is not caught by
73        // ProcessManager and instead sent to libRS, set the child's PGID to its
74        // PID.
75        setpgid(0, 0);
76
77        execv(exe, (char * const *)args);
78
79        ALOGE("execv() failed: %s", strerror(errno));
80        abort();
81        return false;
82    }
83    default: {  // Parent process (actual driver)
84        // Wait on child process to finish execution.
85        int status = 0;
86        pid_t w = TEMP_FAILURE_RETRY(waitpid(pid, &status, 0));
87        if (w == -1) {
88            ALOGE("Waitpid of \"%s\" failed with error %s", exe,
89                  strerror(errno));
90            return false;
91        }
92
93        if (WIFEXITED(status) && WEXITSTATUS(status) == 0) {
94            return true;
95        }
96
97        ALOGE("Child process \"%s\" terminated with status %d", exe, status);
98        return false;
99    }
100    }
101}
102#endif // RS_COMPATIBILITY_LIB
103
104}
105}
106