BSD progname (getprogname, setprogname): Difference between revisions

From Computers Wiki
Jump to navigationJump to search
(Create page)
 
(Add example code)
Line 10: Line 10:


<code>setprogname</code> has functionality for setting <code>__progname</code>, including using <code>strrchr</code> to get the location of the last occurrence of <code>/</code>. This is to normalize a program run from <code>./blah/bin/hello</code> to just <code>hello</code>, which is actually useful added value that isn't mentioned in the man page. 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.<ref>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</ref>. <code>__progname</code> gets set in <code>crt0</code> using the same rule that the <code>setprogname</code> would have followed, but with a manual search, and with an extra rule that sets <code>__progname</code> to an empty string (pointer to <code>\0</code>) instead of <code>NULL</code> if the program name really is <code>NULL</code>, making the point in the man page about <code>getprogname</code> possibly returning <code>NULL</code> moot.<ref>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</ref>
<code>setprogname</code> has functionality for setting <code>__progname</code>, including using <code>strrchr</code> to get the location of the last occurrence of <code>/</code>. This is to normalize a program run from <code>./blah/bin/hello</code> to just <code>hello</code>, which is actually useful added value that isn't mentioned in the man page. 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.<ref>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</ref>. <code>__progname</code> gets set in <code>crt0</code> using the same rule that the <code>setprogname</code> would have followed, but with a manual search, and with an extra rule that sets <code>__progname</code> to an empty string (pointer to <code>\0</code>) instead of <code>NULL</code> if the program name really is <code>NULL</code>, making the point in the man page about <code>getprogname</code> possibly returning <code>NULL</code> moot.<ref>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</ref>

== Quick test ==

Compile this and run it from different paths.

<syntaxhighlight lang="c">
#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;
}
</syntaxhighlight>


== References ==
== References ==

Revision as of 04:39, 23 June 2023

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 that isn't mentioned in the man page. 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