SystemTagList() inconsistency

This forum is for general developer support questions.
Post Reply
softwarefailure
Posts: 112
Joined: Fri Feb 14, 2014 10:29 pm

SystemTagList() inconsistency

Post by softwarefailure »

Consider the following code:

Code: Select all

SystemTags("echo hello",
	SYS_Output, 0,
	SYS_Input, 0,
	SYS_Asynch, TRUE,
	SYS_UserShell, TRUE,
	NP_StackSize, 32768,
	NP_Priority, 0,
	NP_Path, 0,
	TAG_DONE);
On AmigaOS 3 and MorphOS this will print "hello" to the host program's stdout. On AmigaOS 4, however, nothing will be printed. I can fix this by simply removing "SYS_Output,0" from the tag list but I'm still wondering whether this is a bug in OS4 because the behaviour is clearly inconsistent to the behaviour on OS3 and MorphOS. And it's also inconsistent to Execute() behaviour. Consider the following code:

Code: Select all

Execute("echo hello", 0, 0);
The code above prints "hello" to stdout on all three platforms: OS3, OS4, MorphOS. So setting a 0 output handle with Execute() seems to behave differently to setting a 0 output handle for SystemTagList() on OS4...

Is this a bug or a deliberate design decision to break with OS3/MorphOS behaviour considering the interpretation of a 0 filehandle for SYS_Output?
xenic
Posts: 1185
Joined: Sun Jun 19, 2011 12:06 am

Re: SystemTagList() inconsistency

Post by xenic »

softwarefailure wrote:Consider the following code:

Code: Select all

SystemTags("echo hello",
	SYS_Output, 0,
	SYS_Input, 0,
	SYS_Asynch, TRUE,
	SYS_UserShell, TRUE,
	NP_StackSize, 32768,
	NP_Priority, 0,
	NP_Path, 0,
	TAG_DONE);
On AmigaOS 3 and MorphOS this will print "hello" to the host program's stdout. On AmigaOS 4, however, nothing will be printed. I can fix this by simply removing "SYS_Output,0" from the tag list but I'm still wondering whether this is a bug in OS4 because the behaviour is clearly inconsistent to the behaviour on OS3 and MorphOS. And it's also inconsistent to Execute() behaviour.
OS4 AmigaDOS is an updated/improved version. There are lots of changes. The OS4 DOS autodoc states that setting SYS_Input to zero will result in NIL: being opened for input and that setting SYS_Output to zero will have SYS_Output use the SYS_Input stream. You've reported the inconsistancy between OS4 & OS3 treatment of SYS_Input set to zero but I doubt if Colin is going to change it at this point.
Consider the following code:

Code: Select all

Execute("echo hello", 0, 0);
The code above prints "hello" to stdout on all three platforms: OS3, OS4, MorphOS. So setting a 0 output handle with Execute() seems to behave differently to setting a 0 output handle for SystemTagList() on OS4...
The Execute() command is deprecated and not even listed in the main OS4 DOS autodoc. It probably still works to support 68k programs.
Is this a bug or a deliberate design decision to break with OS3/MorphOS behaviour considering the interpretation of a 0 filehandle for SYS_Output?
I'd say it is deliberate but Colin may give a better explanation if he reads this topic.
AmigaOne X1000 with 2GB memory - OS4.1 FE
User avatar
broadblues
AmigaOS Core Developer
AmigaOS Core Developer
Posts: 600
Joined: Sat Jun 18, 2011 2:40 am
Location: Portsmouth, UK
Contact:

Re: SystemTagList() inconsistency

Post by broadblues »

This is broken code IMHO

Code: Select all

SystemTags("echo hello",
   SYS_Output, 0,
   SYS_Input, 0,
   SYS_Asynch, TRUE,
   SYS_UserShell, TRUE,
   NP_StackSize, 32768,
   NP_Priority, 0,
   NP_Path, 0,
   TAG_DONE);
do something like this instead

Code: Select all


#if defined(__amigaos4__)
	                    BPTR in = DupFileHandle(Input());
    	                BPTR out = DupFileHandle(Output());
#else
						BPTR in = Open("NIL:",MODE_NEWFILE);
						BPTR out = 0;
#endif
		            	SNPrintf(buffer,len,"%s %s",p,portname);
		            	
                	    if(0 > SystemTags((CONST_STRPTR)buffer, 
                                                SYS_UserShell,TRUE,
                                                SYS_Asynch,TRUE,
                                                SYS_Input,in,
                                                SYS_Output,out,
                                                TAG_DONE))
	                    {
                        /* we failed so clean up dupped handles */
    	                    if(in)
        	                {
	        	                Close(in);
	            	        }
                    	    if(out)
                        	{
	                        	Close(out);
		                    }
    	                }
User avatar
colinw
AmigaOS Core Developer
AmigaOS Core Developer
Posts: 207
Joined: Mon Aug 15, 2011 9:20 am
Location: Brisbane, QLD. Australia.

Re: SystemTagList() inconsistency

Post by colinw »

softwarefailure wrote: Is this a bug or a deliberate design decision to break with OS3/MorphOS behaviour considering the
interpretation of a 0 filehandle for SYS_Output?
SYS_Output has not changed, SYS_Input has, and just by using ZERO for SYS_Input in your example means that
you do not understand the ramifications. There is no documentation to say that ZERO can be used here,
this is exactly the reason why passing a ZERO SYS_Input tag now causes System() to open "NIL:" by default.

This is required to fix a bunch of issues with older applications using ancient startup code,
or programs that didn't always check for invalid streams and went on to access invalid memory addresses,
at the same time, it provides a consistent and safer behaviour for 68K and PPC programs that doesn't end
in a crash or memory trashing if the user was unaware of the ramifications.

System() used a ZERO SYS_Output argument as a local switch to make a copy of the input stream even in OS3.xx,
which means you always needed to have a valid input stream, via SYS_Input, or inherited from the parent.
The result of this usually ended up in the new process structure in ->pr_CIS ie: Input().

ZERO is not a valid filehandle and is (mis)interpreted differently everywhere the input or output stream
was used and sometimes coders didn't even considered ZERO to be a possibility.


Here's a list of things that immediately come to mind when passing an input filehandle of ZERO,
these are clipped directly from the various autodocs....

System(ASYNC):
* 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.

RunCommand():
* If an Input() stream of zero is supplied, the argument string in
* the input filehandle feature will not be available to the command.
* This means that ReadArgs() and other parsers will not work, ...


There are more issues like this scattered around all over the place, these are now safe in OS4,
but previous OS versions and possibly other flavours of AmigaOS may not have discovered
these issues, how they respond is unknown.
Post Reply