Ben Bacarisse
2/13/2011 1:57:00 AM
Dr Nick <3-nospam@temporary-address.org.uk> writes:
> Andrew Smallshaw <andrews@sdf.lonestar.org> writes:
>
>> On 2011-02-10, Gordon Burditt <gordonb.4yxi6@burditt.org> wrote:
>>>> Are there implementations in which argc can be 0 then?
>>>
>>> Yes. UNIX. Just have a program call, for example:
>>>
>>> execl(path, (char *) NULL);
>
> That's gives me a warning about not enough variable arguments. execl
> needs a null terminated list and clearly the compiler "knows" to expect
> a real one in there.
>
>> On most modern Unix systems that won't initialise main()'s argc to
>> _anything_. Program invocation with a null argv is generally taken
>> as an instruction to the dynamic linker. You'll get a listing of
>> requested and linked in libraries and the program will terminate
>> without ever calling main().
>
> With an extra NULL, or with execv I get a segfault from:
>
> #include <unistd.h>
>
> int main(void) {
> execv("/bin/ls",(char * const *)NULL);
> /* or, and ignore the warning */
> execl("/bin/ls",(char *)NULL);
> /* or */
> execl("/bin/ls",(const *)NULL,(char *)NULL);
> return 0;
> }
>
> and debugging does seem to show it was in the dynamic linker.
>
> execl("/bin/ls","",(char * const *)NULL);
> works but, of course, has an argument.
>
> So I don't think it's as easy as we thought!
That depends on what you thought! Andrew is talking about a null argv
and that's not the same as the original proposal of starting a program
with argc == 0. When argc == 0, argv must have at least one element: a
null pointer.
You can do this:
#include <unistd.h>
int main(void)
{
char *argv[] = {0};
execv("./args", argv);
}
and in when args is this program:
#include <stdio.h>
int main(int argc, char **argv)
{
printf("argc=%d argv[0]=%p\n", argc, (void *)argv[0]);
return 0;
}
you get:
$ ./exec
argc=0 argv[0]=(nil)
which is answers the question at the top of this post.
--
Ben.