OsProcessStarter
Description
This class is to help configure and start an operating system processes.
This class uses a builder design pattern, so configurations for starting the process are being stored internally, and then the OsProcessStarter>>start method can be repeatedly used to spawn new processes with the same configuration.
It's important to note that the external process is running in parallel to the VAST process which is why an asynchronous programming style is preferred when deciding to take action after the external process completes. Many of the examples below will request an #onCompletion future and #then: perform an action when the future notifies that its complete.
Examples
"Run `dir` and print the results on the transcript once the process completes"
(OsProcessStarter startShell: 'dir') onCompletion
then: [:proc | Transcript show: proc outputStream upToEnd ; cr].

"Run `dir /b` and print the results on the transcript once the process completes"
(OsProcessStarter startShell: #('dir' '/b')) onCompletion
then: [:proc | Transcript show: proc outputStream upToEnd; cr].

"Run `dir /b` in a particular working directory."
((OsProcessStarter shell: #('dir' '/b'))
workingDirectory: 'C:\Temp';
start) onCompletion
then: [:proc | Transcript show: proc outputStream upToEnd; cr].

"Run `dir` redirecting stderr to stdout and redirecting stdout to Nul.
Block the current Smalltalk process until the external process completes."
((OsProcessStarter shell: #('dir' '/b'))
redirectErrorToOutput;
redirectOutputToNull;
start) waitForCompletion.
Class Methods
<details> command:
<pre><code> Set the os program and arguments and answer the new starter.
@progAndArgs is a <SequenceableCollection>,
where the first element is the program name
and any remaining elements will be the arguments.

Arguments:
progAndArgs - <SequenceableCollection>
Answers:
<OsProcessStarter>
</code></pre> </details>
<details> new
<pre><code> Answer a new initialized instance of this process starter.
Answers:
<OsProcessStarter>
</code></pre> </details>
<details> shell:
<pre><code> Set the os program and arguments and answer the new starter configured to run @progAndArgs in the system shell
@progAndArgs is a <SequenceableCollection>,
where the first element is the program name
and any remaining elements will be the arguments.

Arguments:
progAndArgs - <SequenceableCollection>
Answers:
<OsProcessStarter>
</code></pre> </details>
<details> start:
<pre><code> Set the os program and arguments and start a new native subprocess. The new subprocess will have stdio connected to VAST with pipes streams
@progAndArgs is a <SequenceableCollection>,
where the first element is the program name
and any remaining elements will be the arguments.

Examples:
The following would run the command
>ls -la
using the current working directory and env of the current process:
p := OsProcessStarter start: #('ls' '-la')
Arguments:
progAndArgs - <SequenceableCollection>
Answers:
<OsVastSubprocess>
</code></pre> </details>
<details> startShell:
<pre><code> Set the os program and arguments and start a new native subprocess spawned using the system shell. The new subprocess will have stdio connected to VAST with pipes streams
@progAndArgs is a <SequenceableCollection>,
where the first element is the program name
and any remaining elements will be the arguments.

Examples:
The following would run the command within a shell environment
>/bin/sh -c ls -la
using the current working directory and env of the current process:
p := OsProcessStarter startShell: #('ls' '-la')
Arguments:
progAndArgs - <SequenceableCollection>
Answers:
<OsVastSubprocess>
</code></pre> </details>
Instance Methods
<details> &&
<pre><code> Answer a conditional sequence pipeline chain. aSequenceableStarter will start as soon as this process starter finishes IF the exit code from this process is considered success (by default, an exitcode of 0)
Arguments:
aSequenceableStarter - <OsProcessStarter | OsPipelineStarter | OsPipelineChainStarter>
Answers:
<OsPipelineChainStarter>
</code></pre> </details>
<details> =>
<pre><code> Answer a sequence pipeline chain. aSequenceableStarter will start as soon as this process starter finishes
Arguments:
aSequenceableStarter - <OsProcessStarter | OsPipelineStarter | OsPipelineChainStarter>
Answers:
<OsPipelineChainStarter>
</code></pre> </details>
<details> |
<pre><code> Answer a pipeline, or pipeline chain, that is configured to feed the output from this starter into the input of @aPipelineableStarter. The execution of this pipeline will perform the starters in parallel
Arguments:
aPipelineableStarter - <OsProcessStarter | OsPipelineStarter | OsPipelineChainStarter>
Answers:
<OsProcessStarter | OsPipelineStarter | OsPipelineChainStarter>
</code></pre> </details>
<details> ||
<pre><code> Answer a conditional sequence process. aSequenceableStarter will start as soon as this process starter finishes IF the exit code from this process is considered a failure code (by default, an exitcode ~= 0)
Arguments:
aSequenceableStarter - <OsProcessStarter | OsPipelineStarter | OsPipelineChainStarter>
Answers:
<OsPipelineChainStarter>
</code></pre> </details>
<details> autoFillError:
<pre><code> Set to true to automatically pull data from internal os pipes to the stderr smalltalk pipe stream. This will activate the deadlock avoidance process which will attempt to fill the smalltalk pipe stream with available data in the os pipe every interval (default: 100ms). This will also enable the policy that whenever a write, or batch of writes, is about to occur to the stdin smalltalk pipe stream, then the stderr smalltalk pipe stream will attempt to be filled.
Note: 'autoFill' only applies when the error has been redirected to pipe streams
@see #redirectErrorToPipe

@see #tuneForDeadlockAvoidance which uses this feature to avoid the situation where both sides (smalltalk and the os process)
are blocked waiting for each other to fill or flush the os pipes.

Arguments:
aBoolean - <Boolean>
</code></pre> </details>
<details> autoFillOutput:
<pre><code> Set to true to automatically pull data from internal os pipes to the stdout smalltalk pipe stream. This will activate the deadlock avoidance process which will attempt to fill the smalltalk pipe stream with available data in the os pipe every interval (default: 100ms). This will also enable the policy that whenever a write, or batch of writes, is about to occur to the stdin smalltalk pipe stream, then the stdout smalltalk pipe stream will attempt to be filled.
Note: 'autoFill' only applies when the output has been redirected to pipe streams
@see #redirectOutputToPipe

@see #tuneForDeadlockAvoidance which uses this feature to avoid the situation where both sides (smalltalk and the os process)
are blocked waiting for each other to fill or flush the os pipes.

Arguments:
aBoolean - <Boolean>
</code></pre> </details>
<details> autoFlushInput:
<pre><code> Set true if any writes to the #inputStream of the process should be immediately flushed, false for normal bufferring behavior. This is useful for interactive scenarios where any request or response should be immediatley sent to the native process, instead of sitting in a buffer until the buffer is full.
Note: 'autoFlush' only applies when the input has been redirected to pipe streams
@see #redirectInputToPipe

@see #tuneForInteractive which uses this feature, in conjuctions with 'autoFill' for the
output/error streams, to create favorable conditions for 2-way conversations between this
process and the native OS Process.

Arguments:
aBoolean - <Boolean>
</code></pre> </details>
<details> command
<pre><code> Answer the builder's Os program and arguments which are, by default, converted from UTF-8 to the current code page. An exception to this are ByteArray program or arguments, which are assumed to already be in UTF-8 format and pass through with no conversion
Answers:
<SequenceableCollection> of <String | ByteArray>
</code></pre> </details>
<details> command:
<pre><code> Set the builder's Os program and arguments. All program and arguments, if required, will be converted into UTF-8 from the current code page
@note: Any element in @progAndArgs that is a <ByteArray>
will not be converted, as <ByteArray>s are assumed to already
be in UTF-8 format.

@progAndArgs is a <SequenceableCollection>,
where the first element is the program name
and any remaining elements will be the arguments.

@progAndArgs can also be a <String | ByteArray>, which is treated
as the program name with no arguments.

Arguments:
progAndArgs - <String | ByteArray> program name (no arguments)
<SequenceableCollection> of <String | ByteArray> program and arg names
Answers:
<OsProcessStarter>
</code></pre> </details>
<details> detached
<pre><code> Answer true if the process should run in 'detached' mode, false otherwise. A detached process is one that will keep running even after VAST exits. Default: A non-detached process is one whose lifecycle is connected to VAST. If VAST exits, then a non-detached process closes along with all its contained processes.
Answers:
<Boolean>
</code></pre> </details>
<details> detached:
<pre><code> Set true if the process should run in 'detached' mode, false otherwise. A detached process is one that will keep running even after VAST exits. Default: A non-detached process is one whose lifecycle is connected to VAST. If VAST exits, then a non-detached process closes along with all its contained processes.
Answers:
<Boolean>
</code></pre> </details>
<details> engine
<pre><code> Answer the identifier of the execution engine to be used to spawn new subprocesses @see OsProcessStarter>>engine: for a detail description
Identifier:
OsProcessConstants::ProcEngineDefault
OsProcessConstants::ProcEngineFork
OsProcessConstants::ProcEngineVFork
OsProcessConstants::ProcEnginePosixSpawn
OsProcessConstants::ProcEngineCreateProcess
OsProcessConstants::ProcEngineUnixProcCompat
nil (alias for OsProcessConstants::ProcEngineDefault)

Answers:
<Integer>
</code></pre> </details>
<details> engine:
<pre><code> Set the execution engine to be used to spawn new subprocesses. @anEngine can be one of
OsProcessConstants::ProcEngineDefault OsProcessConstants::ProcEngineFork OsProcessConstants::ProcEngineVFork OsProcessConstants::ProcEnginePosixSpawn OsProcessConstants::ProcEngineCreateProcess OsProcessConstants::ProcEngineUnixProcCompat nil (alias for OsProcessConstants::ProcEngineDefault)
All Platforms:
ProcEngineDefault - Use the default engine for the platform
Windows Default: ProcEngineCreateProcess
Unix Default: ProcEnginePosixSpawn

Windows:
ProcEngineCreateProcess - Uses the CreateProcess API to spawn new subprocesses

Unix:
ProcEngineFork - Uses fork()/exec() to spawn new subprocesses
ProcEngineVFork - Uses vfork()/exec() to spawn new subprocesses
ProcEnginePosixSpawn - Uses posix_spawn() to spawn new subprocesses
ProcEngineUnixProcCompat - Internal: Used by deprecated UnixProcess for compatibility

Arguments:
anEngine - <Integer> @see OsProcessConstants::ProcEngine*
Raises:
<Exception> invalid execution engine
</code></pre> </details>
<details> environment
<pre><code> Answer an <OsProcessEnvironment> key=value view of the process builder's environment This is initially a copy of the current process environment. Processes started from this builder will use this as the environment
Answers:
<OsProcessEnvironment>
</code></pre> </details>
<details> environment:
<pre><code> Set a key=value view of the process builder's environment This is initially a copy of the current process environment. Processes started from this builder will use this as the environment
Arguments:
envVariables - <OsProcessEnvironment> instance
- <KeyedCollection> of key <String> value <String>
- <SequenceableCollection> of <String> 'key=value'
- nil if using current process env
Answers:
<OsProcessStarter>
</code></pre> </details>
<details> errorBufferSize:
<pre><code> Set the number of bytes to buffer for error (stderr) pipe streams. This setting is only used if redirecting error to its own pipe. If errors are being redirected to output pipes (#redirectErrorToOutput),
then the value of #outputPipeBufferSize will be used. In all other cases, this value will be ignored
Arguments:
anInteger - number of bytes. Buffering is disabled if anInteger is 0
Answers:
<OsProcessStarter>
</code></pre> </details>
<details> inheritError
<pre><code> Inherit error from the parent VAST process stderr.
Answers:
<OsProcessStarter>
</code></pre> </details>
<details> inheritInput
<pre><code> Inherit input from the parent VAST process stdin
Answers:
<OsProcessStarter>
</code></pre> </details>
<details> inheritIO
<pre><code> Inherit input, output and error from the parent VAST process stdin, stdout, stderr
Answers:
<OsProcessStarter>
</code></pre> </details>
<details> inheritOutput
<pre><code> Inherit output from the parent VAST process stdout
Answers:
<OsProcessStarter>
</code></pre> </details>
<details> inputBufferSize:
<pre><code> Set the number of bytes to buffer for input (stdin) pipe streams. This setting is only used if redirecting input to pipes, otherwise it is ignored.
Arguments:
anInteger - number of bytes. Buffering is disabled if anInteger is 0
Answers:
<OsProcessStarter>
</code></pre> </details>
<details> outputBufferSize:
<pre><code> Set the number of bytes to buffer for output (stdout) pipe streams. This setting is only used if redirecting output to pipes, otherwise it is ignored.
Arguments:
anInteger - number of bytes. Buffering is disabled if anInteger is 0
Answers:
<OsProcessStarter>
</code></pre> </details>
<details> processClass
<pre><code> Answer the process class to use when starting new processes It should be compatible with OsVastSubprocess
Arguments:
aProcessClass - <Object>
</code></pre> </details>
<details> processClass:
<pre><code> Set the process class to use. @aProcessClass is intended to be a subclass of OsVastSubprocess. However, it is not required and the custom process class just needs to implement the required methods.
@see OsProcessStarter>>start method for required API impl

Arguments:
aProcessClass - <Object>
</code></pre> </details>
<details> redirectErrorToFile:
<pre><code> Redirect errors to @aFilenameOrPath. The file will be created or truncated if it exists If @aFilenameOrPath is a ByteArray, then it will pass right through with no UTF-8 conversion. Otherwise, we get pass in the string converted form that will be converted to UTF-8.
Arguments:
aFilenameOrPath - <String> or <CfsPath> file on the filesysystem
Answers:
<OsProcessStarter>
</code></pre> </details>
<details> redirectErrorToFile:append:
<pre><code> Redirect errors to @aFilenameOrPath. If @aFilenameOrPath is a ByteArray, then it will pass right through with no UTF-8 conversion. Otherwise, we get pass in the string converted form that will be converted to UTF-8.
If append is true
The file will be opened in atomic append mode
If append is false
The file will be created or truncated if it exists
and opened for writing

Answers:
<OsProcessStarter>
</code></pre> </details>
<details> redirectErrorToNull
<pre><code> Redirect errors to the OS-specific null bucket Do this to ignore errors
Answers:
<OsProcessStarter>
</code></pre> </details>
<details> redirectErrorToOutput
<pre><code> Merge errors with output so they both are redirected to the same location
Answers:
<OsProcessStarter>
</code></pre> </details>
<details> redirectErrorToPipe
<pre><code> Redirect errors to a pipe connected to, and accessible from, OsVastSubprocess>>errorStream
Answers:
<OsProcessStarter>
</code></pre> </details>
<details> redirectInputToFile:
<pre><code> Redirect input to @aFilenameOrPath. If @aFilenameOrPath is a ByteArray, then it will pass right through with no UTF-8 conversion. Otherwise, we get pass in the string converted form that will be converted to UTF-8.
Arguments:
aFilenameOrPath - <String> or <CfsPath> file on the filesysystem
Answers:
<OsProcessStarter>
</code></pre> </details>
<details> redirectInputToNull
<pre><code> Redirect input to the OS-specific null bucket Do this to ignore input
Answers:
<OsProcessStarter>
</code></pre> </details>
<details> redirectInputToPipe
<pre><code> Redirect input to a pipe connected to, and accessible from, OsVastSubprocess>>inputStream
Answers:
<OsProcessStarter>
</code></pre> </details>
<details> redirectIOToNull
<pre><code> Redirect input, output and error to the special NULL descriptor Do this to ignore all input and output (including error)
Answers:
<OsProcessStarter>
</code></pre> </details>
<details> redirectIOToPipes
<pre><code> Redirect input, output and error to pipes connected to the Smalltalk process object Use this if you wish to capture all input and output (including error) as streams that you can programmatically read and write to. These streams will be available on the OsVastSubprocess object
Answers:
<OsProcessStarter>
</code></pre> </details>
<details> redirectOutputToFile:
<pre><code> Redirect output to @aFilenameOrPath. The file will be created or truncated if it exists If @aFilenameOrPath is a ByteArray, then it will pass right through with no UTF-8 conversion. Otherwise, we get pass in the string converted form that will be converted to UTF-8.
Arguments:
aFilenameOrPath - <String> or <CfsPath> file on the filesysystem
Answers:
<OsProcessStarter>
</code></pre> </details>
<details> redirectOutputToFile:append:
<pre><code> Redirect ouptut to @aFilenameOrPath. If @aFilenameOrPath is a ByteArray, then it will pass right through with no UTF-8 conversion. Otherwise, we get pass in the string converted form that will be converted to UTF-8.
If append is true
The file will be opened in atomic append mode
If append is false
The file will be created or truncated if it exists
and opened for writing

Answers:
<OsProcessStarter>
</code></pre> </details>
<details> redirectOutputToNull
<pre><code> Redirect output to the OS-specific null bucket Do this to ignore output
Answers:
<OsProcessStarter>
</code></pre> </details>
<details> redirectOutputToPipe
<pre><code> Redirect output to a pipe connected to, and accessible from, OsVastSubprocess>>outputStream
Answers:
<OsProcessStarter>
</code></pre> </details>
<details> runInShell
<pre><code> Answer true if the command will be spawned using the selected system shell, false otherwise
Answers:
<Boolean>
</code></pre> </details>
<details> runInShell:
<pre><code> Set true if this command should run using the system's shell, false otherwise The default shell for the system is selected. Use #shell: to customize which shell to use.
Arguments:
aBoolean - <Boolean> true to use shell, false otherwise
</code></pre> </details>
<details> shellMode
<pre><code> Answer the identifier of the shell to be used for running
commands in the new subprocesses. @see OsProcessStarter>>shellMode: for a detail description
Identifier:
OsProcessConstants::ProcShellNone
OsProcessConstants::ProcShellDefault
OsProcessConstants::ProcShellCmd
OsProcessConstants::ProcShellPowershell
OsProcessConstants::ProcShellSh
OsProcessConstants::ProcShellBash
OsProcessConstants::ProcShellCsh
OsProcessConstants::ProcShellTcsh
OsProcessConstants::ProcShellKsh
OsProcessConstants::ProcShellZsh
nil (alias for OsProcessConstants::ProcEngineNone)

Answers:
<Integer>
</code></pre> </details>
<details> shellMode:
<pre><code> Set the shell to use for running commands in the new subprocesses. @aShell can be one of
OsProcessConstants::ProcShellNone OsProcessConstants::ProcShellDefault OsProcessConstants::ProcShellCmd OsProcessConstants::ProcShellPowershell OsProcessConstants::ProcShellSh OsProcessConstants::ProcShellBash OsProcessConstants::ProcShellCsh OsProcessConstants::ProcShellTcsh OsProcessConstants::ProcShellKsh OsProcessConstants::ProcShellZsh nil (alias for OsProcessConstants::ProcEngineNone)
All Platforms:
ProcShellNone - Do not use shell with command
ProcEngineDefault - Use the default shell for the platform
Windows Default: ProcShellCmd
Unix Default: ProcShellSh

Windows:
ProcShellCmd - cmd.exe
ProcShellPowershell - powershell.exe

Unix:
ProcShellSh -Bourne Shell (/bin/sh)
ProcShellBash - Bourne-again Shell (/bin/bash)
ProcShellCsh - C Shell (/bin/csh)
ProcShellTcsh - TENEX C Shell (/bin/tcsh)
ProcShellKsh - Korn Shell (/bin/ksh)
ProcShellZsh - Z Shell (/bin/zsh)

Arguments:
aShell - <Integer> @see OsProcessConstants::ProcShell*
Raises:
<Exception> invalid shell
</code></pre> </details>
<details> start
<pre><code> Starts a new process by invoking the @command in the working directory (@workingDirectory), with the associated @environment and stdio specifications.
A new subprocess object will be immediatley answered which
is the handle to the subprocess that has started execution.

@Note: Direct instvar refs are to ensure we pass the UTF-8
form of the instance field without conversion

Answers:
<OsVastSubprocess>
Raises:
<OsProcessException>
</code></pre> </details>
<details> tracingEnabled
<pre><code> Answer true if process execution tracing is enabled, false otherwise
Answers:
<Boolean>
</code></pre> </details>
<details> tracingEnabled:
<pre><code> Set true if process execution tracing should be enabled, false otherwise
Arguments:
aBoolean - <Boolean>
</code></pre> </details>
<details> tuneForDeadlockAvoidance
<pre><code> Set stdout and stderr with the 'autoFill' flag.
This has the following impact:
1. Stdout and stderr buffers are filled just prior to a write to stdin via smalltalk pipe streams
2. A deadlock avoidance ST process is created to fill stdout, stderr in a polling manner.

Note: This only impacts stdout and/or stderr that are redirected to smalltalk pipe streams
</code></pre> </details>
<details> tuneForInteractive
<pre><code> Set stdin with the 'autoFlush' flag.
This has the following impact:
1. The bytes written to smalltalk pipe streams are immediately flushed to stdin.
* For interactive conversations, we don't want to buffer up conversations into
* the smalltalk buffers. We want them to go straight to stdin to get the desired impact.
2. @see #tuneForDeadlockAvoidance for additional impacts.

Note: This only impacts stdin, stdout and stderr that are redirected to smalltalk pipe streams
</code></pre> </details>
<details> workingDirectory
<pre><code> Answer the process builder's working directory This will be used as the working directory of subprocesses started by this builder. By default, this value is converted from UTF-8 to the current code page. An exception to this is if the directory is a ByteArray, which is assumed to already be in UTF-8 format and pass through with no conversion
Answers:
<String | ByteArray> - process builder's working directory
<UndefinedObject> - nil if using CWD of the processs
</code></pre> </details>
<details> workingDirectory:
<pre><code> Set the process starter's working directory This will be used as the working directory of subprocesses started by this starter.
Arguments:
aDirectoryPath - <String> process starter's working dir string
- <UndefinedObject> - nil if current working directory should be used
Answers:
<OsProcessStarter>
</code></pre> </details>
Last modified date: 07/07/2022