svn commit: r200979 - head/contrib/top
Bruce Evans
brde at optusnet.com.au
Fri Dec 25 15:34:55 UTC 2009
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
More information about the svn-src-all
mailing list