Subject: setting and using progname.
To: None <tech-userlevel@netbsd.org>
From: Chris G. Demetriou <cgd@netbsd.org>
List: tech-userlevel
Date: 09/30/2000 15:23:31
so, 'grep' shows 710 instances of uses of __progname in our source
tree, split over 268 files. there appear to be approximately 187
extern declarations of __progname, making it probably the variable
with the most declarations outside of a header file. (this is in a
-current source tree a few days old.)
Some of these places are in libraries, e.g. the implementation of
err() et al., but many are in the programs themselves (e.g. usage()
functions).
This is a rather annoying issue when trying to port our programs to
other systems, especially those which may not be guaranteed to stash a
copy of the program name for easy use.
The right thing to do is have a function to set the 'program name' if
it's not already been set, for use by functions like err(), etc., and
a function to get the program name (for use by programs bodies), where
the information may not be as easily accessible.
I'd propose:
/*
* __progname declared in library or crt0, kept private, but existing
* uses still allowed to avoid breaking things.
*/
const char *__progname;
/*
* Set program name if it's not already set. Memory pointed to by
* arg0 must be valid until program termination.
*/
void
setprogname(const char *arg0)
{
if (__progname != NULL)
return;
__progname = strrchr(arg0, '/');
if (__progname == NULL)
__progname = arg0;
else
__progname++;
}
/* get the current program's name. */
const char *
getprogname(void)
{
return (__progname);
}
Code could be immediately converted from using direct references to
__progname (with attendant extern declarations) to using
getprogname(), since it would still be set in crt0.
At the start of main, programs which wish to be more portable would
call:
setprogname(argv[0]);
to be sure that the implementation of getprogname(), err(), etc., on
the target OS would have a program name to use.
I note that heimdal (or at least the version in our tree 8-) does
something similar with functions named [gs]et_progname -- i'm not sure
that it would respond well to having similarly-named functions
provided by the environment. I don't really care about the name, but
have a slight preference for non-_ versions (so they look like
gethostname/sethostname).
any thoughts or comments? I think this is long overdue...
cgd
--
Chris Demetriou - cgd@netbsd.org - http://www.netbsd.org/People/Pages/cgd.html
Disclaimer: Not speaking for NetBSD, just expressing my own opinion.