+bool IsDir(std::string path)
+{
+ struct stat statbuf;
+ if(stat(path.c_str(), &statbuf))
+ return false; // Actually error; but certainly not a directory
+ return ((statbuf.st_mode & S_IFDIR) == S_IFDIR);
+}
+
+bool IsDirDelimiter(char c)
+{
+ return c == '/';
+}
+
+bool RecursiveDelete(std::string path)
+{
+ /*
+ Execute the 'rm' command directly, by fork() and execve()
+ */
+
+ infostream<<"Removing \""<<path<<"\""<<std::endl;
+
+ //return false;
+
+ pid_t child_pid = fork();
+
+ if(child_pid == 0)
+ {
+ // Child
+ char argv_data[3][10000];
+ strcpy(argv_data[0], "/bin/rm");
+ strcpy(argv_data[1], "-rf");
+ strncpy(argv_data[2], path.c_str(), 10000);
+ char *argv[4];
+ argv[0] = argv_data[0];
+ argv[1] = argv_data[1];
+ argv[2] = argv_data[2];
+ argv[3] = NULL;
+
+ verbosestream<<"Executing '"<<argv[0]<<"' '"<<argv[1]<<"' '"
+ <<argv[2]<<"'"<<std::endl;
+
+ execv(argv[0], argv);
+
+ // Execv shouldn't return. Failed.
+ _exit(1);
+ }
+ else
+ {
+ // Parent
+ int child_status;
+ pid_t tpid;
+ do{
+ tpid = wait(&child_status);
+ //if(tpid != child_pid) process_terminated(tpid);
+ }while(tpid != child_pid);
+ return (child_status == 0);
+ }
+}
+
+bool DeleteSingleFileOrEmptyDirectory(std::string path)
+{
+ if(IsDir(path)){
+ bool did = (rmdir(path.c_str()) == 0);
+ if(!did)
+ errorstream<<"rmdir errno: "<<errno<<": "<<strerror(errno)
+ <<std::endl;
+ return did;
+ } else {
+ bool did = (unlink(path.c_str()) == 0);
+ if(!did)
+ errorstream<<"unlink errno: "<<errno<<": "<<strerror(errno)
+ <<std::endl;
+ return did;
+ }
+}
+
+std::string TempPath()
+{
+ /*
+ Should the environment variables TMPDIR, TMP and TEMP
+ and the macro P_tmpdir (if defined by stdio.h) be checked
+ before falling back on /tmp?
+
+ Probably not, because this function is intended to be
+ compatible with lua's os.tmpname which under the default
+ configuration hardcodes mkstemp("/tmp/lua_XXXXXX").
+ */
+#ifdef __ANDROID__
+ return DIR_DELIM "sdcard" DIR_DELIM PROJECT_NAME DIR_DELIM "tmp";