aboutsummaryrefslogtreecommitdiff
path: root/backends/fs/posix/posix-fs.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'backends/fs/posix/posix-fs.cpp')
-rw-r--r--backends/fs/posix/posix-fs.cpp89
1 files changed, 89 insertions, 0 deletions
diff --git a/backends/fs/posix/posix-fs.cpp b/backends/fs/posix/posix-fs.cpp
index 4baf9f14fe..b38a07637c 100644
--- a/backends/fs/posix/posix-fs.cpp
+++ b/backends/fs/posix/posix-fs.cpp
@@ -38,6 +38,8 @@
#include <sys/stat.h>
#include <dirent.h>
#include <stdio.h>
+#include <errno.h>
+#include <fcntl.h>
#ifdef __OS2__
#define INCL_DOS
@@ -251,4 +253,91 @@ Common::WriteStream *POSIXFilesystemNode::createWriteStream() {
return StdioStream::makeFromPath(getPath(), true);
}
+bool POSIXFilesystemNode::create(bool isDirectory) {
+ bool success;
+
+ if (isDirectory) {
+ success = mkdir(_path.c_str(), 0755) == 0;
+ } else {
+ success = creat(_path.c_str(), 0755) != -1;
+ }
+
+ if (success) {
+ setFlags();
+ if (_isValid) {
+ if (_isDirectory != isDirectory) warning("failed to create %s: got %s", isDirectory ? "directory" : "file", _isDirectory ? "directory" : "file");
+ return _isDirectory == isDirectory;
+ }
+
+ warning("POSIXFilesystemNode: %s() was a success, but stat indicates there is no such %s",
+ isDirectory ? "mkdir" : "creat", isDirectory ? "directory" : "file");
+ return false;
+ }
+
+ return false;
+}
+
+namespace Posix {
+
+bool assureDirectoryExists(const Common::String &dir, const char *prefix) {
+ struct stat sb;
+
+ // Check whether the prefix exists if one is supplied.
+ if (prefix) {
+ if (stat(prefix, &sb) != 0) {
+ return false;
+ } else if (!S_ISDIR(sb.st_mode)) {
+ return false;
+ }
+ }
+
+ // Obtain absolute path.
+ Common::String path;
+ if (prefix) {
+ path = prefix;
+ path += '/';
+ path += dir;
+ } else {
+ path = dir;
+ }
+
+ path = Common::normalizePath(path, '/');
+
+ const Common::String::iterator end = path.end();
+ Common::String::iterator cur = path.begin();
+ if (*cur == '/')
+ ++cur;
+
+ do {
+ if (cur + 1 != end) {
+ if (*cur != '/') {
+ continue;
+ }
+
+ // It is kind of ugly and against the purpose of Common::String to
+ // insert 0s inside, but this is just for a local string and
+ // simplifies the code a lot.
+ *cur = '\0';
+ }
+
+ if (mkdir(path.c_str(), 0755) != 0) {
+ if (errno == EEXIST) {
+ if (stat(path.c_str(), &sb) != 0) {
+ return false;
+ } else if (!S_ISDIR(sb.st_mode)) {
+ return false;
+ }
+ } else {
+ return false;
+ }
+ }
+
+ *cur = '/';
+ } while (cur++ != end);
+
+ return true;
+}
+
+} // End of namespace Posix
+
#endif //#if defined(POSIX)