Asynchronous err = SystemTags() and error return
Posted: Fri Oct 17, 2025 4:46 pm
by gdridi
Hello!
I 'm using err = SystemTags() with SYS_ASYNC and the error return are weird.
Is it possible that the asynchronous call of SystemTags () prevents good error returns.
That is error == -1 or error with IoErr() set accordingly.
Peculiarly calling with SystemTags(cmd, SYS_ASYNC) :
1. "dir SDK: poil" would like "bad number of arguments" err=118
2. "dir SDK007:" would like "could not find file or device" err=205
Thank you a lot for testing and replies,
DGILLES - Arabic console
Re: Asynchronous err = SystemTags() and error return
Posted: Sat Oct 18, 2025 4:57 am
by colinw
dos.library/System dos.library/System
NAME
System -- Have a shell handler execute a command line. (V36)
SYNOPSIS
int32 error = System(CONST_STRPTR command,
const struct TagItem *tags);
int32 error = SystemTagList(CONST_STRPTR command,
const struct TagItem *tags);
int32 error = SystemTags(CONST_STRPTR command, uint32 Tag1, ...);
FUNCTION
System() spawns a new Shell handler process to execute the command,
returns the return code the command produced, or -1 if the command
could not be run for any reason.
Normal Shell command-line parsing will be done including redirection
on the command.
This function has two primary modes, Synchronous and Asynchronous,
this is controlled by the boolean tag; SYS_Asynch.
Asynchronous commands cause this function to return immediately,
while Synchronous commands will wait until command execution finishes.
Each mode has different requirements and ramifications when dealing
with the filehandles. It is very important to follow these rules;
() Synchronous execution will NOT close any filehandles when the
command returns, if supplying your own via the tags SYS_Input,
SYS_Output or SYS_Error, you must close them (if needed).
If a tag is NOT specified, it will default to using the calling
process' respective filehandle, ie; Input(), Output(), ErrorOutput().
() Asynchronous execution WILL close both input and output filehandles
and conditionally the error filehandle (depending on SYS_CloseError)
after executing the command, even if these were the caller process'
inherited Input() and Output() filehandles, so be well warned !!
To stay out of trouble in Asynch mode, both SYS_Input and SYS_Output
should generally be specified and should not be allowed to default
to the inherited parents' filehandles, unless this is intentional.
It is legal to use DupFileHandle() on the parent filehandles,
but check the result as it is possible to have duplication failure
and the result will be 0, which is "NIL:" and may not be intended.
The ErrorOutput() stream is never inherited in Asynch mode,
as the default is ZERO.
The SYS_Error tag is required for anything else and also the
SYS_CloseError tag must also be used if you want it to be closed.
() If command output is not required, it is always safe to pass
ZERO to both the SYS_Input and SYS_Output tags, this results in
the function using "NIL:" for the shell handler process. (V53.65+)
() If input and output are to both be to the same CON: window,
pass a filehandle for a CON: window in SYS_Input and then pass a
SYS_Output of ZERO. The shell handler will automatically set the
default Output() filehandle to the window you passed via SYS_Input.
() Specifying a SYS_Error filehandle is optional and won't result in
loss of output as software such as CLIB and DOS functions will
default to using the Output() filehandle when ErrorOutput() is ZERO.
Functions like PutErrStr() and PrintFault() mention this.
() NEVER under any circumstances, should you pass the same filehandle
to more than one tag. SYS_Input, SYS_Output and SYS_Error must
never share the same non-zero filehandle in any execution mode.
A copy of the current directory and path list will be inherited from
the calling process by default, if it has one, otherwise tags below
allow for alternatives. The path and current directory are used to
find the command for execution.
This function normally uses the resident boot shell-handler,
but other shells can be specified via SYS_UserShell and SYS_CustomShell.
Normally, things from a user are sent to the UserShell.
The UserShell defaults to the same shell as the boot shell handler.
INPUTS
command - (STRPTR) Program name and arguments to start as from a shell.
TAGS
SYS_Input (BPTR) -- Input filehandle; defaults to the parent.
Passing a ZERO value with this tag will cause
this function to internally open "NIL:" (V53.65+)
SYS_Output (BPTR) -- Output filehandle; defaults to the parent.
Specify ZERO for a copy of the SYS_Input stream.
SYS_Error (BPTR) -- Error Output filehandle; (mode dependant),
For SYS_ASynch,FALSE - defaults to the parent.
For SYS_ASynch,TRUE - defaults to ZERO.
This is not closed unless SYS_CloseError,TRUE
SYS_CloseError (int32; boolean) -- Due to legacy compatibility issues
DOS is unable to allow the SYS_Error stream to be closed by default.
You must specify this tag as TRUE to have it automatically close
the SYS_Error filehandle on exit, if one is supplied.
SYS_Asynch (int32; boolean) -- If TRUE, this function will return
as soon as the child shell handler process has been started.
If FALSE, this function will wait for the shell command to finish.
Defaults to FALSE.
SYS_ExecuteInputStream (int32; boolean) -- When TRUE, the 'command'
string parameter will be ignored, (set it to "" or 0),
and then the input file handle will be used to read shell commands,
this filehandle is supplied via the SYS_Input tag.
SYS_Asynch tag will currently be forced to FALSE when this tag
is specified, but do not depend on this behaviour for the future.
The input file handle may also be a console descriptor to
spawn a new syncronous interactive shell process. (V53.45+)
SYS_UserShell (int32; boolean) -- TRUE makes the user resident "Shell"
execute the command, while FALSE makes a custom shell specified
by SYS_CustomShell execute the command.
If no SYS_CustomShell is specified, "BootShell" will be the name
of the default resident handler.
If this tag is TRUE, the SYS_CustomShell tags will be ignored.
Defaults to FALSE.
SYS_CustomShell (STRPTR) -- Make this specified shell handler execute
the program instead of the default. The parameter must be the
name of the shell handler to use, as found on the dos resident
segment list. The function IDOS->FindSegment() is used internally
for this, to obtain the seglist to the specified shell handler.
This tag is ignored if the tag 'SYS_UserShell,TRUE' was specified
Defaults to "BootShell".
SYS_CurrentDir (BPTR) -- Current directory for the shell process.
Defaults to a DupLock() copy of the parent's current directory.
SYS_StackSize (int32) -- The stack size the shell process should use.
Defaults to the DOS prefs minimum value or the same as the parent
task (whatever is larger) when this tag is not specified.
SYS_Name (STRPTR) -- Name of the shell process.
Defaults to "Background CLI" if no tag is specified.
The shell process' task structure; task->tc_Node.ln_Name will
point to the DOS allocated buffer to where this string is copied.
The exec function FindTask() searches on this string.
SYS_CopyVars (int32; boolean) -- Indicate whether the local variables
associated with the parent should be copied for the shell process.
Defaults to TRUE.
SYS_Path (BPTR) -- BCPL pointer to a 'struct PathNode' chain
which should be used for the shell process.
Note: this path is used as is and NOT duplicated.
It will be freed automatically when the shell process exits and
must be freed manually if the shell process could not be created.
See; dos.doc/#?CmdPath#?.
SYS_Priority (int8; -128 .. 127) -- Task priority of the shell process.
Defaults to the same as the parent.
SYS_WindowPtr (APTR) -- Indicate where dos.library requesters should
be displayed for the shell process (on the Workbench screen,
a custom screen or not at all).
Defaults to the same value as the parent process only if it is
a value of 0 or -1 and the parent is a process and the SYS_ASynch
tag is FALSE, otherwise it will be 0.
EG; A value of 0, indicates requesters should be displayed on
the default public screen. (Usually WorkBench)
A value of -1 indicates that no requesters shall be shown.
Otherwise, a pointer to an open intuition window that all
requesters should be opened on.
RESULT
error -- 0 for success.
Depending on the mode used, the result value returned can mean
different things;
SYS_Asynch,TRUE:
-1 = indicates System() failure.
0 = indicates System() success,
SYS_Asynch,FALSE:
-1 = indicates System() failure.
n = non-zero program error.
0 = indicates program success. (no error)
Note that ONLY with a -1 error code, the caller is responsible for
deallocating filehandles, paths or other things passed in via tags.
-1 error codes will be returned if DOS could not find the shell,
or was otherwise unable to start the new shell process.
Consult IoErr() to find out what actually happened.
NOTES
From V37+, if an input filehandle is passed, and it's either
interactive or a "NIL:" filehandle, the pr_ConsolePort of the new
handler process will be set from that filehandle's port.
This function will also send an ACTION_CHANGE_SIGNAL dospacket to the
input stream handler upon startup, and again upon returning, restoring
the sigtask to the parent process. (the same applies to old Execute()).
From 51.77 If an ASYNCH command was started ok, (returncode 0)
the new process identifier (PID), from the shell process structure field
process->pr_ProcessID, may be obtained by calling IoErr() immediately
after this function returns. Note that PID numbers can never be zero.
Some additional NP_xxx tags are allowed to be passed through to the
internal CreateNewProc() call which starts up the shell handler process,
this allows for setting up some esoteric things that are not covered
by the SYS_xxx tags, for the safer functions, SYS_xxx tags have been
provided as aliases, other ones that could be problematic are not,
only experienced users should use them and only when understanding
the possible ramifications.
Some NP_xxx tags cannot be allowed to be passed directly, but instead
these are generally sent via the startup packet for the shell-handler
during initialisation, or are a handler process creation attribute,
or via dedicated SYS_xxx tags, so the following tags will conflict and
will always be filtered out from any user tags that are supplied;
NP_Start -- Not used.
NP_Seglist -- SYS_UserShell, SYS_CustomShell determins this.
NP_FreeSeglist -- Always FALSE.
NP_Input -- Always 0, Sent via the handler startup packet.
NP_CloseInput -- Always FALSE.
NP_Output -- Always 0, Sent via the handler startup packet.
NP_CloseOutput -- Always FALSE.
NP_Error -- SYS_Error passes this via the handler process.
NP_ProgramDir -- Set by the shell handler.
NP_Cli -- Always TRUE, we definately need one of these.
BUGS
Before 53.65 launching asynch commands from a workbench started process
that use clib/newlib wrappers would initialise their own pr_ConsolePort
and close it when that process ends, if an ASYNCH child shell process
was started with the SYS_Input tag set to ZERO, it would copy the
parents pr_ConsolePort which would leave the new ASYNCH child process
using a dead pr_ConsolePort when the parent process exits.
So now, specifying a ZERO input stream automatically opens "NIL:"
no matter what mode is used, this will circumvent the problem.
SEE ALSO
<dos/dostags.h>, Input(), Output(), ErrorOutput(), DupFileHandle(),
ProcessScan(), NotifyProcListChange(),
AddCmdPathNode(), DupCmdPathList(), FreeCmdPathList(),
SetCurrentCmdPathList(), SearchCmdPathList(), RemoveCmdPathNode().
Re: Asynchronous err = SystemTags() and error return
Posted: Sat Oct 18, 2025 2:59 pm
by gdridi
Hello!
. . .
RESULT
error -- 0 for success.
Depending on the mode used, the result value returned can mean
different things;
SYS_Asynch,TRUE:
-1 = indicates System() failure.
0 = indicates System() success,
SYS_Asynch,FALSE:
-1 = indicates System() failure.
n = non-zero program error.
0 = indicates program success. (no error)
So if system() called with SYS_Asynch,TRUE and a AmigaDOS cmd fail on error (not the Shell) ,
There’s no way to retrieve the error reason by a call IoErr().
That’s what i proved with my program but wanted a confirmation.
DGILLES - Arabic console os4depot.net -
Re: Asynchronous err = SystemTags() and error return
Posted: Sun Oct 19, 2025 9:58 am
by colinw
Basically true, as it says;
; Asynchronous commands cause this function to return immediately,
; while Synchronous commands will wait until command execution finishes.
So, it's pretty difficult to return the result of the command if the spawning shell
process returns immediately before the command even finishes running.
So I would recommend not using ASYNC mode, then there is no issue.
However, if you must run async, there is a convoluted way to get the shell command
return code and error number when the command does eventually terminate.
But - you will have to either use global variables or bundle the data in a message and
return it to the parent process when it finishes.
You were part of the topic 7 months ago.
viewtopic.php?t=5081&start=10