=== modified file 'src/com/goldencode/p2j/main/ClientCore.java'
--- src/com/goldencode/p2j/main/ClientCore.java	2023-01-17 12:58:57 +0000
+++ src/com/goldencode/p2j/main/ClientCore.java	2023-01-26 12:12:44 +0000
@@ -120,6 +120,7 @@
 
 package com.goldencode.p2j.main;
 
+import java.io.*;
 import java.util.*;
 import java.util.function.*;
 import java.util.logging.*;
@@ -188,6 +189,11 @@
    public static void start(BootstrapConfig config, boolean file, boolean single, Supplier<String> diag)
    throws Exception
    {
+      // Load native library
+      loadNativeLibrary();
+      
+      setOutputToFile(config);
+      
       String  uuid     = config.getString("server", "spawner", "uuid", null);
       boolean dbg      = config.getBoolean("logging", "debug", "enable", false);
       String  referrer = config.getString("web", "referrer", "url", null);
@@ -198,9 +204,6 @@
       // iterations of the core loop
       ScreenDriver<?> driver = (uuid == null) ? null : processTemporaryClient(uuid, config);
       
-      // Load native library
-      loadNativeLibrary();
-      
       while (running)
       {
          Object          context = null; 
@@ -431,6 +434,25 @@
       return isStop;
    }
 
+   private static void setOutputToFile(BootstrapConfig config)
+   {
+      String outputToFile = config.getString("server", "clientConfig", "outputToFile", null);
+      if (outputToFile == null)
+      {
+         return;
+      }
+      
+      try
+      {
+         outputToFile = outputToFile.replace("%pid%", String.valueOf(getPid()));
+         System.setOut(new PrintStream(new FileOutputStream(outputToFile), true));
+      }
+      catch (Throwable t)
+      {
+         System.err.println("ClientCore: Unable to redirect stdout to outputToFile " + outputToFile);
+      }
+   }
+
    /**
     * Loads native library and performs required initial steps for P2J library to working.
     */

=== modified file 'src/com/goldencode/p2j/main/ProcessClientBuilder.java'
--- src/com/goldencode/p2j/main/ProcessClientBuilder.java	2017-04-01 23:33:34 +0000
+++ src/com/goldencode/p2j/main/ProcessClientBuilder.java	2023-01-26 09:43:24 +0000
@@ -132,9 +132,9 @@
       if (outputToFile != null)
       {
          cmd.add("-O");
-         cmd.add(outputToFile);
+         cmd.add("server:clientConfig:outputToFile=" + outputToFile);
       }
 
       return cmd;
    }
-}
\ No newline at end of file
+}

=== modified file 'src/native/spawn.c'
--- src/native/spawn.c	2021-05-19 21:40:23 +0000
+++ src/native/spawn.c	2023-01-26 12:21:45 +0000
@@ -162,9 +162,6 @@
    #define ALLPERMS (S_ISUID|S_ISGID|S_ISVTX|S_IRWXU|S_IRWXG|S_IRWXO)/* 07777 */
 #endif
 
-/* prototypes */
-void stdout_redirect();
-
 /* Global data */
 struct passwd *pw;
 int extra_logging = 0;
@@ -400,12 +397,6 @@
             logMessage(message_buffer);
             exit(audit(ERR_SPAWN_CHDIR_WD, "chdir(workdir)"));
          }
-
-         /* Redirect STDOUT if required */
-         if (output_file_name[0] != 0)
-         {
-            stdout_redirect();
-         }
          
          /* Execute command */
          exit(execvp(command, argv));
@@ -921,6 +912,7 @@
 
    int nopts;
    int debug_opt_found = 0;
+   int output_to_file_opt_found = 0;
    
    JavaVMOption options[8];
    options[0].optionString = "-Djava.class.path=./p2j.jar:.";
@@ -1015,12 +1007,26 @@
    jsize jlength = (*env)->GetArrayLength(env, (jarray) command);
    int length = (int) jlength;
    
+   if (output_file_name[0] != 0)
+   {
+      output_to_file_opt_found = 1;
+   }
+   
    /* make it 1-based, so it follows the structure of the command line arguments 
       (0 is program name); also, one more position is needed for execvp, which requires for the
       arguments to be null-terminated. */
-   char **arguments = (char**) malloc((length + 2) * sizeof(char*));
+   char **arguments = (char**) malloc((length + 2 + output_to_file_opt_found) * sizeof(char*));
    arguments[0] = NULL;
-   arguments[length + 1] = NULL;
+   
+   arguments[length + 1 + output_to_file_opt_found] = NULL;
+
+   if (output_to_file_opt_found == 1)
+   {
+      int len = strlen(output_file_name) + 1;
+      arguments[length + 1] = (char*) malloc(len * sizeof(char));
+      memset(arguments[length + 1], '\0', len);
+      strcpy(arguments[length + 1], output_file_name);
+   }
    
    int i;
    for (i = 0; i < (int) length; i++)
@@ -1151,38 +1157,6 @@
 }
 
 /**
- * Redirect STDOUT to an output file. 
- */
-void stdout_redirect()
-{
-   int output_fd; 
-   char pid[32];
-   
-   /* convert pid to string */
-   sprintf(pid, "%u", getpid()); 
-   
-   /* replace %pid% placeholder */
-   char* filename = replace_str(output_file_name, "%pid%", pid);
-    
-   // Open file
-   output_fd = open(filename, O_WRONLY | O_CREAT | O_APPEND, 0644);
-   
-   if (output_fd == -1)
-   {
-      fprintf(stderr, "Cannot open file %s\n", filename);
-   }
-   else
-   {
-      /* Redirect STDOUT to file */
-      if (dup2(output_fd, STDOUT_FILENO) == -1)
-      {
-         close(output_fd);
-         fprintf(stderr, "Cannot redirect STDOUT to file %s\n", filename);
-      }
-   }
-}
-
-/**
  * Main function which allows both password and P2J server-style authentication.
  * <p>
  * For P2J server-style authentiation, the following files need to exist in current directory:

