]> git.mxchange.org Git - flightgear.git/blobdiff - src/Main/fg_init.cxx
Environment manager: use aircraft_pos helper
[flightgear.git] / src / Main / fg_init.cxx
index 8ad9803f9be9c1de0270c8c76838b9406603b6db..8905a6a1deef0cbcaaaebbacf9c01c66498fb193 100644 (file)
 #  include <config.h>
 #endif
 
+#include <simgear/compiler.h>
+
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>             // strcmp()
 
-#ifdef _WIN32
+#if defined(SG_WINDOWS)
 #  include <io.h>               // isatty()
+#  include <process.h>          // _getpid()
+#  include <Windows.h>
 #  define isatty _isatty
+#else
+// for open() and options
+#  include <sys/types.h>        
+#  include <sys/stat.h>
+#  include <fcntl.h>
 #endif
 
-#include <simgear/compiler.h>
-
 #include <string>
 #include <boost/algorithm/string/compare.hpp>
 #include <boost/algorithm/string/predicate.hpp>
 #include "positioninit.hxx"
 #include "util.hxx"
 
+#if defined(SG_MAC)
+#include <GUI/CocoaHelpers.h> // for Mac impl of platformDefaultDataPath()
+#endif
+
 using std::string;
 using std::endl;
 using std::cerr;
@@ -379,27 +390,10 @@ static SGPath platformDefaultDataPath()
   return config;
 }
 
-#elif __APPLE__
-#include <CoreServices/CoreServices.h>
+#elif defined(SG_MAC)
 
-static SGPath platformDefaultDataPath()
-{
-  FSRef ref;
-  OSErr err = FSFindFolder(kUserDomain, kApplicationSupportFolderType, false, &ref);
-  if (err) {
-    return SGPath();
-  }
-
-  unsigned char path[1024];
-  if (FSRefMakePath(&ref, path, 1024) != noErr) {
-    return SGPath();
-  }
+// platformDefaultDataPath defined in GUI/CocoaHelpers.h
 
-  SGPath appData;
-  appData.set((const char*) path);
-  appData.append("FlightGear");
-  return appData;
-}
 #else
 static SGPath platformDefaultDataPath()
 {
@@ -407,7 +401,7 @@ static SGPath platformDefaultDataPath()
 }
 #endif
 
-void fgInitHome()
+bool fgInitHome()
 {
   SGPath dataPath = SGPath::fromEnv("FG_HOME", platformDefaultDataPath());
   globals->set_fg_home(dataPath.c_str());
@@ -416,6 +410,66 @@ void fgInitHome()
     if (!fgHome.exists()) {
         fgHome.create(0755);
     }
+    
+    if (!fgHome.exists()) {
+        flightgear::fatalMessageBox("Problem setting up user data",
+                                    "Unable to create the user-data storage folder at: '"
+                                    + dataPath.str() + "'");
+        return false;
+    }
+    
+    if (fgGetBool("/sim/fghome-readonly", false)) {
+        // user / config forced us into readonly mode, fine
+        SG_LOG(SG_GENERAL, SG_INFO, "Running with FG_HOME readonly");
+        return true;
+    }
+    
+// write our PID, and check writeability
+    SGPath pidPath(dataPath, "fgfs.pid");
+    if (pidPath.exists()) {
+        SG_LOG(SG_GENERAL, SG_INFO, "flightgear instance already running, switching to FG_HOME read-only.");
+        // set a marker property so terrasync/navcache don't try to write
+        // from secondary instances
+        fgSetBool("/sim/fghome-readonly", true);
+        return true;
+    }
+    
+    char buf[16];
+    bool result = false;
+#if defined(SG_WINDOWS)
+    size_t len = snprintf(buf, 16, "%d", _getpid());
+
+    HANDLE f = CreateFileA(pidPath.c_str(), GENERIC_READ | GENERIC_WRITE, 
+                                                  FILE_SHARE_READ, /* sharing */
+                           NULL, /* security attributes */
+                           CREATE_NEW, /* error if already exists */
+                           FILE_FLAG_DELETE_ON_CLOSE,
+                                                  NULL /* template */);
+    
+    result = (f != INVALID_HANDLE_VALUE);
+    if (result) {
+               DWORD written;
+        WriteFile(f, buf, len, &written, NULL /* overlapped */);
+    }
+#else
+    // POSIX, do open+unlink trick to the file is deleted on exit, even if we
+    // crash or exit(-1)
+    size_t len = snprintf(buf, 16, "%d", getpid());
+    int fd = ::open(pidPath.c_str(), O_WRONLY | O_CREAT | O_TRUNC | O_EXCL, 0644);
+    if (fd >= 0) {
+        ::write(fd, buf, len);
+        ::unlink(pidPath.c_str()); // delete file when app quits
+        result = true;
+    }
+    
+    fgSetBool("/sim/fghome-readonly", false);
+#endif
+    if (!result) {
+        flightgear::fatalMessageBox("File permissions problem",
+                                    "Can't write to user-data storage folder, check file permissions and FG_HOME.",
+                                    "User-data at:" + dataPath.str());
+    }
+    return result;
 }
 
 // Read in configuration (file and command line)