Subject: bin/31452: top & uptime
To: None <gnats-admin@netbsd.org, netbsd-bugs@netbsd.org>
From: None <zafer@gmx.org>
List: netbsd-bugs
Date: 10/03/2005 05:18:00
>Number:         31452
>Category:       bin
>Synopsis:       top & uptime
>Confidential:   no
>Severity:       non-critical
>Priority:       high
>Responsible:    bin-bug-people
>State:          open
>Class:          change-request
>Submitter-Id:   net
>Arrival-Date:   Mon Oct 03 05:18:00 +0000 2005
>Originator:     Zafer Aydogan
>Release:        3.99.9
>Organization:
>Environment:
i386
>Description:
This is a feature request:

I would like to see the uptime of the machine, when using top.
This was discussed in January in tech-userlevel.


>How-To-Repeat:
top
>Fix:
I'll append a patch for the current top source code, that will show the uptime left to the time on the first line.
This patch was authored by Simon Burge back in January.
I just applied it to our current code.

The diffs are also available here:

http://mia.aydogan.net/netbsd/top/


==========================================
[diff for Revision 1.13 of display.c]
==========================================

--- display.c	2005-10-03 06:53:28.000000000 +0200
+++ display.c.new	2005-10-01 18:01:48.000000000 +0200
@@ -54,6 +54,7 @@
 #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 @@
 }
 
 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 @@
 
     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;
 }
 



===============================================
[diff for  Revision 1.6 of display.h]
===============================================


--- display.h	2005-10-03 06:53:28.000000000 +0200
+++ display.h.new	2005-10-01 18:02:00.000000000 +0200
@@ -40,7 +40,7 @@
 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));



====================================
diff for  Revision 1.8 of machine.h
====================================

--- machine.h	2005-10-03 06:53:28.000000000 +0200
+++ machine.h.new	2005-10-01 18:01:29.000000000 +0200
@@ -63,6 +63,7 @@
 {
     int    last_pid;
     double load_avg[NUM_AVERAGES];
+    time_t uptime;
     int    p_total;
     int    P_ACTIVE;     /* number of procs considered "active" */
     int    *procstates;




===========================================
diff for  Revision 1.22 of top.c
===========================================

--- top.c	2005-10-03 06:53:28.000000000 +0200
+++ top.c.new	2005-10-01 18:01:15.000000000 +0200
@@ -520,7 +520,7 @@
 	/* 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,






==================================================
diff for Revision 1.23 of machine/m_netbsd15.c
==================================================

--- m_netbsd15.c	2005-10-03 06:53:53.000000000 +0200
+++ m_netbsd15.c.new	2005-10-01 18:02:10.000000000 +0200
@@ -339,7 +339,9 @@
 	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;
 
@@ -435,6 +437,16 @@
 	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;
 }