[comp.sys.atari.st] Another proposal for passing argv

preston@felix.UUCP (Preston Bannister) (08/08/87)

I had some rather non-obvious problems with one of my makefiles.  It
turned out that the cause of the problem with the way the program
arguments were passed between Gulam and programs compiled with MWC.

Mark Williams and Beckmeyer have agreed on a convention for passing the
argv[] style argument list.  The argument list is passed as a part of
the environment (pointed to in the basepage).  The format is something
like:

	<sequence of normal null-terminated strings>
	ARGV=CCCPA???????????????\0	; exact sequence of C|P|A|F|? varies
	<arg[0] string>\0
	<arg[1] string>\0
	  :        :
	<arg[argc-1] string>\0
	\0				; two nulls end the environment

There are two main advantages in passing the argument list like this:

1.  The name of the program (in argv[0]) is availible.

    This is useful if you have a program that might perform different
    functions if named differently (an example might be a program that
    either moved or copied lists of files depending on if it was named
    'mv' or 'cp').

2.  Long argument lists can be passed.

    TOS limits the parameter list to a 127 character string.  While
    you or I might not typically type in more than 127 characters to a
    command, a shell that does wildcard expansion can easily pass that
    limit.  With an argv[] style parameter list you can pass an
    essentially unlimited number of arguments.

Also the string after 'ARGV=' indicates the type of the (up to) 20
files open when the program was invoked (where C = console, P =
parallel port, A = serial port, F = file, ? = not open).  This
information is useful and is necessary for I/O redirection to work
from the console.

(I believe the above explanation is correct.  Someone correct me if
I'm wrong :-)


The problem with the above scheme is that a program that does not
recognize the special form of the ARGV list may pass the environment on
to it's child unchanged.  If the child _does_ recognize the ARGV list
in the environment, and the parent re-directed files or wanted to pass
a different argument list, the child will be using the _wrong_
information.

What we really need is a means for passing argument lists that will
not be accidently propagated by ignorant programs.  

(You don't think I would have typed all this if I didn't have a
suggestion, do you? :-)

Apparently MSDOS 3.x uses a scheme that would fit our requirements. 
If we change the above representation of the environment as follows:

	<sequence of normal null-terminated strings>
	\0				; two nulls end the environment
	\1				; indicates argv argument
	\0				;   list follows...
	CCCPA???????????????\0	; exact sequence of C|P|A|F|? varies
	<arg[0] string>\0
	<arg[1] string>\0
	  :        :
	<arg[argc-1] string>\0
	\0				; two nulls end argument list

Programs that were oblivious to the extended argument passing scheme 
would stop copying the environment list when the first two consecutive
nulls were found.  The extended argument list would not be copied.

The chances of a \1 and a \0 byte immediately following an environment
string seem fairly remote (the people at Atari who have access to the
sources to Pexec could verify this?).

========================================
Preston L. Bannister
USENET	   :	ucbvax!trwrb!felix!preston
BIX	   :	plb
CompuServe :	71350,3505
GEnie      :	p.bannister
--
========================================
Preston L. Bannister
USENET	   :	ucbvax!trwrb!felix!preston
BIX	   :	plb
CompuServe :	71350,3505
GEnie      :	p.bannister

apratt@atari.UUCP (Allan Pratt) (08/12/87)

in article <4659@felix.UUCP>, preston@felix.UUCP (Preston Bannister) says:
> 	<sequence of normal null-terminated strings>
> 	\0				; two nulls end the environment
> 	\1				; indicates argv argument
> 	\0				;   list follows...
> 	CCCPA???????????????\0	; exact sequence of C|P|A|F|? varies
> 	<arg[0] string>\0
> 	<arg[1] string>\0
> 	  :        :
> 	<arg[argc-1] string>\0
> 	\0				; two nulls end argument list
> 
> Programs that were oblivious to the extended argument passing scheme 
> would stop copying the environment list when the first two consecutive
> nulls were found.  The extended argument list would not be copied.
> 

THIS DOESN'T WORK.

You pass a pointer to an environment string to Pexec, and Pexec COPIES
this environment into a Malloc'ed region.  Then Pexec Malloc's the
TPA, loads the program, and launches it.  Naturally, Pexec detects the
end of the environment from the double-null, and won't copy the
rest as suggested above.

The reason it happens like this is to pave the way for ownership of
memory, or for virtual memory, or something: a given process's
environment is in its own address space, not in its parent's address
space. 

But let's look at the problem in some new terms: what you need to do is
establish that the ARGV string in the environment actually came from
your own parent -- that is, the process which Pexec'ed you.  My proposal
is to add an environment variable PARENTBP (or something) and set that
to the basepage address of the parent.  Then the child can check the
parent-basepage address in its own basepage against this environment
variable, and if they match, the ARGV string is valid.  If they don't
match, the child looks in the command line area for its args. 

To formalize the proposal, I submit that the MWC/Beckmeyer trick of
placing arguments in the environment be amended as follows:

1.  Place an environment variable PARENTBP=xxxxxxxx in the environment,
where xxxxxxxx is the basepage address (in 8 hex digits) of the process
doing the Pexec.

2.  When the runtime startup code builds argv[], it should check the
PARENTBP variable value against the parent pointer in its own basepage.
If they don't match, the 127-byte command-line argument area should be
parsed for arguments.

The advantages of this are twofold: it solves the problem unambiguously
with no change to ROMs, and it is tolerant of old shells and old
programs.  New programs started from an old shell will not find PARENTBP,
and will blindly assume that the ARGV string is for them (as they do now),
and old programs started from new shells will not check for PARENTBP,
with the same result.

How about it, gang? Are the shell-writers out there interested in
adopting this standard?  If you can poke any holes in it, please do
so and we'll try to get it right.

/----------------------------------------------\
| Opinions expressed above do not necessarily  |  -- Allan Pratt, Atari Corp.
| reflect those of Atari Corp. or anyone else. |     ...lll-lcc!atari!apratt
\----------------------------------------------/	(APRATT on GEnie)