Fix a tiny memory-leak when calling vfork
[ardour.git] / libs / pbd / pbd / system_exec.h
index dc17ced2f673236860b36ad8ece7d71faad4ba56..1e36c3df9fcba136adc0f70738d52babd5b98ef1 100644 (file)
@@ -1,6 +1,6 @@
 /*
     Copyright (C) 2010 Paul Davis
-    Author: Robin Gareus <robin@gareus.org>
+    Copyright (C) 2010-2014 Robin Gareus <robin@gareus.org>
 
     This program is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
@@ -17,8 +17,8 @@
     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 
 */
-#ifndef __ardour_system_exec_h__
-#define __ardour_system_exec_h__
+#ifndef _libpbd_system_exec_h_
+#define _libpbd_system_exec_h_
 
 #ifndef STDIN_FILENO
 #define STDIN_FILENO 0
 #define STDERR_FILENO 2
 #endif
 
+#ifdef PLATFORM_WINDOWS
+#include <windows.h>
+
+#ifdef interface
+#undef interface // VKamyshniy: to avoid "include/giomm-2.4/giomm/dbusmessage.h:270:94: error: expected ',' or '...' before 'struct'"
+#endif
+
+#else // posix
+#include <sys/types.h>
+#include <sys/wait.h> /* WNOHANG is part of the exposed API */
+#endif
+
 #include <string>
 #include <pthread.h>
 #include <signal.h>
 #include <map>
 
-#ifdef NOPBD  /* outside ardour */
+#ifdef NOPBD  /* unit-test outside ardour */
 #include <sigc++/bind.h>
 #include <sigc++/signal.h>
 #else
-#include <pbd/signals.h>
+#include "pbd/signals.h"
 #endif
 
+namespace PBD {
+
 /** @class: SystemExec
  *  @brief execute an external command
  *
@@ -56,7 +70,7 @@
  * \ref Terminated is sent if the child application exits.
  *
  */
-class SystemExec
+class LIBPBD_API SystemExec
 {
        public:
                /** prepare execution of a program with 'execve'
@@ -104,6 +118,9 @@ class SystemExec
 
                virtual ~SystemExec ();
 
+               static char* format_key_value_parameter (std::string, std::string);
+
+               std::string to_s() const;
 
                /** fork and execute the given program
                 *
@@ -116,7 +133,7 @@ class SystemExec
                 * @return If the process is already running or was launched successfully
                 * the function returns zero (0). A negative number indicates an error.
                 */
-               int start (int stderr_mode = 1);
+               int start (int stderr_mode, const char *_vfork_exec_wrapper);
                /** kill running child-process
                 *
                 * if a child process exists trt to shut it down by closing its STDIN.
@@ -149,12 +166,19 @@ class SystemExec
                 */
                void close_stdin ();
                /** write into child-program's STDIN
-                * @param d data to write
+                * @param d text to write
                 * @param len length of data to write, if it is 0 (zero), d.length() is
                 * used to determine the number of bytes to transmit.
                 * @return number of bytes written.
                 */
-               int write_to_stdin (std::string d, size_t len=0);
+               size_t write_to_stdin (std::string const& d, size_t len=0);
+
+               /** write into child-program's STDIN
+                * @param data data to write
+                * @param bytes length of data to write
+                * @return number of bytes written.
+                */
+               size_t write_to_stdin (const void* d, size_t bytes=0);
 
                /** The ReadStdout signal is emitted when the application writes to STDOUT.
                 * it passes the written data and its length in bytes as arguments to the bound
@@ -198,7 +222,7 @@ class SystemExec
                char **envp;
 
        private:
-#ifdef __WIN32__
+#ifdef PLATFORM_WINDOWS
                PROCESS_INFORMATION *pid;
                HANDLE stdinP[2];
                HANDLE stdoutP[2];
@@ -207,17 +231,22 @@ class SystemExec
                void make_wargs(char **);
 #else
                pid_t pid;
+# ifndef NO_VFORK
+               char **argx;
+# endif
 #endif
                void init ();
                pthread_mutex_t write_lock;
 
-               int fdin; ///< file-descriptor for writing to child's STDIN. This variable is identical to pin[1] but also used as status check if the stdin pipe is open: <0 means closed.
                int pok[2];
                int pin[2];
                int pout[2];
 
                pthread_t      thread_id_tt;
                bool           thread_active;
-};
 
-#endif /* __ardour_system_exec_h__ */
+}; /* end class */
+
+}; /* end namespace */
+
+#endif /* _libpbd_system_exec_h_ */