PCL
pcl::ExternalProcess Class Reference

Execution of external programs. More...

#include <ExternalProcess.h>

+ Inheritance diagram for pcl::ExternalProcess:

Public Types

using error_code = ExternalProcessError::value_type
 
using pid_type = int64
 
using process_error_event_handler = void(Control::*)(ExternalProcess &sender, error_code error)
 
using process_event_handler = void(Control::*)(ExternalProcess &sender)
 
using process_exit_event_handler = void(Control::*)(ExternalProcess &sender, int exitCode, bool exitOk)
 

Public Member Functions

 ExternalProcess ()
 
 ExternalProcess (const ExternalProcess &)=delete
 
 ExternalProcess (ExternalProcess &&)=delete
 
 ~ExternalProcess () override
 
size_type BytesAvailable () const
 
size_type BytesToWrite () const
 
void CloseStandardError ()
 
void CloseStandardInput ()
 
void CloseStandardOutput ()
 
void EnsureUnique () override
 
StringList Environment () const
 
int ExitCode () const
 
bool HasCrashed () const
 
bool IsRunning () const
 
bool IsStarting () const
 
void Kill ()
 
void OnError (process_error_event_handler handler, Control &receiver)
 
void OnFinished (process_exit_event_handler handler, Control &receiver)
 
void OnStandardErrorDataAvailable (process_event_handler handler, Control &receiver)
 
void OnStandardOutputDataAvailable (process_event_handler handler, Control &receiver)
 
void OnStarted (process_event_handler handler, Control &receiver)
 
ExternalProcessoperator= (const ExternalProcess &)=delete
 
ExternalProcessoperator= (ExternalProcess &&)=delete
 
pid_type PID () const
 
ByteArray Read ()
 
void RedirectStandardError (const String &filePath, bool append=false)
 
void RedirectStandardInput (const String &filePath)
 
void RedirectStandardOutput (const String &filePath, bool append=false)
 
void RedirectStandardOutput (ExternalProcess &process)
 
void SetEnvironment (const StringList &environment)
 
void SetWorkingDirectory (const String &dirPath)
 
ByteArray StandardError ()
 
ByteArray StandardOutput ()
 
void Start (const String &program, const StringList &arguments=StringList())
 
void Terminate ()
 
bool WaitForDataAvailable (int ms=6000)
 
bool WaitForDataWritten (int ms=6000)
 
bool WaitForFinished (int ms=6000)
 
bool WaitForStarted (int ms=6000)
 
String WorkingDirectory () const
 
void Write (const ByteArray &data)
 
void Write (const char *text)
 
void Write (const IsoString &text)
 
void Write (const String &text)
 
void Write (const void *data, size_type count)
 
- Public Member Functions inherited from pcl::UIObject
virtual ~UIObject () noexcept(false)
 
bool IsAlias () const
 
bool IsGarbage () const
 
bool IsNull () const
 
bool IsSameObject (const UIObject &o) const
 
bool IsUnique () const
 
String ObjectId () const
 
IsoString ObjectType () const
 
bool operator< (const UIObject &o) const
 
bool operator== (const UIObject &o) const
 
size_type RefCount () const
 
void SetObjectId (const String &id)
 

Static Public Member Functions

static int ExecuteProgram (const String &program, const StringList &arguments=StringList())
 
static ExternalProcessNull ()
 
static pid_type StartProgram (const String &program, const StringList &arguments=StringList(), const String &workingDirectory=String())
 
- Static Public Member Functions inherited from pcl::UIObject
static UIObjectNull ()
 

Additional Inherited Members

- Protected Member Functions inherited from pcl::UIObject
 UIObject ()=default
 
 UIObject (const UIObject &x)
 
 UIObject (UIObject &&x)
 
UIObjectoperator= (const UIObject &x)
 
UIObjectoperator= (UIObject &&x)
 

Detailed Description

ExternalProcess is essentially a PCL wrapper to Qt's QProcess class, which the PixInsight core application uses as the underlying implementation for management of external processes on the PixInsight platform.

TODO: Write a detailed description for ExternalProcess.

Definition at line 109 of file ExternalProcess.h.

Member Typedef Documentation

◆ error_code

using pcl::ExternalProcess::error_code = ExternalProcessError::value_type

The type used to represent error conditions in external processes.

Definition at line 131 of file ExternalProcess.h.

◆ pid_type

The type of a platform-dependent Process Identifier (PID).

On Linux/UNIX (Linux, FreeBSD and Mac OS X), a PID is a 64-bit integer.

On Windows platforms, a PID is a pointer to a _PROCESS_INFORMATION structure (hence, on 64-bit Windows platforms a PID is also a 64-bit integer number).

Definition at line 123 of file ExternalProcess.h.

Constructor & Destructor Documentation

◆ ExternalProcess() [1/3]

pcl::ExternalProcess::ExternalProcess ( )

Constructs an ExternalProcess object.

◆ ~ExternalProcess()

pcl::ExternalProcess::~ExternalProcess ( )
inlineoverride

Destroys the client-side ExternalProcess instance and dereferences the server-side object. If the server-side object becomes unreferenced, it will be garbage-collected and eventually destroyed by the core application.

Definition at line 144 of file ExternalProcess.h.

◆ ExternalProcess() [2/3]

pcl::ExternalProcess::ExternalProcess ( const ExternalProcess )
delete

Copy constructor. Copy semantics are disabled for ExternalProcess because this class represents unique server-side objects.

◆ ExternalProcess() [3/3]

pcl::ExternalProcess::ExternalProcess ( ExternalProcess &&  )
delete

Move constructor. Move semantics are disabled for ExternalProcess because of parent-child server-side object relations.

Member Function Documentation

◆ BytesAvailable()

size_type pcl::ExternalProcess::BytesAvailable ( ) const

Returns the number of bytes waiting to be read from this running process. If the process is not running, this member function returns zero.

When this function returns a nonzero value, the available data can be read by calling one of the Read() member functions.

◆ BytesToWrite()

size_type pcl::ExternalProcess::BytesToWrite ( ) const

Returns the number of bytes pending to be written to this running process. If the process is not running, this function returns zero.

If this function returns a nonzero value, it is because one of the Write() member functions has been called previously for this process with nonempty data.

◆ CloseStandardError()

void pcl::ExternalProcess::CloseStandardError ( )

Closes the standard error stream (stderr) of the running process.

After calling this function, you no longer can read data from the process through its stderr stream. Calling this function can be useful to save memory for processes that generate large amounts of output data, or if a running process starts producing loads of data that you don't want to process anymore.

Note
This function can only be called for a running process. If the process is not running, an Error exception is thrown.

◆ CloseStandardInput()

void pcl::ExternalProcess::CloseStandardInput ( )

Closes the standard input stream (stdin) of the running process.

After calling this function, you no longer can write to the process using one of the Write() member functions (doing so will always throw an Error exception due to an I/O error).

There are programs that require you to close the input stream explicitly. An example is the 'cat' UNIX utility. For example, if you enter the 'cat' command from a UNIX terminal, the program starts reading data from its stdin stream (which is the terminal in this example) until you press the "Ctrl+D" combination to close it.

Note
This function can only be called for a running process. If the process is not running, an Error exception is thrown.

◆ CloseStandardOutput()

void pcl::ExternalProcess::CloseStandardOutput ( )

Closes the standard output stream (stdout) of the running process.

After calling this function, you no longer can read data from the process through its stdin stream. Calling this function can be useful to save memory for processes that generate large amounts of output data, or if a running process starts producing loads of data that you don't want to process anymore.

Note
This function can only be called for a running process. If the process is not running, an Error exception is thrown.

◆ EnsureUnique()

void pcl::ExternalProcess::EnsureUnique ( )
inlineoverridevirtual

Ensures that the server-side object managed by this instance is uniquely referenced.

Since external processes are unique objects, calling this member function has no effect.

Reimplemented from pcl::UIObject.

Definition at line 179 of file ExternalProcess.h.

◆ Environment()

StringList pcl::ExternalProcess::Environment ( ) const

Returns the list of environment variables for this process. Environment variables are 'name=value' items that most programs can interpret to modify their functionality.

If no environment has been set for this process, an empty list is returned.

◆ ExecuteProgram()

static int pcl::ExternalProcess::ExecuteProgram ( const String program,
const StringList arguments = StringList() 
)
static

Executes a program as a child process and waits for it to terminate.

Parameters
programPath to an existing executable file.
argumentsOptional list of command-line arguments that will be passed to the executable. Arguments containing spaces will be enclosed by quotes automatically. The default value is an empty list.

Returns the program's exit code. If the specified program cannot be executed, this member function throws an Error exception.

◆ ExitCode()

int pcl::ExternalProcess::ExitCode ( ) const

Returns the exit code of the finished process. This is normally the return value of the process' main() function.

◆ HasCrashed()

bool pcl::ExternalProcess::HasCrashed ( ) const

Returns true iff the running process has crashed.

◆ IsRunning()

bool pcl::ExternalProcess::IsRunning ( ) const

Returns true iff the process is running. An ExternalProcess object represents a running process briefly (usually) after calling its Start() member function, when the IsStarting() function returns false, and just before an OnStarted() event is generated.

◆ IsStarting()

bool pcl::ExternalProcess::IsStarting ( ) const

Returns true iff the process is starting. An ExternalProcess object enters the starting state after calling its Start() member function, but before the actual process is running.

◆ Kill()

void pcl::ExternalProcess::Kill ( )

Forces termination of the running process.

On Linux/UNIX platforms (Linux, FreeBSD and Mac OS X) a SIGKILL signal is sent to the process.

On Windows, the TerminateProcess() API function is called to force process termination.

Warning
Unconditional termination of processes is always risky and should be avoided. For example, the running program wil not have an opportunity to close open files or save modified data. This function should only be used as a last resort to terminate a process.

◆ Null()

static ExternalProcess& pcl::ExternalProcess::Null ( )
static

Returns a reference to a null ExternalProcess instance. A null ExternalProcess does not correspond to an existing external process in the PixInsight core application.

◆ operator=() [1/2]

ExternalProcess& pcl::ExternalProcess::operator= ( const ExternalProcess )
delete

Copy assignment. Copy semantics are disabled for ExternalProcess because this class represents unique server-side objects.

◆ operator=() [2/2]

ExternalProcess& pcl::ExternalProcess::operator= ( ExternalProcess &&  )
delete

Move assignment. Move semantics are disabled for ExternalProcess because of parent-child server-side object relations.

◆ PID()

pid_type pcl::ExternalProcess::PID ( ) const

Returns the platform-dependent Process Identifier (PID) of the running process. See the ExternalProcess::pid_type type definition for more information.

If the process is not running this member function returns zero.

◆ Read()

ByteArray pcl::ExternalProcess::Read ( )

Reads all the data available from the standard output and standard error streams (stdout and stderr, respectively) of this process, and returns them as a ByteArray object.

If the process has not sent any new data through its output streams, or if the process is not running, an empty ByteArray is returned. Note that after the reading operation, both stdout and stderr streams are cleared, i.e. the data can only be read once.

Note
In the returned ByteArray, the data from both stdout and stderr streams will be mixed because they are gathered as they are generated. If you need the data from both streams separately, call the StandardOutput() and StandardError() member functions as appropriate.

◆ RedirectStandardError()

void pcl::ExternalProcess::RedirectStandardError ( const String filePath,
bool  append = false 
)

Redirects the standard error output stream (stderr) of the process to the specified file.

Parameters
filePathPath to the file where the process will write its standard error data.
appendIf true and the specified file already exists, its contents will be preserved and newly generated data will be appended. If false, the existing file will be overwritten and its previous contents will be lost. The default value is false (overwrite).

For more information on redirection of process output, see the RedirectStandardOutput() functions.

◆ RedirectStandardInput()

void pcl::ExternalProcess::RedirectStandardInput ( const String filePath)

Redirects the standard input stream (stdin) of the process from the specified file.

Parameters
filePathPath to an existing file from which the process will read its standard input data. The current contents of the file won't be modified or affected in any way by calling this function.

Example:

p.RedirectStandardInput( "/tmp/foo.txt" );
p.Start( "grep", StringList() << "\'bar\'" );

The above code snippet is equivalent to this command:

grep 'bar' </tmp/foo.txt

Note
This member function can only be called before running the process, i.e. before calling Start(). Otherwise an Error exception is thrown.

◆ RedirectStandardOutput() [1/2]

void pcl::ExternalProcess::RedirectStandardOutput ( const String filePath,
bool  append = false 
)

Redirects the standard output stream (stdout) of the process to the specified file.

Parameters
filePathPath to the file where the process will write its standard output data.
appendIf true and the specified file already exists, its contents will be preserved and newly generated data will be appended. If false, the existing file will be overwritten and its previous contents will be lost. The default value is false (overwrite).

Example:

p1.RedirectStandardOutput( "/tmp/foo.txt" );
p1.Start( "ls", StringList() << "-la" << "*.bar" );

The above code snippet is equivalent to this command:

ls -la *.bar >/tmp/foo.txt

Note
This member function can only be called before running the process, i.e. before calling Start(). Otherwise an Error exception is thrown.

◆ RedirectStandardOutput() [2/2]

void pcl::ExternalProcess::RedirectStandardOutput ( ExternalProcess process)

Redirects the standard output stream (stdout) of the process to the specified process.

Parameters
processReference to a process where this process will write its standard output data.

This function can be used to build a pipe between two programs. For example:

p1.RedirectStandardOutput( p2 );
p1.Start( "cat", StringList() << "*.bar" );
p2.Start( "grep", StringList() << "\'foo\'" );

would produce the same result as this command:

cat *.bar |grep 'foo'

Note
This member function can only be called before running both processes, i.e. before calling Start() for this process and the specified process. Otherwise an Error exception is thrown.

◆ SetEnvironment()

void pcl::ExternalProcess::SetEnvironment ( const StringList environment)

Sets the environment for this process.

The environment is a list of 'name=value' elements, knwon as environment variables, that most programs can interpret to modify their functionality.

If no environment is explicitly set for a process, it will inherit the environment of the calling process.

Note
This member function can only be called before running the process, i.e. before calling Start(). Otherwise an Error exception is thrown.

◆ SetWorkingDirectory()

void pcl::ExternalProcess::SetWorkingDirectory ( const String dirPath)

Sets the working directory for this process.

Parameters
dirPathPath to an existing directory, which will be the working directory of the process when it is started.
Note
This member function can only be called before running the process, i.e. before calling Start(). Otherwise an Error exception is thrown.

◆ StandardError()

ByteArray pcl::ExternalProcess::StandardError ( )

Reads all the data available from the standard error stream (stderr) of this process, and returns them as a ByteArray object.

If the process has not sent any new data through its stderr stream, or if the process is not running, an empty ByteArray is returned. Note that after the reading operation the stderr stream is cleared, i.e. the data can only be read once.

◆ StandardOutput()

ByteArray pcl::ExternalProcess::StandardOutput ( )

Reads all the data available from the standard output stream (stdout) of this process, and returns them as a ByteArray object.

If the process has not sent any new data through its stdout stream, or if the process is not running, an empty ByteArray is returned. Note that after the reading operation the stdout stream is cleared, i.e. the data can only be read once.

◆ Start()

void pcl::ExternalProcess::Start ( const String program,
const StringList arguments = StringList() 
)

Attempts to execute an external process.

Parameters
programPath to the executable file.
argumentsOptional list of command-line arguments that will be passed to the executable. Arguments containing spaces will be enclosed by quotes automatically. The default value is an empty list.

If the specified program cannot be executed for some reason (for example, because the specified program does not exist, or because the calling process doesn't have enough privileges), this function throws an Error exception.

This function implicitly opens the standard input, output and error I/O streams (stdin, stdout and stderr, respectively) of the running process. You can read from and write to the process using the Read() and Write() member functions of ExternalProcess, respectively. You can also close the I/O streams using the CloseXX() member functions.

◆ StartProgram()

static pid_type pcl::ExternalProcess::StartProgram ( const String program,
const StringList arguments = StringList(),
const String workingDirectory = String() 
)
static

Executes a program as an independent process.

Parameters
programPath to an existing executable file.
argumentsOptional list of command-line arguments that will be passed to the executable. Arguments containing spaces will be enclosed by quotes automatically. The default value is an empty list.
workingDirectoryPath to an existing directory, which will be the working directory of the process. The default value is an empty string.

The program is executed as a standalone process, also known as a daemon on Linux/UNIX. It can continue running after the calling application terminates.

Returns the platform-dependent process identifier (PID) of the running process. If the specified program cannot be executed, this member function throws an Error exception.

◆ Terminate()

void pcl::ExternalProcess::Terminate ( )

Attempts to terminate the running process.

On Linux/UNIX platforms (Linux, FreeBSD and Mac OS X) a SIGTERM signal is sent to the process.

On Windows, this function sends WM_CLOSE messages to all top-level windows owned by the process and to its main thread. Console Windows applications that don't have a message loop, or GUI Windows applications that don't process WM_CLOSE messages adequately, cannot be terminated by calling this member function. In these cases, the only way to terminate the running process is by calling Kill().

Note
Note that there is no guarantee that the running process will terminate after calling this function.

◆ WaitForDataAvailable()

bool pcl::ExternalProcess::WaitForDataAvailable ( int  ms = 6000)

Waits for the running process to send data.

Parameters
msMaximum waiting time in milliseconds. If a negative value is specified, this function will never time out. The default waiting time is 6000 ms (six seconds).

This function suspends the calling task for at most the specified time, or forever if a negative time value is specified. Returns true if the process sent some data through one of its output streams (standard output or standard error) before the specified time elapsed. Returns false if the process timed out. In the latter case, this function can be called again to continue waiting for the process to generate output data. When new output data is available from the process, it can be read immediately by calling one of the Read() member functions.

Warning
When called from the root thread, this function can freeze the entire PixInsight graphical interface. For asynchronous external process execution, consider calling WaitForXX() functions from a separate thread. Be aware that if you specify a large waiting time or a negative value, this function may crash the calling thread.

◆ WaitForDataWritten()

bool pcl::ExternalProcess::WaitForDataWritten ( int  ms = 6000)

Waits for the running process to receive data.

Parameters
msMaximum waiting time in milliseconds. If a negative value is specified, this function will never time out. The default waiting time is 6000 ms (six seconds).

This function suspends the calling task for at most the specified time, or forever if a negative time value is specified. Returns true if the process received the data sent previously through its input stream (the process' standard input) before the specified time elapsed. Returns false if the process timed out. In the latter case, this function can be called again to continue waiting for the process to fetch its input data. Data can be sent to a running process by calling one of the Write() member functions.

Warning
When called from the root thread, this function can freeze the entire PixInsight graphical interface. For asynchronous external process execution, consider calling WaitForXX() functions from a separate thread. Be aware that if you specify a large waiting time or a negative value, this function may crash the calling thread.

◆ WaitForFinished()

bool pcl::ExternalProcess::WaitForFinished ( int  ms = 6000)

Waits for the running process to finish execution.

Parameters
msMaximum waiting time in milliseconds. If a negative value is specified, this function will never time out. The default waiting time is 6000 ms (six seconds).

This function suspends the calling task for at most the specified time, or forever if a negative time value is specified. Returns true if the process finished its execution before the specified time elapsed. Returns false if the process timed out. In the latter case, this function can be called again to continue waiting for the process to finish.

Warning
When called from the root thread, this function can freeze the entire PixInsight graphical interface. For asynchronous external process execution, consider calling WaitForXX() functions from a separate thread. Be aware that if you specify a large waiting time or a negative value, this function may crash the calling thread.

◆ WaitForStarted()

bool pcl::ExternalProcess::WaitForStarted ( int  ms = 6000)

Waits for the process to start execution.

Parameters
msMaximum waiting time in milliseconds. If a negative value is specified, this function will never time out. The default waiting time is 6000 ms (six seconds).

This function suspends the calling task for at most the specified time, or forever if a negative time value is specified. Returns true if the process started before the specified time elapsed. Returns false if the process timed out. In the latter case, this function can be called again to continue waiting for the process to start.

Warning
When called from the root thread, this function can freeze the entire PixInsight graphical interface. For asynchronous external process execution, consider calling WaitForXX() functions from a separate thread. Be aware that if you specify a large waiting time or a negative value, this function may crash the calling thread.

◆ WorkingDirectory()

String pcl::ExternalProcess::WorkingDirectory ( ) const

Returns the working directory (aka folder) of this process.

◆ Write() [1/5]

void pcl::ExternalProcess::Write ( const ByteArray data)

Writes the specified data to the standard input stream (stdin) of this process.

◆ Write() [2/5]

void pcl::ExternalProcess::Write ( const char *  text)

Writes the specified text to the standard input stream (stdin) of this process. The specified 8-bit string will be treated as a sequence of bytes, and the terminating null character of the string will be excluded.

◆ Write() [3/5]

void pcl::ExternalProcess::Write ( const IsoString text)

Writes the specified text to the standard input stream (stdin) of this process. The specified 8-bit string will be treated as a sequence of bytes, and the terminating null character of the string will be excluded.

◆ Write() [4/5]

void pcl::ExternalProcess::Write ( const String text)

Writes the specified text to the standard input stream (stdin) of this process. The specified UTF-16 string will be treated as a sequence of bytes, and the terminating null character of the string (two bytes) will be excluded.

◆ Write() [5/5]

void pcl::ExternalProcess::Write ( const void *  data,
size_type  count 
)

Writes count contiguous bytes starting at the specified data location to the standard input stream (stdin) of this process.


The documentation for this class was generated from the following file:
StringList
Dynamic list of Unicode (UTF-16) strings.
pcl::ExternalProcess::ExternalProcess
ExternalProcess()