BSD progname (getprogname, setprogname)
The BSD __progname interface, composed of (getprogname and setprogname), stood out to me while reading the NetBSD source code. Why have functions for argv[0]
? It turns out it does a little more.
Initial thoughts
The man page says the functions appeared in NetBSD 1.6 and seems to suggest that they store argv[0]
verbatim, even if it is NULL
, and that setprogname
is useless because crt0
calls it during C runtime initialization and because the program name is a write-once value.[1] The functions then found their way into FreeBSD 4.4.[2] Unlike NetBSD and FreeBSD, OpenBSD states that the functions originated as a wrapper for the 4.4BSD __progname
interface, first appearing in OpenBSD 5.4.[3]
How NetBSD does it
getprogname
simply returns __progname
.[4]
setprogname
has functionality for setting __progname
, including using strrchr
to get the location of the last occurrence of /
. This is to normalize a program run from ./blah/bin/hello
to just hello
, which is actually useful added value. However, unless the source file is modified, this functionality is never used, since a constant defined in the file makes the function a no-op.[5] __progname
gets set in crt0
using the same rule that the setprogname
would have followed, but with a manual search, and with an extra rule that sets __progname
to an empty string (pointer to \0
) instead of NULL
if the program name really is NULL
, making the point in the man page about getprogname
possibly returning NULL
moot.[6]
Quick test
Compile this and run it from different paths.
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[])
{
printf("progname is %s\n", getprogname());
printf("argv[0] is %s\n", argv[0]);
return EXIT_SUCCESS;
}
References
- ↑ https://man.netbsd.org/NetBSD-9.3-STABLE/getprogname.3
- ↑ https://man.freebsd.org/cgi/man.cgi?query=getprogname&apropos=0&sektion=3&manpath=FreeBSD+13.2-RELEASE+and+Ports&arch=default&format=html
- ↑ https://man.openbsd.org/OpenBSD-7.3/getprogname.3
- ↑ http://cvsweb.netbsd.org/bsdweb.cgi/src/lib/libc/gen/getprogname.c?rev=1.5&content-type=text/x-cvsweb-markup&only_with_tag=MAIN
- ↑ http://cvsweb.netbsd.org/bsdweb.cgi/src/lib/libc/gen/setprogname.c?rev=1.3&content-type=text/x-cvsweb-markup&only_with_tag=MAIN
- ↑ http://cvsweb.netbsd.org/bsdweb.cgi/src/lib/csu/common/crt0-common.c?rev=1.27&content-type=text/x-cvsweb-markup&only_with_tag=MAIN