BSD progname (getprogname, setprogname): Difference between revisions
(Add example code) |
(→How NetBSD does it: Remove incorrect statement about this not being mentioned in the man page) |
||
(One intermediate revision by the same user not shown) | |||
Line 3: | Line 3: | ||
== Initial thoughts == |
== Initial thoughts == |
||
The man page says the functions appeared in NetBSD 1.6 and seems to suggest that they store <code>argv[0]</code> verbatim, even if it is <code>NULL</code>, and that <code>setprogname</code> is useless because <code>crt0</code> calls it during C runtime initialization and because the program name is a write-once value.<ref>https://man.netbsd.org/NetBSD-9.3-STABLE/getprogname.3</ref> The functions then found their way into FreeBSD 4.4.<ref>https://man.freebsd.org/cgi/man.cgi?query=getprogname&apropos=0&sektion=3&manpath=FreeBSD+13.2-RELEASE+and+Ports&arch=default&format=html</ref> |
The man page says the functions appeared in NetBSD 1.6 and seems to suggest that they store <code>argv[0]</code> verbatim, even if it is <code>NULL</code>, and that <code>setprogname</code> is useless because <code>crt0</code> calls it during C runtime initialization and because the program name is a write-once value.<ref>https://man.netbsd.org/NetBSD-9.3-STABLE/getprogname.3</ref> The functions then found their way into FreeBSD 4.4.<ref>https://man.freebsd.org/cgi/man.cgi?query=getprogname&apropos=0&sektion=3&manpath=FreeBSD+13.2-RELEASE+and+Ports&arch=default&format=html</ref> Unlike NetBSD and FreeBSD, OpenBSD states that the functions originated as a wrapper for the 4.4BSD <code>__progname</code> interface, first appearing in OpenBSD 5.4.<ref>https://man.openbsd.org/OpenBSD-7.3/getprogname.3</ref> |
||
== How NetBSD does it == |
== How NetBSD does it == |
||
Line 9: | Line 9: | ||
<code>getprogname</code> simply returns <code>__progname</code>.<ref>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</ref> |
<code>getprogname</code> simply returns <code>__progname</code>.<ref>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</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 |
<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. 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 == |
== Quick test == |
Latest revision as of 04:00, 26 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. 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