Subject: Re: top & uptime
To: Zafer Aydogan <zafer@gmx.org>
From: Simon Burge <simonb@wasabisystems.com>
List: tech-userlevel
Date: 01/24/2005 22:18:12
--pf9I7BMVVzbSWLtt
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline

On Mon, Jan 24, 2005 at 11:22:41AM +0100, Zafer Aydogan wrote:

> Top currently shows only the time but not the uptime of the machine. I'd
> appreciate to see the uptime in top.

The attached patch changes the first line of the display from:

    load averages:  2.46,  2.76,  2.73         up 0 days, 20:05   22:10:55

instead of:

    load averages:  2.46,  2.76,  2.73                            22:10:55

Do we want this change in our source tree?  It doesn't worry me either
way, but I've CC'd this to tech-userlevel where these sorts of changes
are discussed (and BCC'd to current-users so anyone on that list can see
that it's moved).

Simon.
--
Simon Burge                                   <simonb@wasabisystems.com>
NetBSD Development, Support and Service:   http://www.wasabisystems.com/

--pf9I7BMVVzbSWLtt
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="uptime.diff"

Index: display.c
===================================================================
RCS file: /cvsroot/src/usr.bin/top/display.c,v
retrieving revision 1.13
diff -d -p -u -r1.13 display.c
--- display.c	24 Jan 2005 10:38:47 -0000	1.13
+++ display.c	24 Jan 2005 11:09:31 -0000
@@ -54,6 +54,7 @@ __RCSID("$NetBSD: display.c,v 1.13 2005/
 #include <ctype.h>
 #include <time.h>
 #include <stdarg.h>
+#include <tzfile.h>
 
 #include "screen.h"		/* interface to screen package */
 #include "layout.h"		/* defines for screen position layout */
@@ -268,11 +269,29 @@ double *avenrun;
 }
 
 void
-i_timeofday(tod)
+i_timeofday(tod, uptimep)
 
 time_t *tod;
+time_t *uptimep;
 
 {
+    char up[MAX_COLS];
+    time_t uptime;
+    int days, hrs, mins;
+
+    uptime = *uptimep;	/* work on local copy */
+    uptime += 30;	/* round off to nearest minute */
+    if (uptime > SECSPERMIN) {
+        days = uptime / SECSPERDAY;
+        uptime %= SECSPERDAY;
+        hrs = uptime / SECSPERHOUR;
+        uptime %= SECSPERHOUR;
+        mins = uptime / SECSPERMIN;
+	snprintf(up, sizeof(up), "up %d day%s, %2d:%02d", days,
+		 days != 1 ? "s" : "", hrs, mins);
+    } else
+	up[0] = '\0';	/* null string if we don't know the uptime */
+
     /*
      *  Display the current time.
      *  "ctime" always returns a string that looks like this:
@@ -286,20 +305,20 @@ time_t *tod;
 
     if (smart_terminal)
     {
-	Move_to(screen_width - 8, 0);
+	Move_to(screen_width - 8 - (3 + strlen(up)), 0);
     }
     else
     {
-	fputs("    ", stdout);
+	fprintf(stdout, "    %s    ", up);
     }
 #ifdef DEBUG
     {
 	char *foo;
 	foo = ctime(tod);
-	fputs(foo, stdout);
+	printf("%s  %s", up, foo);
     }
 #endif
-    printf("%-8.8s\n", &(ctime(tod)[11]));
+    printf("%s   %-8.8s\n", up, &(ctime(tod)[11]));
     lastline = 1;
 }
 
Index: display.h
===================================================================
RCS file: /cvsroot/src/usr.bin/top/display.h,v
retrieving revision 1.6
diff -d -p -u -r1.6 display.h
--- display.h	16 Jul 2002 00:40:51 -0000	1.6
+++ display.h	24 Jan 2005 11:09:31 -0000
@@ -40,7 +40,7 @@ struct statics;
 int display_init __P((struct statics *));
 void i_loadave __P((int, double *));
 void u_loadave __P((int, double *));
-void i_timeofday __P((time_t *));
+void i_timeofday __P((time_t *, time_t *));
 void i_procstates __P((int, int *));
 void u_procstates __P((int, int *));
 char *cpustates_tag __P((void));
Index: machine.h
===================================================================
RCS file: /cvsroot/src/usr.bin/top/machine.h,v
retrieving revision 1.8
diff -d -p -u -r1.8 machine.h
--- machine.h	3 Oct 2003 15:32:06 -0000	1.8
+++ machine.h	24 Jan 2005 11:09:31 -0000
@@ -63,6 +63,7 @@ struct system_info
 {
     int    last_pid;
     double load_avg[NUM_AVERAGES];
+    time_t uptime;
     int    p_total;
     int    P_ACTIVE;     /* number of procs considered "active" */
     int    *procstates;
Index: top.c
===================================================================
RCS file: /cvsroot/src/usr.bin/top/top.c,v
retrieving revision 1.20
diff -d -p -u -r1.20 top.c
--- top.c	23 Jul 2004 13:31:50 -0000	1.20
+++ top.c	24 Jan 2005 11:09:31 -0000
@@ -520,7 +520,7 @@ Usage: %s [-bIinqSuv] [-d count] [-o fie
 	/* display the current time */
 	/* this method of getting the time SHOULD be fairly portable */
 	time(&curr_time);
-	i_timeofday(&curr_time);
+	i_timeofday(&curr_time, &system_info.uptime);
 
 	/* display process state breakdown */
 	(*d_procstates)(system_info.p_total,
Index: machine/m_netbsd15.c
===================================================================
RCS file: /cvsroot/src/usr.bin/top/machine/m_netbsd15.c,v
retrieving revision 1.22
diff -d -p -u -r1.22 m_netbsd15.c
--- machine/m_netbsd15.c	13 Feb 2004 11:36:24 -0000	1.22
+++ machine/m_netbsd15.c	24 Jan 2005 11:09:32 -0000
@@ -315,7 +315,9 @@ get_system_info(si)
 	int mib[2];
 	struct uvmexp_sysctl uvmexp;
 	struct swapent *sep, *seporig;
+	struct timeval boottime;
 	u_int64_t totalsize, totalinuse;
+	time_t now;
 	int size, inuse, ncounted, i;
 	int rnswap, nswap;
 
@@ -411,6 +413,16 @@ get_system_info(si)
 	si->memory = memory_stats;
 	si->swap = swap_stats;
 	si->last_pid = -1;
+
+	time(&now);
+	mib[0] = CTL_KERN;
+	mib[1] = KERN_BOOTTIME;
+	ssize = sizeof(boottime);
+	if (sysctl(mib, 2, &boottime, &ssize, NULL, 0) != -1 &&
+	    boottime.tv_sec != 0)
+		si->uptime = now - boottime.tv_sec;
+	else
+		si->uptime = 0;
 }
 
 

--pf9I7BMVVzbSWLtt--