[comp.sys.atari.st] A proposal for extended ARG passing

trb@stag.UUCP ( Todd Burkey ) (10/15/87)

 remote from syntel
Date: Tue, 13 Oct 87 02:00:10 CDT
To: trb
From: syntel!dal@stag.UUCP (Dale Schumacher)
Subject: Extended Argument Passing Proposal
Message-Id: <1013870200100132@syntel.UUCP>

			-------------------------------

		A PROPOSAL FOR EXTENDED ARGUMENT PASSING IN C.
		  by David (orc) Parsons and Dale Schumacher

			-------------------------------

    Why change argc/argv in the first place?  Well, there are times where
(a) it would be nice to have more than 128 bytes of commandline, (b) it
would be nice to pass arguments to a child process without having the
startup code in the child process retokenize (spaces inside of an argument,
tokens containing `>', `<', `*', and `?', etc.) and (c) it's nice to have
a more Un*x-like interface for argc/argv.

    The method employed by Mark Williams involves making a mess of the
already confused environment string.  We would like to suggest a cleaner
way of handling extended arguments.  Of course, the normal command line
image will have to be supported for programs which don't understand the
extended format, and the extended format must be validated in some way,
but these are fairly trivial problems.

    What we'd like to do is this.  Take an unused/reserved location in the
process basepage (aka TPA), perhaps the "reserved" pointer field located
at offset 0x28, as a pointer to an argument structure (Any problems with
using this location, Atari?  More information about what's really in the
rest of the basepage would be very helpful).  The structure would be:

	struct {
		char	xarg_magic[4];		/* verification value */
		int	xargc;			/* argc */
		char	**xargv;		/* argv */
		char	*xiovector;		/* i/o stream status */
	}

    The <xarg_magic> value in some preset constant like "xArg", and serves
to validate the extended argument format.  <xargc> holds the normal <argc>
value.  <xargv> is a pointer into the parent's dataspace where the list of
<argv> argument pointers is stored.  Obviously, the <argv> values would also
reside in the parent, and should be copied by the child process as part of
the startup procedure.  <xiovector> is either NULL, indicating that this
feature is not supported, or points to a '\0' terminated string which
describes the state of the i/o streams.  Only the characters [CAPF?] are
valid in the <xiovector> string.  These represent <C>onsole, <A>ux port,
<P>rinter, <F>ile and <?>unknown.  This feature is present mostly to
allow operation similiar Mark Williams, if desired.

    To support this convention, a custom set of exec()-like functions
are created.  They basically create both the command line image and the
extended parameter structure, then "load no go" the process, modify the
basepage accordingly and then "just go" to execute the process.  The next
version of the dLibs public domain C libraries (and also the next release
of the STadel BBS) are planned to support this extended argument format.
If there is interest, the sources for these routines could be posted to
this newsgroup.

    Please direct all flames (or even nice comments) to:
	..ihnp4!meccts!stag!syntel!dal	-or-  syntel!dal@stag.UUCP
	..ihnp4!meccts!stag!pell!orc	-or-  pell!orc@stag.UUCP

                Dale Schumacher
                ..ihnp4!meccts!stag!syntel!dal
                (alias: Dalnefre')

apratt@atari.UUCP (Allan Pratt) (10/19/87)

Please consider my proposal again.  You may have missed it.  First, here
are the reasons that yours won't work (the second one is deadly):

in article <242@stag.UUCP>, trb@stag.UUCP ( Todd Burkey ) says:
> 			-------------------------------
> 
> 		A PROPOSAL FOR EXTENDED ARGUMENT PASSING IN C.
> 		  by David (orc) Parsons and Dale Schumacher
> 
> 			-------------------------------
> [...]
>
>     What we'd like to do is this.  Take an unused/reserved location in the
> process basepage (aka TPA), perhaps the "reserved" pointer field located
> at offset 0x28, as a pointer to an argument structure (Any problems with
> using this location, Atari?  More information about what's really in the
> rest of the basepage would be very helpful).  

Reason number 1:

Reserved things (in the basepage and elsewhere) are reserved for two
reasons: (A) we don't want people mucking around with them, and (B) we
want to be able to change them later.  The basepage is especially
important in this regard, because people mucking around with it can
cause LOTS of trouble, and because we REALLY MIGHT change it -- after
all, it contains almost all the process-specific information in the
system. 

> [...]
>
>     To support this convention, a custom set of exec()-like functions
> are created.  They basically create both the command line image and the
> extended parameter structure, then "load no go" the process, modify the
> basepage accordingly and then "just go" to execute the process.

Reason number 2: 

Pexec "load/nogo" followed by "just go" doesn't work.  When the child
terminates, its memory is not freed because it is still "owned" by the
parent.  It gets freed when the parent terminates, but if the parent is
a shell, it will probably never terminate. 

Yes, this is a bug.  Yes, it can be fixed and will be.  No, the fix
won't be available soon (because it and other fixes in the works will
need extensive testing).


My proposal:

The only problems with the MWC trick of putting args in the environment
are (1) it defies the definition of the environment (but I can deal with
that), and (2) you can't tell if the args in the environment are really
intended for you.

The reason I like the MWC trick is that it works within the system,
rather than using reserved memory which Atari might snatch away from you.

The way to fix the MWC trick is to place the basepage address of the
process doing the exec'ing in the environment along with the ARGV string.
That way, the child which inherits this environment can compare the address
in the environment with its parent's basepage address (found in the child's
basepage).  If they match, the args are intended for it.  If they don't,
it uses the command line in the basepage.

The reason for this runaround is that some programs exec children the
old-fashioned way.

Let's say your shell is smart (uses ARGV) and your compiler is smart,
but your editor isn't (it can exec children, but only with old-fashioned
args in the command line).  You type "edit foo.c" so ARGV=/EDIT/FOO.C//
gets put in the environment (where / represents a null byte).  You edit,
then exec the compiler from within the editor (I do it all the time),
with the args "-o foo.prg foo.c.  The compiler gets ARGV=/EDIT/FOO.C//
in its environment, but "-o foo.prg foo.c" in its command line.  What
does it do? If it's compiled with MWC, it uses the ARGV in the
environment.  You lose. 

If the compiler could tell that the args in the environment didn't come
from its immediate parent, it wouldn't get confused.

Therefore I propose a new standard: place the environment variable
"PARENT=xxxxxxxx" in the environment (anywhere), where the eight x's
are the hex address of the basepage of the process doing the exec'ing.
The code which decodes the environment converts this value from ASCII back
into hex and compares it with the parent's basepage address supplied in
the basepage.  If they don't match, it takes the args from the basepage
command line.

============================================
Opinions expressed above do not necessarily	-- Allan Pratt, Atari Corp.
reflect those of Atari Corp. or anyone else.	  ...ames!atari!apratt

"When you prick me, do I not leak?"  -- Data