OsProcessStarter
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.
Its 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
command:
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>
new
Answer a new initialized instance of this process starter.
Answers:
<OsProcessStarter>
shell:
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>
start:
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>
startShell:
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>
Instance Methods
&&
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>
=>
Answer a sequence pipeline chain.
aSequenceableStarter will start as soon as this process starter finishes
Arguments:
aSequenceableStarter - <OsProcessStarter | OsPipelineStarter | OsPipelineChainStarter>
Answers:
<OsPipelineChainStarter>
|
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>
||
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>
autoFillError:
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>
autoFillOutput:
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>
autoFlushInput:
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>
command
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>
command:
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>
detached
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>
detached:
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>
engine
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>
engine:
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
environment
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>
environment:
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>
errorBufferSize:
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>
inheritError
Inherit error from the parent VAST process stderr.
Answers:
<OsProcessStarter>
inheritInput
Inherit input from the parent VAST process stdin
Answers:
<OsProcessStarter>
inheritIO
Inherit input, output and error from the parent VAST process stdin, stdout, stderr
Answers:
<OsProcessStarter>
inheritOutput
Inherit output from the parent VAST process stdout
Answers:
<OsProcessStarter>
inputBufferSize:
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>
outputBufferSize:
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>
processClass
Answer the process class to use when starting new processes
It should be compatible with OsVastSubprocess
Arguments:
aProcessClass - <Object>
processClass:
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>
redirectErrorToFile:
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>
redirectErrorToFile:append:
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>
redirectErrorToNull
Redirect errors to the OS-specific null bucket
Do this to ignore errors
Answers:
<OsProcessStarter>
redirectErrorToOutput
Merge errors with output so they both
are redirected to the same location
Answers:
<OsProcessStarter>
redirectErrorToPipe
Redirect errors to a pipe connected to, and accessible from,
OsVastSubprocess>>errorStream
Answers:
<OsProcessStarter>
redirectInputToFile:
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>
redirectInputToNull
Redirect input to the OS-specific null bucket
Do this to ignore input
Answers:
<OsProcessStarter>
redirectInputToPipe
Redirect input to a pipe connected to, and accessible from,
OsVastSubprocess>>inputStream
Answers:
<OsProcessStarter>
redirectIOToNull
Redirect input, output and error to the special NULL descriptor
Do this to ignore all input and output (including error)
Answers:
<OsProcessStarter>
redirectIOToPipes
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>
redirectOutputToFile:
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>
redirectOutputToFile:append:
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>
redirectOutputToNull
Redirect output to the OS-specific null bucket
Do this to ignore output
Answers:
<OsProcessStarter>
redirectOutputToPipe
Redirect output to a pipe connected to, and accessible from,
OsVastSubprocess>>outputStream
Answers:
<OsProcessStarter>
runInShell
Answer true if the command will be spawned using the selected system shell,
false otherwise
Answers:
<Boolean>
runInShell:
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
shellMode
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>
shellMode:
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
start
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>
tracingEnabled
Answer true if process execution tracing is enabled, false otherwise
Answers:
<Boolean>
tracingEnabled:
Set true if process execution tracing should be enabled, false otherwise
Arguments:
aBoolean - <Boolean>
tuneForDeadlockAvoidance
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
tuneForInteractive
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
workingDirectory
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
workingDirectory:
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>
Last modified date: 02/23/2021