Quellcode durchsuchen

Filesystem class also captures stderr when executing console command.
Turn on SDL filesystem support for Linux platform.

Yao Wei Tjong 姚伟忠 vor 11 Jahren
Ursprung
Commit
cea3743ea7
2 geänderte Dateien mit 40 neuen und 8 gelöschten Zeilen
  1. 37 8
      Source/Engine/IO/FileSystem.cpp
  2. 3 0
      Source/ThirdParty/SDL/include/SDL_config_linux.h

+ 37 - 8
Source/Engine/IO/FileSystem.cpp

@@ -31,6 +31,8 @@
 #include "Log.h"
 #include "Thread.h"
 
+#include <SDL_filesystem.h>
+
 #include <cstdio>
 #include <cstring>
 
@@ -67,27 +69,54 @@ extern "C" const char* SDL_IOS_GetResourceDir();
 namespace Urho3D
 {
 
-int DoSystemCommand(const String& commandLine, bool redirectStdOutToLog)
+int DoSystemCommand(const String& commandLine, bool redirectToLog, Context* context)
 {
-    if (!redirectStdOutToLog)
+    if (!redirectToLog)
         return system(commandLine.CString());
 
+    // Get a platform-agnostic temporary file name for stderr redirection
+    String stderrFilename;
+    String adjustedCommandLine(commandLine);
+    char* prefPath = SDL_GetPrefPath("urho3d", "Urho3D");
+    if (prefPath)
+    {
+        stderrFilename = String(prefPath) + "command-stderr";
+        adjustedCommandLine += " 2>" + stderrFilename;
+        SDL_free(prefPath);
+    }
+
     #ifdef _MSC_VER
     #define popen _popen
     #define pclose _pclose
     #endif
 
-    // Use popen/pclose to capture the stdout of the command
-    FILE *file = popen(commandLine.CString(), "r");
+    // Use popen/pclose to capture the stdout and stderr of the command
+    FILE *file = popen(adjustedCommandLine.CString(), "r");
     if (!file)
         return -1;
+
+    // Capture the standard output stream
     char buffer[128];
     while (!feof(file))
     {
-        if (fgets(buffer, 128, file))
+        if (fgets(buffer, sizeof(buffer), file))
             LOGRAW(String(buffer));
     }
-    return pclose(file);
+    int exitCode = pclose(file);
+
+    // Capture the standard error stream
+    if (!stderrFilename.Empty())
+    {
+        SharedPtr<File> errFile(new File(context, stderrFilename, FILE_READ));
+        while (!errFile->IsEof())
+        {
+            unsigned numRead = errFile->Read(buffer, sizeof(buffer));
+            if (numRead)
+                Log::WriteRaw(String(buffer, numRead), true);
+        }
+    }
+
+    return exitCode;
 }
 
 int DoSystemRun(const String& fileName, const Vector<String>& arguments)
@@ -190,7 +219,7 @@ public:
     /// The function to run in the thread.
     virtual void ThreadFunction()
     {
-        exitCode_ = DoSystemCommand(commandLine_, false);
+        exitCode_ = DoSystemCommand(commandLine_, false, 0);
         completed_ = true;
     }
     
@@ -311,7 +340,7 @@ void FileSystem::SetExecuteConsoleCommands(bool enable)
 int FileSystem::SystemCommand(const String& commandLine, bool redirectStdOutToLog)
 {
     if (allowedPaths_.Empty())
-        return DoSystemCommand(commandLine, redirectStdOutToLog);
+        return DoSystemCommand(commandLine, redirectStdOutToLog, context_);
     else
     {
         LOGERROR("Executing an external command is not allowed");

+ 3 - 0
Source/ThirdParty/SDL/include/SDL_config_linux.h

@@ -317,6 +317,9 @@
 /* #undef SDL_POWER_BEOS */
 /* #undef SDL_POWER_HARDWIRED */
 
+/* Enable filesystem support */
+#define SDL_FILESYSTEM_UNIX 1
+
 /* Enable assembly routines */
 #define SDL_ASSEMBLY_ROUTINES 1
 /* #undef SDL_ALTIVEC_BLITTERS */