Path: utzoo!utgpu!jarvis.csri.toronto.edu!mailrus!shadooby!accuvax.nwu.edu!tank!uwvax!per2!dag From: dag@per2.UUCP (Daniel A. Glasser) Newsgroups: comp.sys.atari.st Subject: Extended argument passing conventions in Pexec() [MWC] Summary: MWC responds to the ongoing extended argument debate. Keywords: MWC Pexec Argument Passing Message-ID: <841@per2.UUCP> Date: 11 Apr 89 14:41:31 GMT Reply-To: mwc.uucp!rec Organization: on behalf of Mark Williams Company Lines: 177 [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]] [ The following is posted for a friend at Mark Williams Company. Please ] [ direct replies to mwc.uucp!rec (mwc connects to cbmvax regularly, and ] [ is somewhere in the network maps for Illinois.) ] [ Daniel A. Glasser ] [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]] There has been a lot of noise about argument passing conventions over the past weeks. Atari is proposing an ARGS convention. A group of users is counter-proposing an xArgs convention. These two groups only agree that the MWC ARGV convention must go. My name is Roger Critchlow. I work for Mark Williams. I invented the MWC ARGV argument passing convention in October 1985. I don't think either of the proposed replacements is an improvement. ----------------------------------------------------------------------- Our convention is incomplete because you can't tell if the ARGV was actually passed by your parent or simply passed on by some intervening shell? #include stupid_parent_p() { char *mine = BP->p_env; char *its = BP->p_parent->p_env; while (*mine != 0) if (strcmp(mine, its) == 0) mine += strlen(mine), its += strlen(its); else return 0; /* the environment contains a difference */ return 1; /* the environment is identical to the end */ } This example is only the simplest of many procedural validations of the ARGV convention. You can chase the parent pointers all the way to the desktop and determine who exactly is responsible for each part of the environment in each of the processes active. I don't think that every program which uses ARGV needs be burdened with this sort of validation, but it's clearly possible. ----------------------------------------------------------------------- Our convention is messy because it involves copying arguments around in the environment? But all three proposed argument conventions require copying, and all three pass linkage information in the environment, and the ARGV convention is the most efficient of the three. The ARGS convention requires: 1) The copying of the environment by Pexec() which includes arguments, 2) A scan of the environment to find the arguments, 3) A size scan of the arguments to find out how much buffer is required, 4) then a rescan and copy into a local buffer translating FF into 00, presumably building the argv vector at the same time. The xArgs convention requires: 1) The copying of the environment by Pexec() which excludes arguments, 2) A scan of the environment to find the xArgs pointer, 3) A scan of the xArgs arguments to count up the size of the arguments, 4) then a rescan and copy into a local buffer. The ARGV convention requires: 1) The copying of the environment by Pexec() which includes arguments, 2) A scan of the environment to find the arguments building the envp[] and argv[] vectors in parallel. The ARGS and xArgs proponents are proposing to load more code into the runtime startup to support their proposals. This extra code is to count up the size of some strings, allocate a buffer, and copy the strings into it. What does Pexec() do with the environment pointer? Well it counts up the size of the strings, allocates a buffer, and copies the strings into it. How many independent count-allocate-copies does it take to start a Gemdos process? ARGV rides for free on top of Pexec(), ARGS and xArgs saddle the user process with additional work. ----------------------------------------------------------------------- Programs which ignore the ARGV convention for arguments end up mis-interpreting ARGV specified arguments as environmental variables and passing screwed up environments on to their children. This problem is addressed differently by the ARGS and xArgs proposals. The ARGS convention will allow non-complying programs to pass their arguments onto their children, but the arguments will no longer be misinterpreted as environmental variables. The environment is still polluted with arguments, but the pollution isn't as cruddy as the MWC kind. :-) The xArgs convention passes a pointer, encoded in ascii, to the parent's copy of the xArgs block. { :-) I've always felt that if consenting processes on the ST wanted to pass loaded guns among themselves that was their business, but that the default interprocess communication path shouldn't force processes to be so trusting. } So the environment is still polluted with argument information, but it is even less cruddy than the ARGS crud. :-) In article <156@np1.hep.nl> Geert J v Oldenborgh suggested truncating the environment after extracting the ARGV from it. I think this is an excellent suggestion: it adds one instruction, 2 words, to the runtime startup module and immediately cures one whole class of bugs, the class created by MWC compiled programs doing naive Pexec()'s. I have two solutions for binary programs which screw up the environment by ignoring the ARGV standard but cannot be rebuilt with the improved runtime startup. Both involve the same transformation suggested above. Solution 1 - call the program indirectly through a second program which truncates the environment before passing it on. This would involve renaming the offending program: Frename(0,"numbnuts.prg","numbnuts.ugh"); and then compiling the following interface layer, which assumes that its own runtime startup is stepping on ARGV as discussed above, in its place: #include #include main() { Pterm((int)Pexec(0,"numbnuts.ugh",BP->p_cmdlin,BP->p_env)); } Solution 2 - rewrite the binary of the offending program to incorporate the environment truncation into the offending program's runtime startup. As long as the offending program does not address the process basepage with program-counter relative addressing, this is a simple matter of shifting the existing program text and data up by enough bytes to make room for the environment truncation code and rewriting the program relocation to reflect the new position. I have a program to do this. How do you identify programs which need this treatment? Well, I assume that they usually reveal themselves when they attempt to call a command compiled with the MWC package. If the usage message generated by make, ld, cc, or some other MWC compiled utility seems inappropriate, then try calling a simple echo program like this: main(argc, argv, envp) int argc; char *argv[], *envp[]; { int i; for (i = 0; i < argc; i += 1) printf("%s%c", argv[i], (i+1==argc) ? '\n' : ' '); for (i = 0; envp[i] != 0; i += 1) printf("%s\n", envp[i]); return(0); } This will tell you what arguments the suspect shell is actually passing. If you can't get the suspect shell to call 'echo.prg' you can trick it by temporarily renaming 'echo.prg' to the name of the program which the suspect shell insists on miscalling. If you're more energetic, you could write a protocol policeman using the ARGV validation ideas suggested above. ----------------------------------------------------------------------- In summary, the ARGV convention can be validated by comparing the ARGV received in the environment to the ARGV received by the parent; the ARGV convention rides for free on Pexec() while the new proposals both involve additional overhead; and it is trivial to fix programs which pollute the environment by ignoring the ARGV convention. If Atari wants MWC to discard the ARGV argument convention, I hope they'll wait until they can find something better to replace it with. :-) -- rec -- [%%% End of included text %%%] -- _____________________________________________________________________________ Daniel A. Glasser One of those things that goes uwvax!per2!dag "BUMP!!!(ouch)" in the night. ---Persoft, Inc.---------465 Science Drive-------Madison, WI 53711-----------