Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP Path: utzoo!mnetor!uunet!seismo!rutgers!mtune!codas!cpsc6a!rtech!wrs!dg From: dg@wrs.UUCP (David Goodenough) Newsgroups: comp.lang.c Subject: Re: Accessing argc & argv from a function Message-ID: <289@wrs.UUCP> Date: Tue, 4-Aug-87 00:23:17 EDT Article-I.D.: wrs.289 Posted: Tue Aug 4 00:23:17 1987 Date-Received: Thu, 6-Aug-87 01:37:35 EDT References: <420@sugar.UUCP> <39@flmis06.ATT.COM> <382@root44.co.uk> <5773@ut-ngp.UUCP> Reply-To: dg@wrs.UUCP (David Goodenough) Organization: Wind River Systems, Emeryville, CA Lines: 94 In article <5773@ut-ngp.UUCP> ayac071@ngp.UUCP (Bill Douglass) writes: >In article <382@root44.co.uk> njh@root44.UUCP (Nigel Horne) writes: >>In article <39@flmis06.ATT.COM> mikel@flmis06.ATT.COM (Mikel Manitius) writes: >>> >>>However I am still looking for a way to get at "argc" and "argv" from >>>a function when I don't have access to "main". getenv() and putenv() >>>gets it from somewhere... Technically getenv reference environ - a global variable which is a char ** type of thing. However it just so happens that environ is also the third argument to main(), which brings me to the following little program. I wrote this over lunch the other day, and believe it or not it works. I'm not suggesting that you all go and replace /bin/echo with this [among other things I haven't implemented the -n switch :-) ], but it demonstrates that what was requested is possible - if a little messy, and about as safe as nitroglycerine. *NOTE* it runs on a 68K and you *WILL*HAVE* to change struct frame to reflect what your stack frames look like on whatever machine you're using. However it does behave as expected, for all those of you with 68Ks I suggest you try it (if you drop the printf in getargs, and the passing of ip all the way down) it behaves just like echo - except there ain't no argc & argv declared in main(). If Mikel Manitius is still after something and the following is close, but doesn't work - email me & I'll help you as much as I can. -- dg@wrs.UUCP - David Goodenough +---+ | +-+-+ +-+-+ | +---+ --- cut here --- cut here --- cut here --- cut here --- cut here --- extern char **environ; /* need this to know when to stop */ main() /* no args!! */ { int i; /* just used for address checking when we * get to the bottom */ getit(&i, 5); /* go do the work */ } getit(ip, n) /* this recursively calls itself to put * some fake crud on the stack */ int *ip; { int ac; char **av; int i; if (n) getit(ip, n - 1); /* not far enough down */ else { findargs(&ac, &av, ip); /* at the bottom - get argc & argv */ for (i = 1; i < ac; i++) printf("%s%c", av[i], (i == ac - 1) ? '\n' : ' '); /* and print args - just like echo!! */ } } struct frame /* stack frame structure for a 68K */ { struct frame *_dynamic; /* dynamic link to previous frame */ char *_return; /* return address: I didn't know what type to * make this, so I made it a char * */ int _argc; /* argc when we get there */ char **_argv; /* argv when we get there */ char **_envp; /* envp when we get there */ } *work; findargs(acp, avp, ip) /* this does the work - ip is not needed, * it's just printed for verification */ int *acp, *ip; char ***avp; { int i; /* only one local variable, used to get a * reference to the current stack frame */ work = (struct frame *) (&i + 1); /* ugh! - point work at the current frame */ while (work->_envp != environ) work = work->_dynamic; /* run up the stack till we hit a valid * environment which we hope is main!! */ *acp = work->_argc; /* get argc */ *avp = work->_argv; /* and argv */ printf("%x %x\n", ip, work); /* just to compare pointers - these two should * be sizeof int apart */ }