/*
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
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>
-#ifdef NOPBD /* outside ardour */
+#include <map>
+
+#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
*
* \ref Terminated is sent if the child application exits.
*
*/
-class SystemExec
+class LIBPBD_API SystemExec
{
public:
/** prepare execution of a program with 'execve'
*
*/
SystemExec (std::string c, char ** a);
+
+ /** similar to \ref SystemExec but expects a whole command line, and
+ * handles some simple escape sequences.
+ *
+ * @param command complete command-line to be executed
+ * @param subs a map of <char, std::string> listing the % substitutions to
+ * be made.
+ *
+ * creates an argv array from the given command string, splitting into
+ * parameters at spaces.
+ * "\ " is non-splitting space, "\\" (and "\" at end of command) as "\",
+ * for "%<char>", <char> is looked up in subs and the corresponding string
+ * substituted. "%%" (and "%" at end of command)
+ * returns an argv array suitable for creating a new SystemExec with
+ */
+ SystemExec (std::string command, const std::map<char, std::string> subs);
+
virtual ~SystemExec ();
+ static char* format_key_value_parameter (std::string, std::string);
+
+ std::string to_s() const;
+
/** fork and execute the given program
*
* @param stderr_mode select what to do with program's standard error
* @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.
*/
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
int nicelevel; ///< process nice level - defaults to 0
void make_argp(std::string);
+ void make_argp_escaped(std::string command, const std::map<char, std::string> subs);
void make_envp();
char **argp;
char **envp;
private:
-#ifdef __WIN32__
+#ifdef PLATFORM_WINDOWS
PROCESS_INFORMATION *pid;
HANDLE stdinP[2];
HANDLE stdoutP[2];
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_ */