'who' and 'pinky' both assume that ctime never fails, but this isn't true on hosts with 64-bit time_t and 32-bit int. Here's a patch.
2004-06-19 Paul Eggert <[EMAIL PROTECTED]> Don't dump core if ctime returns NULL; this is possible on hosts with 64-bit time_t and 32-bit int. * src/who.c: Include "inttostr.h". (time_string): If ctime fails, print the raw time as an integer instead of dumping core. * src/pinky.c: Likewise, as follows: Include "inttostr.h". (time_string): New function, copied from who.c. (print_entry): Use it. Index: src/who.c =================================================================== RCS file: /home/meyering/coreutils/cu/src/who.c,v retrieving revision 1.94 diff -p -u -r1.94 who.c --- src/who.c 13 Jun 2004 22:03:07 -0000 1.94 +++ src/who.c 20 Jun 2004 04:57:46 -0000 @@ -33,6 +33,7 @@ #include "readutmp.h" #include "error.h" +#include "inttostr.h" #include "vasprintf.h" /* The official name of this program (e.g., no `g' prefix). */ @@ -233,8 +234,17 @@ time_string (const STRUCT_UTMP *utmp_ent the tv_sec member of a struct timeval value.'' */ time_t tm = UT_TIME_MEMBER (utmp_ent); - char *ptr = ctime (&tm) + 4; - ptr[12] = '\0'; + char *ptr = ctime (&tm); + if (ptr) + { + ptr += 4; + ptr[12] = '\0'; + } + else + { + static char buf[INT_BUFSIZE_BOUND (intmax_t)]; + ptr = (TYPE_SIGNED (time_t) ? imaxtostr (tm, buf) : umaxtostr (tm, buf)); + } return ptr; } Index: src/pinky.c =================================================================== RCS file: /home/meyering/coreutils/cu/src/pinky.c,v retrieving revision 1.38 diff -p -u -r1.38 pinky.c --- src/pinky.c 21 Jan 2004 23:38:21 -0000 1.38 +++ src/pinky.c 20 Jun 2004 04:57:31 -0000 @@ -26,6 +26,7 @@ #include "system.h" #include "error.h" +#include "inttostr.h" #include "readutmp.h" /* The official name of this program (e.g., no `g' prefix). */ @@ -160,6 +161,33 @@ idle_string (time_t when) return (const char *) idle_hhmm; } +/* Return a standard time string, "mon dd hh:mm" + FIXME: handle localization */ +static const char * +time_string (const STRUCT_UTMP *utmp_ent) +{ + /* Don't take the address of UT_TIME_MEMBER directly. + Ulrich Drepper wrote: + ``... GNU libc (and perhaps other libcs as well) have extended + utmp file formats which do not use a simple time_t ut_time field. + In glibc, ut_time is a macro which selects for backward compatibility + the tv_sec member of a struct timeval value.'' */ + time_t tm = UT_TIME_MEMBER (utmp_ent); + + char *ptr = ctime (&tm); + if (ptr) + { + ptr += 4; + ptr[12] = '\0'; + } + else + { + static char buf[INT_BUFSIZE_BOUND (intmax_t)]; + ptr = (TYPE_SIGNED (time_t) ? imaxtostr (tm, buf) : umaxtostr (tm, buf)); + } + return ptr; +} + /* Display a line of information about UTMP_ENT. */ static void @@ -173,7 +201,6 @@ print_entry (const STRUCT_UTMP *utmp_ent #define DEV_DIR_LEN (sizeof (DEV_DIR_WITH_TRAILING_SLASH) - 1) char line[sizeof (utmp_ent->ut_line) + DEV_DIR_LEN + 1]; - time_t tm; /* Copy ut_line into LINE, prepending `/dev/' if ut_line is not already an absolute pathname. Some system may put the full, @@ -238,14 +265,7 @@ print_entry (const STRUCT_UTMP *utmp_ent printf (" %-6s", "???"); } - /* Don't take the address of UT_TIME_MEMBER directly. - Ulrich Drepper wrote: - ``... GNU libc (and perhaps other libcs as well) have extended - utmp file formats which do not use a simple time_t ut_time field. - In glibc, ut_time is a macro which selects for backward compatibility - the tv_sec member of a struct timeval value.'' */ - tm = UT_TIME_MEMBER (utmp_ent); - printf (" %-12.12s", ctime (&tm) + 4); + printf (" %s", time_string (utmp_ent)); #ifdef HAVE_UT_HOST if (include_where && utmp_ent->ut_host[0]) _______________________________________________ Bug-coreutils mailing list [EMAIL PROTECTED] http://lists.gnu.org/mailman/listinfo/bug-coreutils