BSD progname (getprogname, setprogname)

From Computers Wiki
Jump to navigationJump to search

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