bug-coreutils
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

fix for an unlikely core dump in 'who' and 'pinky'


From: Paul Eggert
Subject: fix for an unlikely core dump in 'who' and 'pinky'
Date: Sat, 19 Jun 2004 22:19:11 -0700
User-agent: Gnus/5.1006 (Gnus v5.10.6) Emacs/21.3 (gnu/linux)

'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  <address@hidden>

        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])




reply via email to

[Prev in Thread] Current Thread [Next in Thread]