Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 26 Dec 2009 02:34:50 +1100 (EST)
From:      Bruce Evans <brde@optusnet.com.au>
To:        Ed Schouten <ed@freebsd.org>
Cc:        svn-src-head@freebsd.org, svn-src-all@freebsd.org, src-committers@freebsd.org
Subject:   Re: svn commit: r200979 - head/contrib/top
Message-ID:  <20091226014906.Y43539@delplex.bde.org>
In-Reply-To: <200912250902.nBP92gSW055301@svn.freebsd.org>
References:  <200912250902.nBP92gSW055301@svn.freebsd.org>

next in thread | previous in thread | raw e-mail | index | archive | help
On Fri, 25 Dec 2009, Ed Schouten wrote:

> Log:
>  Let top(1) use MAXLOGNAME instead of UT_NAMESIZE.
>
>  The maximum user login length should have nothing to do with <utmp.h>.

top was trying to be portable.  Its portable parts cannot use MAXLOGNAME,
since that is not in POSIX (I guess it is a BSDism).

> Modified:
>  head/contrib/top/username.c
>
> Modified: head/contrib/top/username.c
> ==============================================================================
> --- head/contrib/top/username.c	Fri Dec 25 08:06:35 2009	(r200978)
> +++ head/contrib/top/username.c	Fri Dec 25 09:02:41 2009	(r200979)
> @@ -30,17 +30,17 @@
>  *  This makes the table size independent of the passwd file size.
>  */
>
> +#include <sys/param.h>

top's portable parts also cannot use <sys/param.h>.  It used to handle this
by only including <sys/param.h> in "os.h", and then including "os.h" to
get some unportable bits (mainly via compatibility macros or extra
declarations in "os.h").  "os.h" itself is not so good -- it begins by
including <sys/param.h> unconditionally, so it doesn't compile on any
pure POSIX systems.  Then it has garbage like "caddr_t malloc();"
(only used on 16+ year old "BSD" systems).

> #define    is_empty_hash(x)	(hash_table[x].name[0] == 0)
> @@ -129,7 +129,7 @@ int wecare;		/* 1 = enter it always, 0 =
>
>     /* empty or wrong slot -- fill it with new value */
>     hash_table[hashindex].uid = uid;
> -    (void) strncpy(hash_table[hashindex].name, name, UT_NAMESIZE);
> +    (void) strncpy(hash_table[hashindex].name, name, MAXLOGNAME - 1);

MAXLOGNAME is spelled {LOGIN_NAME_MAX} in POSIX.1-2001.  This doesn't
help for top's portablility, since POSIX didn't have this until 2001,
but top is trying to support pre-4.4 BSD.

FreeBSD correctly doesn't define LOGIN_NAME_MAX (except briefly in 2003),
so that this limit isn't fixed and thus broken like UT_NAMESIZE.  So
there is no alternative to spelling {LOGIN_NAME_MAX} in the portable
way (sysconf(_SC_LOGIN_NAME_MAX) plus error handling) for working
portably on POSIX.1-2001 systems.  FreeBSD never uses this spelling in
libc -- there it uses the unportable spelling MAXLOGNAME and in most
places has CTASSERT()s which assumes that MAXLOGNAME is a compile-time
constant.

This is partially fixed in top-3.8beta1.  From username.c:

% #include "os.h"

The correct include, and top now uses autoconf, but "os.h" is still bad
internally.

% 
% #include <sys/types.h>
% #include <pwd.h>
% #include <utmp.h>
% 
% #include "top.h"
% #include "utils.h"
% #include "hash.h"
% 
% #define EXPIRETIME (60 * 5)
% 
% /* we need some sort of idea how long usernames can be */
% #ifndef MAXLOGNAME
% #ifdef _POSIX_LOGIN_NAME_MAX 
% #define MAXLOGNAME _POSIX_LOGIN_NAME_MAX 
% #else
% #define MAXLOGNAME 9
% #endif
% #endif

top now essentially uses MAXLOGNAME, but if this is not defined (it
would be defined on FreeBSD by "os.h" including <sys/param.h>), then
top uses _POSIX_LOGIN_NAME_MAX on POSIX.1-2001 systems (autoconfi will
have defined HAVE_LIMITS_H which will have caused "os.h" to have
included <limits.h>); otherwise it uses 9.  But _POSIX_LOGIN_NAME_MAX
is a wrong value to use on most POSIX.1-2001 systems, including FreeBSD.
It is the minimum value permitted by POSIX.1-2001 and is always 9;
thus most of the above ifdef is just an obfuscated spelling of 9.  9
is smaller than {LOGIN_NAME_MAX} on most POSIX.1-2001 systems including
FreeBSD, but is not too bad for top since top is short of space and
barely has space for 9; in fact its display seems to be limited to 9
(8 without the NUL, since TOP_USERNAME_LEN is never defined so the
default of 8 is used).  Thus values > 9 seem to cause at most minor
differences in sorting (when usernames truncated to 8 chars are not
unique) under FreeBSD.

Bruce



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