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 <br...@clisp.org> * 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)