Ensure that the cache directory exists before calling compiler.

Bug: 7077014
Change-Id: Iab94a265193d4ff749573520939c974a982ac7c1
diff --git a/rsScriptC.cpp b/rsScriptC.cpp
index 466c18a..b291045 100644
--- a/rsScriptC.cpp
+++ b/rsScriptC.cpp
@@ -24,6 +24,8 @@
 #include <bcinfo/BitcodeWrapper.h>
 #endif
 
+#include <sys/stat.h>
+
 using namespace android;
 using namespace android::renderscript;
 
@@ -51,6 +53,43 @@
     }
 }
 
+bool ScriptC::createCacheDir(const char *cacheDir) {
+    String8 cacheDirString, currentDir;
+    struct stat statBuf;
+    int statReturn = stat(cacheDir, &statBuf);
+    if (!statReturn) {
+        return true;
+    }
+
+    // String8 path functions strip leading /'s
+    // insert if necessary
+    if (cacheDir[0] == '/') {
+        currentDir += "/";
+    }
+
+    cacheDirString.setPathName(cacheDir);
+
+    while (cacheDirString.length()) {
+        currentDir += (cacheDirString.walkPath(&cacheDirString));
+        statReturn = stat(currentDir.string(), &statBuf);
+        if (statReturn) {
+            if (errno == ENOENT) {
+                if (mkdir(currentDir.string(), S_IRUSR | S_IWUSR | S_IXUSR)) {
+                    ALOGE("Couldn't create cache directory: %s",
+                          currentDir.string());
+                    ALOGE("Error: %s", strerror(errno));
+                    return false;
+                }
+            } else {
+                ALOGE("Stat error: %s", strerror(errno));
+                return false;
+            }
+        }
+        currentDir += "/";
+    }
+    return true;
+}
+
 void ScriptC::setupScript(Context *rsc) {
     mEnviroment.mStartTimeMillis
                 = nanoseconds_to_milliseconds(systemTime(SYSTEM_TIME_MONOTONIC));
@@ -211,6 +250,11 @@
     bitcodeLen = BT->getTranslatedBitcodeSize();
 #endif
 
+    // ensure that cache dir exists
+    if (!createCacheDir(cacheDir)) {
+      return false;
+    }
+
     if (!rsc->mHal.funcs.script.init(rsc, this, resName, cacheDir, bitcode, bitcodeLen, 0)) {
         return false;
     }