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.