Hi Jim,
> >> I suggest you declare those functions with the "nonnull" attribute.
>
> I was referring to the functions in progname.h:
>
> set_program_name
> set_program_name_and_installdir
The __nonnull__ attribute on these functions would help preventing or detecting
the bug, because these functions are always called with argument argv[0],
not with a literal NULL.
> > =========================== proposed linux-kernel report
> > =======================
> ...
> perhaps incomplete, since you can make the same argument about the "envp"
> pointer.
How so? When the caller passes a NULL envp argument - which POSIX does not
allow - the kernel provides an empty environment array instead. The callee
never sees a NULL 'environ'.
POSIX refers to argv[0], but not to envp[0].
It also contains language that explicitly says the callee is not guaranteed to
be
invoked with a POSIX compliant 'environ':
"The new process might be invoked in a non-conforming environment if the
envp array does not contain implementation-defined variables required
by the implementation to provide a conforming environment. See the
_CS_V7_ENV entry in <unistd.h> and confstr() for details."
> I do realize
> that this "fail early" aspect can be seen as a feature to help
> detect and hence diagnose/repair the underlying cause in the parent.
Absolutely.
Also, dumping core is the only way for the user to tell which program was
invoked in this irregular way.
> Will you put this in gnulib?
> Do you mean "the exec*ve* system call" or perhaps "an exec system call"?
Yes, "an exec system call" is better than "the exec system call". Thanks.
Committed.
Bruno
2009-12-06 Bruno Haible <[email protected]>
* lib/progname.c: Include stdio.h, stdlib.h.
(set_program_name): Reject a NULL argument.
*** lib/progname.c.orig 2009-12-06 23:19:17.000000000 +0100
--- lib/progname.c 2009-12-06 23:19:07.000000000 +0100
***************
*** 23,28 ****
--- 23,30 ----
#include "progname.h"
#include <errno.h> /* get program_invocation_name declaration */
+ #include <stdio.h>
+ #include <stdlib.h>
#include <string.h>
***************
*** 44,49 ****
--- 46,61 ----
const char *slash;
const char *base;
+ /* Sanity check. POSIX requires the invoking process to pass a non-NULL
+ argv[0]. */
+ if (argv0 == NULL)
+ {
+ /* It's a bug in the invoking program. Help diagnosing it. */
+ fputs ("A NULL argv[0] was passed through an exec system call.\n",
+ stderr);
+ abort ();
+ }
+
slash = strrchr (argv0, '/');
base = (slash != NULL ? slash + 1 : argv0);
if (base - argv0 >= 7 && strncmp (base - 7, "/.libs/", 7) == 0)