Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 6 Jan 2003 14:12:56 -0500 (EST)
From:      Garrett Wollman <wollman@lcs.mit.edu>
To:        obrien@FreeBSD.org
Cc:        cvs-committers@FreeBSD.org, cvs-all@FreeBSD.org
Subject:   Re: cvs commit: src/lib/libc/gen sysconf.c
Message-ID:  <200301061912.h06JCuZ3089105@khavrinen.lcs.mit.edu>
In-Reply-To: <20030106043730.GA24930@dragon.nuxi.com>
References:  <200209210214.g8L2E4Wc086892@freefall.freebsd.org> <20030106043730.GA24930@dragon.nuxi.com>

next in thread | previous in thread | raw e-mail | index | archive | help
<<On Sun, 5 Jan 2003 20:37:31 -0800, "David O'Brien" <obrien@FreeBSD.org> said:

> On a related note, why should 'LOGIN_NAME_MAX' be a run-time value?
> One of the most common use of it is "char foo[LOGIN_NAME_MAX];".

Such code is erroneous.  POSIX says quite clearly that
{LOGIN_NAME_MAX} is a run-time configuration parameter.  Programs
which are unable to cope with this ought not use the POSIX
parameter.  Bruce convinced me some moons ago that these parameters
should be left undefined in order to break buggy programs such as
these.

The only parameters which are guaranteed to be compile-time constants
are those listed in src/usr.bin/getconf/limits.gperf.

> Calling sysconf(3) in this context will not work.

Certainly it will:

#if LOGIN_NAME_MAX == 0
	char *buf;
	long buflen;

	buflen = sysconf(_SC_LOGIN_NAME_MAX);
	if (buflen < _POSIX_LOGIN_NAME_MAX) {
		/*
		 * Uh-oh.  Either we had an error, or there is no limit.
		 * Deal as best we can by assuming the POSIX minimum.
		 * If we were smarter, we would allocate however much space
		 * is actually needed for what we're planning to put in
		 * this buffer, but obrien's example did not give enough
		 * context.
		 */
		buflen = _POSIX_LOGIN_NAME_MAX;
	}
	buf = malloc((size_t)buflen);
#else
	char buf[LOGIN_NAME_MAX];
	long buflen = (long)sizeof buf;
#endif

	/*
	 * Do something with buf.
	 */

#if LOGIN_NAME_MAX == 0
	free(buf);
#endif

You could also write this as a run-time dynamic array, in those
dialects of C which support it:

	long maxlogname = sysconf(_SC_LOGIN_NAME_MAX);
	char buf[maxlogname < 1 ? _POSIX_LOGIN_NAME_MAX : (size_t)maxlogname];

-GAWollman


To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe cvs-all" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200301061912.h06JCuZ3089105>