![]() |
TSDuck v3.45-4766
MPEG Transport Stream Toolkit
|
Fork a process and create a pipe to its standard input, seen as a C++ std::basic_ostream<char>. More...
#include <tsForkPipeOutputStream.h>


Public Types | |
| enum | InputMode { STDIN_PARENT , STDIN_PIPE , STDIN_NONE } |
| How to standard input in the created process. More... | |
| enum | OutputMode { KEEP_BOTH , STDOUT_ONLY , STDERR_ONLY , STDOUT_PIPE , STDOUTERR_PIPE } |
| How to merge standard output and standard error in the created process. More... | |
| using | SuperClass = std::basic_ostream< char > |
| Explicit reference to the public superclass. | |
| enum | WaitMode { ASYNCHRONOUS , SYNCHRONOUS , EXIT_PROCESS } |
| How to wait for the created process when close() is invoked. More... | |
Public Member Functions | |
| ForkPipeOutputStream (Report *report) | |
| Constructor. | |
| ForkPipeOutputStream (ReporterBase *delegate) | |
| Constructor. | |
| virtual | ~ForkPipeOutputStream () override |
| Destructor. | |
| void | abortPipeReadWrite () |
| Abort any currenly input/output operation in the pipe. | |
| virtual bool | asyncCompletedStream (IOSB *iosb) override |
| Update the status of an asynchronous readStream() or writeStream() after it completed. | |
| virtual bool | close (bool silent=false) override |
| Close the pipe. | |
| virtual bool | endOfStream () override |
| Check if the end of stream was reached while reading. | |
| SysHandleType | getHandle () const |
| Get the underlying file descriptor or device handle. | |
| bool | getIgnoreAbort () const |
| Get "ignore abort". | |
| SysHandleType | getProcessHandle () const |
| Get the created process handle. | |
| SysProcessIdType | getProcessId () const |
| Get the created process id. | |
| virtual SysHandleType | getReadHandle () const override |
| Get the underlying file descriptor or device handle for read operations. | |
| SysSocketType | getReadSocket () const |
| Get the underlying file descriptor or device handle as a system socket handle for read operations. | |
| SysSocketType | getSocket () const |
| Get the underlying file descriptor or device handle as a system socket handle. | |
| virtual SysHandleType | getWriteHandle () const override |
| Get the underlying file descriptor or device handle for write operations. | |
| SysSocketType | getWriteSocket () const |
| Get the underlying file descriptor or device handle as a system socket handle for write operations. | |
| bool | isBroken () const |
| Check if the pipe was broken. | |
| bool | isNonBlocking () const |
| Check if the device is in non-blocking mode. | |
| bool | isOpen () const |
| Check if the process is running and the pipe is open (when used). | |
| virtual bool | isReadStream () override |
| Check if the stream is open for read. | |
| bool | isSupportedByReactor (bool recheck=false) |
| Check if the device is supported by a reactor for non-blocking or asynchronous I/O. | |
| bool | isSynchronous () const |
| Check if synchronous mode is active (ie. | |
| virtual bool | isWriteStream () override |
| Check if the stream is open for write. | |
| bool | muteReport (bool mute) |
| Temporarily mute the associated report. | |
| bool | open (const UString &command, WaitMode wait_mode, size_t buffer_size, OutputMode out_mode, InputMode in_mode) |
| Create the process, open the optional pipes. | |
| virtual bool | readStream (void *addr, size_t max_size, size_t &ret_size, const AbortInterface *abort=nullptr, IOSB *iosb=nullptr) override |
| Read some data from the stream. | |
| virtual bool | readStream (void *addr, size_t size, const AbortInterface *abort=nullptr) override |
| Read complete data from the stream. | |
| virtual Report & | report () const override |
| Access the Report which is associated with this object. | |
| void | setIgnoreAbort (bool on) |
| Set "ignore abort". | |
| bool | setNonBlocking (bool non_blocking) |
| Set the device in non-blocking mode. | |
| Report * | setReport (Report *report) |
| Associate this object with another Report to log errors. | |
| ReporterBase * | setReport (ReporterBase *delegate) |
| Associate this object with another ReporterBase to log errors. | |
| virtual bool | writeStream (const void *addr, size_t size, IOSB *iosb=nullptr) override |
| Write data to the stream. | |
| virtual bool | writeStream (const void *addr, size_t size, size_t &written_size, IOSB *iosb=nullptr) override |
| Write some data to the stream. | |
Static Public Member Functions | |
| static bool | GetOutput (UString &output, const UString &command, Report &report, bool include_stderr=false) |
| This static method launches a command and gets its output as text. | |
| static bool | IsPendingStatus (int error_code) |
| This static method checks if a system error code means "I/O in progress" (asynchronous I/O) or "I/O would block" (non-blocking I/O). | |
| static bool | Launch (const UString &command, Report &report, OutputMode out_mode=KEEP_BOTH, InputMode in_mode=STDIN_PARENT, WaitMode wait_mode=ASYNCHRONOUS) |
| This static method launches a command, without pipe, optionally without waiting for the completion of the command process. | |
| static int | SilentLevel (bool silent, int default_severity=Severity::Error) |
| Compute a log severity level from a "silent" parameter. | |
Static Public Attributes | |
| static constexpr size_t | DEFAULT_STREAM_BUFFER_SIZE = 1024 |
| Default stream buffer size in bytes. | |
Protected Member Functions | |
| virtual bool | allowSetNonBlocking () const override |
| Check that the non-blocking mode can be set. | |
| bool | checkNonBlocking (bool non_blocking, const UChar *opname) |
| Check the blocking mode of a device. | |
| bool | checkNonBlocking (IOSB *iosb, const UChar *opname) |
| Check the blocking mode of a device. | |
| int | genericSystemRead (void *addr, size_t max_size, size_t &ret_size, const AbortInterface *abort, NonBlockingDevice::IOSB *iosb, uint64_t position) |
| Generic system read operation. | |
| int | genericSystemWrite (const void *addr, size_t size, size_t &written_size, NonBlockingDevice::IOSB *iosb, uint64_t position) |
| Generic system write operation. | |
| bool | setSystemNonBlocking (bool non_blocking) |
| Low-level method to set the system file or socket descriptor in non-blocking mode. | |
| virtual bool | writeStreamBuffer (const void *addr, size_t size) override |
| Write buffered data to underlying output devicen whatever it is. | |
Static Protected Member Functions | |
| template<class T > requires std::derived_from<T, StreamInterface> | |
| static bool | ReadStreamHelper (T *obj, void *addr, size_t size, const AbortInterface *abort) |
| Implementation helper for fixed-size version of readStream(). | |
| template<class T > requires std::derived_from<T, StreamInterface> | |
| static bool | WriteStreamHelper (T *obj, const void *addr, size_t size, NonBlockingDevice::IOSB *iosb) |
| Implementation helper for fixed-size version of writeStream(). | |
Fork a process and create a pipe to its standard input, seen as a C++ std::basic_ostream<char>.
|
inherited |
How to wait for the created process when close() is invoked.
No pipe can be used with EXIT_PROCESS because there would be nobody on the other end of the pipe.
| Enumerator | |
|---|---|
| ASYNCHRONOUS | Don't wait, close() will return immediately. |
| SYNCHRONOUS | Wait for process completion during close(). |
| EXIT_PROCESS | Exit parent process during open(). UNIX: call exec(), Windows: call exit() after process creation. |
|
inherited |
|
inherited |
How to merge standard output and standard error in the created process.
|
explicit |
Constructor.
| [in] | report | Where to report errors. The report object must remain valid as long as this object exists or setReport() is used with another Report object. If report is null, log messages are discarded. |
|
explicit |
Constructor.
| [in] | delegate | Use the report of another ReporterBase. If delegate is null, log messages are discarded. |
|
overridevirtual |
Close the pipe.
Optionally wait for process termination if wait_mode was SYNCHRONOUS on open().
| [in] | silent | If true, do not report errors. This is typically useful when the object is in some error condition and closing it is necessary although it may generate additional meaningless errors. |
Reimplemented from ts::ForkPipe.
|
overrideprotectedvirtual |
Write buffered data to underlying output devicen whatever it is.
Must be implemented by subclasses.
| [in] | addr | Buffered data address. |
| [in] | size | Buffered data size in bytes. |
Implements ts::AbstractStandardOutputStream.
|
inherited |
Create the process, open the optional pipes.
| [in] | command | The command to execute. |
| [in] | wait_mode | How to wait for process termination in close(). |
| [in] | buffer_size | The pipes buffer size in bytes. Used on Windows only. Zero means default. |
| [in] | out_mode | How to handle stdout and stderr. |
| [in] | in_mode | How to handle stdin. |
|
inlineinherited |
Check if the process is running and the pipe is open (when used).
|
inlineinherited |
Check if the pipe was broken.
|
inlineinherited |
Check if synchronous mode is active (ie.
will wait for process termination).
|
inlineinherited |
Get the created process id.
|
inlineinherited |
Get the created process handle.
The concept of process handle exists on Windows only.
|
inlineinherited |
Set "ignore abort".
| [in] | on | If true and the process aborts, do not report error when writing data. when writing data. |
|
inlineinherited |
Get "ignore abort".
|
inherited |
Abort any currenly input/output operation in the pipe.
The pipe is left in a broken state and can be only closed.
|
staticinherited |
This static method launches a command, without pipe, optionally without waiting for the completion of the command process.
| [in] | command | The command to execute. |
| [in,out] | report | Where to report errors. |
| [in] | out_mode | How to handle stdout and stderr. Must be KEEP_BOTH (default), STDOUT_ONLY or STDERR_ONLY. Output modes using pipes are forbidden. |
| [in] | in_mode | How to handle stdin. Must be STDIN_PARENT (default) or STDIN_NONE. Input modes using pipes are forbidden. |
| [in] | wait_mode | How to wait for the command process. Must be ASYNCHRONOUS (default) or SYNCHRONOUS. |
|
staticinherited |
This static method launches a command and gets its output as text.
| [in] | output | The output of the command. |
| [in] | command | The command to execute. |
| [in,out] | report | Where to report errors. |
| [in] | include_stderr | If false, the standard error of the command is the same as the parent process. If true, the standard error is merged with the standard output in output. |
|
overridevirtualinherited |
Get the underlying file descriptor or device handle for read operations.
Subclasses should override this method.
Reimplemented from ts::NonBlockingDevice.
|
overridevirtualinherited |
Get the underlying file descriptor or device handle for write operations.
Subclasses should override this method.
Reimplemented from ts::NonBlockingDevice.
|
overridevirtualinherited |
Read complete data from the stream.
Read exactly size bytes, waiting if necessary.
Synchronization: There is no iosb parameter because this method uses blocking I/O by design. An error is returned if the instance of the class which implements StreamInterface is in non-blocking mode.
| [out] | addr | Address of the buffer for the incoming data. |
| [in] | size | Size in bytes of the buffer. |
| [in] | abort | If non-zero, invoked when I/O is interrupted (in case of user-interrupt, return, otherwise retry). |
Implements ts::StreamInterface.
|
overridevirtualinherited |
Read some data from the stream.
Wait and read at least one byte. Don't try to read exactly max_size bytes. If ret_size is less than max_bytes, it is possible to read more.
| [out] | addr | Address of the buffer for the incoming data. |
| [in] | max_size | Maximum size in bytes of the buffer. |
| [out] | ret_size | Returned input size in bytes. If zero, end of file has been reached or an error occurred. |
| [in] | abort | If non-zero, invoked when I/O is interrupted (in case of user-interrupt, return, otherwise retry). |
| [in,out] | iosb | Address of an IOSB structure. If non-null, the stream must be in non-blocking mode. When null, the stream must be in blocking mode (the default). See the description of ts::NonBlockingDevice::IOSB. Important: The parameter iosb should not be used by applications. It should be used only by "reactive classes", which work in combination with a Reactor. |
Implements ts::StreamInterface.
|
overridevirtualinherited |
Write data to the stream.
All bytes are written to the stream, blocking or retrying when necessary when the stream is in blocking mode. The base implementation of writeStream() uses the virtual version with a written_size output parameter.
| [in] | addr | Address of the data to write. |
| [in] | size | Size in bytes of the data to write. |
| [in,out] | iosb | Address of an IOSB structure. If non-null, the stream must be in non-blocking mode. When null, the stream must be in blocking mode (the default). See the description of ts::NonBlockingDevice::IOSB. Important: The parameter iosb should not be used by applications. It should be used only by "reactive classes", which work in combination with a Reactor. |
Implements ts::StreamInterface.
|
overridevirtualinherited |
Write some data to the stream.
All bytes are written to the stream, blocking or retrying when necessary when the stream is in blocking mode. Return the number of actually written bytes if some error occurred before writing everything.
| [in] | addr | Address of the data to write. |
| [in] | size | Size in bytes of the data to write. |
| [out] | written_size | Actually written size in bytes. Can be less than size in case of error in the middle of the write. |
| [in,out] | iosb | Address of an IOSB structure. If non-null, the stream must be in non-blocking mode. When null, the stream must be in blocking mode (the default). See the description of ts::NonBlockingDevice::IOSB. Important: The parameter iosb should not be used by applications. It should be used only by "reactive classes", which work in combination with a Reactor. |
Implements ts::StreamInterface.
|
overridevirtualinherited |
Update the status of an asynchronous readStream() or writeStream() after it completed.
This method applies to asynchronous I/O only (Windows), not non-blocking I/O (UNIX).
| [in,out] | iosb | Address of the IOSB structure which was used when readStream() or writeStream() was called. |
Implements ts::StreamInterface.
|
overridevirtualinherited |
Check if the stream is open for read.
Implements ts::StreamInterface.
|
overridevirtualinherited |
Check if the stream is open for write.
Implements ts::StreamInterface.
|
overridevirtualinherited |
Check if the end of stream was reached while reading.
Implements ts::StreamInterface.
|
overrideprotectedvirtualinherited |
Check that the non-blocking mode can be set.
Must be implemented by subclasses which do not support setting the non-blocking in certain states, such as after being opened. The default implementation always allows setting the non-blocking mode.
Reimplemented from ts::NonBlockingDevice.
|
inherited |
Set the device in non-blocking mode.
Important: Usually, this method must be called before opening the device, whatever it means. Otherwise it is ignored and the device blocking mode is unchanged.
| [in] | non_blocking | It true, the device is set in non-blocking mode. |
|
inlineinherited |
Check if the device is in non-blocking mode.
|
inherited |
Check if the device is supported by a reactor for non-blocking or asynchronous I/O.
| [in] | recheck | If true, force a recheck. If false and the device was previously checked, return the previous cached value. |
|
inlinestaticinherited |
This static method checks if a system error code means "I/O in progress" (asynchronous I/O) or "I/O would block" (non-blocking I/O).
| [in] | error_code | System error code. |
|
inherited |
Get the underlying file descriptor or device handle.
This method is reserved for low-level operations and should not be used by normal applications.
On UNIX systems, sockets are standard file descriptors. On Windows systems, sockets and devices handles are two distinct types (SOCKET, an integer type, and HANDLE, a pointer type). However, SOCKET and HANDLE have the same size and can be converted between each other. In practice, all Windows device handles are pointers. When Microsoft decided to implement the BSD socket API, they needed to represent sockets as integers. The integer is simply a cast of the HANDLE pointer.
In practice, the methods getHandle() and getSocket() return the same value, represented as two different portable types, SysHandleType and SysSocketType. Note that this types are defined as their real representation. On UNIX systems, both are defined as int and are compatible. However, on Windows systems, they are defined as HANDLE and SOCKET and are not compatible. So, accidentally mixing the two compiles on UNIX but not on Windows. Be careful to use the right type for the right usage.
There is one important difference between getHandle() and getSocket(): the error values, SYS_HANDLE_INVALID and SYS_SOCKET_INVALID. Be careful, these constants have distinct binary values on Windows. This is the only case were it is not possible to cast between a SysHandleType value and a SysSocketType value. This is why it is recommended to always use getHandle() when a SysHandleType is required and getSocket() when a SysSocketType is required.
A subclass which uses file descriptors or device handles for read, write, or both, must override the methods getReadHandle(), getWriteHandle(), or both. If the two types of operations use the same file descriptor, the two methods must return the same value.
An application should call getReadHandle() for read operations and getWriteHandle() for write operations. The method getHandle() returns getReadHandle() if its returns a valid value, and getWriteHandle() otherwise.
|
inherited |
Get the underlying file descriptor or device handle as a system socket handle.
|
inherited |
Get the underlying file descriptor or device handle as a system socket handle for read operations.
|
inherited |
Get the underlying file descriptor or device handle as a system socket handle for write operations.
|
protectedinherited |
Check the blocking mode of a device.
Called by subclass methods which are explicitly called in blocking or non-blocking mode.
| [in] | non_blocking | The required non-blocking mode. |
| [in] | opname | Name of the operation, for the error message. |
|
protectedinherited |
Check the blocking mode of a device.
Called by subclass methods which are explicitly called in blocking or non-blocking mode.
| [in,out] | iosb | Address of an IOSB structure. If non-null, we are in non-blocking mode. When null, we are in blocking mode. When non-null, pending is reset to false and overlap is zeroed. |
| [in] | opname | Name of the operation, for the error message. |
|
protectedinherited |
Low-level method to set the system file or socket descriptor in non-blocking mode.
| [in] | non_blocking | It true, the device is set in non-blocking mode. |
Summary: Do not use this method unless you exactly know what you are doing.
UNIX: Depending on the way a file descriptor is created, it may be possible to specify the non-blocking mode from the beginning. Or it can be somehow inherited. However, this is not portable.
Examples:
In all cases, it is possible to set a file descriptor in non-blocking mode at any time using the method setSystemNonBlocking(). This method uses fcntl(F_SETFL) to alter the file descriptor's flags.
Windows: The natural way of not being blocked on I/O on Windows is asynchronous I/O. To increase the general confusion, there is some form of non-blocking mode on Windows sockets, and only sockets, not other forms of file handles. This mode is activated using "ioctlsocket(fd, FIONBIO, &mode)". When this mode is active, socket I/O become similar to UNIX: they immediately either succeed or fail, but never block. However, there is no way to get notified when the I/O becomes possible. There is no equivalent to epoll (Linux) or kqueue (macOS and BSD). The Windows I/O Completion Ports can only work on asynchronous I/O, using OVERLAPPED structures. Because this form of non-blocking mode is mostly useless in practice, we do not use it and the method setSystemNonBlocking() does nothing on Windows.
|
protectedinherited |
Generic system write operation.
This is a convenience method which can be used (or not) by subclasses when the system calls write() (UNIX) or WriteFile() (Windows) are appropriate.
| [in] | addr | Address of the data to write. |
| [in] | size | Size in bytes of the data to write. |
| [out] | written_size | Actually written size in bytes. Can be less than size in case of error in the middle of the write. |
| [in,out] | iosb | Address of an IOSB structure. If non-null, the stream must be in non-blocking mode. When null, the stream must be in blocking mode (the default). See the description of ts::NonBlockingDevice::IOSB. |
| [in] | position | This value is only used on Windows with asynchronous I/O on disk file. On Windows, when asynchronous I/O are used on random access files, the file position is not maintained. Each read or write operation is performed at the specified absolute position. |
|
protectedinherited |
Generic system read operation.
This is a convenience method which can be used (or not) by subclasses when the system calls read() (UNIX) or ReadFile() (Windows) are appropriate.
| [out] | addr | Address of the buffer for the incoming data. |
| [in] | max_size | Maximum size in bytes of the buffer. |
| [out] | ret_size | Returned input size in bytes. If zero, end of file has been reached or an error occurred. |
| [in] | abort | If non-zero, invoked when I/O is interrupted (in case of user-interrupt, return, otherwise retry). |
| [in,out] | iosb | Address of an IOSB structure. If non-null, the stream must be in non-blocking mode. When null, the stream must be in blocking mode (the default). See the description of ts::NonBlockingDevice::IOSB. |
| [in] | position | This value is only used on Windows with asynchronous I/O on disk file. On Windows, when asynchronous I/O are used on random access files, the file position is not maintained. Each read or write operation is performed at the specified absolute position. |
|
overridevirtualinherited |
Access the Report which is associated with this object.
Can be called from another thread only if the Report object is thread-safe.
Implements ts::ReporterInterface.
Associate this object with another Report to log errors.
| [in] | report | Where to report errors. The report object must remain valid as long as this object exists or setReport() is used with another Report object. If report is null, log messages are discarded. |
|
inherited |
Associate this object with another ReporterBase to log errors.
| [in] | delegate | Use the report of another ReporterBase. If delegate is null, the previous explicit Report is used.. |
|
inherited |
Temporarily mute the associated report.
| [in] | mute | It true, report() will return a null report (log messages are discarded), until muteReport() is invoked again with mute set to false. |
|
inlinestaticinherited |
Compute a log severity level from a "silent" parameter.
Some subclass methods have a "silent" parameter to avoid reporting errors which may be insignificant, typically when closing a device after an error, in which case the close operation may produce other errors if the previous error left the device in an inconsistent state. While those errors should not be displayed as errors, we still display them at debug level.
| [in] | silent | If true, do not report errors, report debug messages instead. |
| [in] | default_severity | Default severity, in non-silent mode (error by default). |
|
inlinestaticprotectedinherited |
Implementation helper for fixed-size version of writeStream().
Often, the fixed-size version can be implemented using the variable-size version. However, this works well at a given derivation stage only.
Assume that:
| T | A subclass of StreamInterface. Write data to the stream. All bytes are written to the stream, blocking or retrying when necessary when the stream is in blocking mode. The base implementation of writeStream() uses the virtual version with a written_size output parameter. |
| [in,out] | obj | Object of class T. |
| [in] | addr | Address of the data to write. |
| [in] | size | Size in bytes of the data to write. |
| [in,out] | iosb | Address of an IOSB structure. If non-null, the stream must be in non-blocking mode. When null, the stream must be in blocking mode (the default). See the description of ts::NonBlockingDevice::IOSB. Important: The parameter iosb should not be used by applications. It should be used only by "reactive classes", which work in combination with a Reactor. |
|
inlinestaticprotectedinherited |
Implementation helper for fixed-size version of readStream().
See writeStreamHelper() for a rationale.
| T | A subclass of StreamInterface. |
| [in,out] | obj | Object of class T. |
| [out] | addr | Address of the buffer for the incoming data. |
| [in] | size | Size in bytes of the buffer. |
| [in] | abort | If non-zero, invoked when I/O is interrupted (in case of user-interrupt, return, otherwise retry). |