Problems with SCO Unix 3.2.0

Stacey Campbell staceyc at sco.COM
Sat Jun 9 06:19:08 AEST 1990


In article <300007 at hpspcoi.HP.COM> darko at hpspcoi.HP.COM (David Arko) writes:
>Yes, It does seem that SCO Unix 3.2.0 has a bug with 'w' and 'uptime'.

Here's a program that will print uptime and cpu utilisation information
for SCO Unix/386 and for probably any other System V.3.2 based Unix.

The program will display cpu user, kernel and idle percentages over the
previous second.  This is obviously different from the load information
presented by the Xenix 'w' command, but still may be of some use.

Just unshar it and type 'make wup'.

Note that this is hacked out of a terminal status line utility that I
submitted to comp.sources.misc (v11i086 - statline).  If you want the
statline source then send a request to;

Stacey Campbell       staceyc at sco.com
{uunet,decwrl,ucscc,att,sq,altos,lotus,phoenix,sun,microsoft,xbs}!sco!staceyc

Note that 'wup' needs to read /unix and /dev/kmem.  If this is not
possible the error messages will be "nlist error" and "cannot open kmem"
respectively.

#!/bin/sh
# shar:	Shell Archiver  (v1.22)
#
#	Run the following text with /bin/sh to create:
#	  wup.c
#
sed 's/^X//' << 'SHAR_EOF' > wup.c &&
X#include <fcntl.h>
X#include <stdio.h>
X#include <a.out.h>
X#include <sys/types.h>
X#include <sys/sysinfo.h>
X#include <errno.h>
X
X#define NL_SYSINFO 0
X#define NL_LBOLT 1
X#define CPU_INFO_SZ (sizeof(sysinfo.cpu) / sizeof(sysinfo.cpu[0]))
X#define DEFAULT_HZ "60"
X
Xextern long lseek();
Xextern char *getenv();
X
Xstruct sysinfo sysinfo;
Xtime_t lbolt;
Xstatic struct nlist NlistInfo[] = {
X	{"sysinfo"},
X	{"lbolt"},
X	{0}};
X
Xstatic int LoadFnInit();
Xstatic int UptimeFnInit();
Xstatic int LoadFn();
Xstatic int LoadFnInit();
Xstatic int NlistLoaded = 0;
Xstatic int KmemFd;
Xstatic time_t SavedCpu[CPU_INFO_SZ];
Xstatic time_t BootTime;
Xstatic int Hertz;
X
Xint main(argc, argv)
X
Xint argc;
Xchar *argv[];
X
X	{
X	if (! LoadFnInit(stderr))
X		exit(1);
X	if (! UptimeFnInit(stderr))
X		exit(1);
X	(void)sleep(1);
X	if (! LoadFn(stdout))
X		exit(1);
X	if (! UptimeFn(stdout))
X		exit(1);
X	return 0;
X	}
X
Xstatic void DisplayAdd(display, msg)
X
XFILE *display;
Xchar *msg;
X
X	{
X	(void)fputs(msg, display);
X	}
X
Xstatic int LoadFnInit(display)
X
XFILE *display;
X
X	{
X	int i;
X	char *hz_str;
X	static int kmem_status = 0;
X
X	if (! NlistLoaded)
X		{
X		NlistLoaded = 1;
X		if (nlist("/unix", NlistInfo) < 0)
X			{
X			DisplayAdd(display, "nlist error\n");
X			return 0;
X			}
X		if (NlistInfo[NL_SYSINFO].n_value == 0)
X			{
X			DisplayAdd(display, "bad sysinfo offset\n");
X			return 0;
X			}
X		if (NlistInfo[NL_LBOLT].n_value == 0)
X			{
X			DisplayAdd(display, "bad lbolt offset\n");
X			return 0;
X			}
X		if (! (hz_str = getenv("HZ")))
X			hz_str = DEFAULT_HZ;
X		Hertz = atoi(hz_str);
X		if ((KmemFd = open("/dev/kmem", O_RDONLY)) < 0)
X			{
X			DisplayAdd(display, "cannot open kmem\n");
X			return 0;
X			}
X		if (lseek(KmemFd, NlistInfo[NL_SYSINFO].n_value, 0) == -1L)
X			{
X			char buf[128];
X			extern char *sys_errlist[];
X
X			sprintf(buf, "kmem lseek error %d %s %u\n", errno,
X			    sys_errlist[errno], NlistInfo[NL_SYSINFO].n_value);
X			DisplayAdd(display, buf);
X			return 0;
X			}
X		if (read(KmemFd, (char *)&sysinfo, sizeof(sysinfo)) < 0)
X			{
X			DisplayAdd(display, "kmem read error\n");
X			return 0;
X			}
X		for (i = 0; i < CPU_INFO_SZ; ++i)
X			SavedCpu[i] = sysinfo.cpu[i];
X
X		kmem_status = 1;
X		}
X
X	return kmem_status;
X	}
X
Xstatic int LoadFn(display)
X
XFILE *display;
X
X	{
X	int i;
X	time_t all_krn;
X	time_t new_cpu[CPU_INFO_SZ];
X	double total_cpu;
X	char buf[128];
X
X	if (lseek(KmemFd, NlistInfo[NL_SYSINFO].n_value, 0) == -1L)
X		{
X		DisplayAdd(stderr, "kmem lseek error\n");
X		return 0;
X		}
X	if (read(KmemFd, (char *)&sysinfo, sizeof(sysinfo)) < 0)
X		{
X		DisplayAdd(stderr, "kmem read error\n");
X		return 0;
X		}
X
X	total_cpu = 0.0;
X	for (i = 0; i < CPU_INFO_SZ; ++i)
X		{
X		total_cpu += new_cpu[i] = sysinfo.cpu[i] - SavedCpu[i];
X		SavedCpu[i] = sysinfo.cpu[i];
X		}
X
X	DisplayAdd(display, "CPU utilisation: ");
X	sprintf(buf, "user %.0f%%, ", new_cpu[CPU_USER] / total_cpu * 100.0);
X	DisplayAdd(display, buf);
X/* it's probably not "fair" to lump WAIT and SXBRK into
X * KERNEL but these are non-user cycles so what the hell */
X	all_krn = new_cpu[CPU_KERNEL] + new_cpu[CPU_WAIT] + new_cpu[CPU_SXBRK];
X	sprintf(buf, "kernel %.0f%%, ", all_krn / total_cpu * 100.0);
X	DisplayAdd(display, buf);
X	sprintf(buf, "idle %.0f%%\n", new_cpu[CPU_IDLE] / total_cpu * 100.0);
X	DisplayAdd(display, buf);
X
X	return 1;
X	}
X
Xstatic int UptimeFnInit(display)
X
XFILE *display;
X
X	{
X	if (LoadFnInit(display) == 0)
X		return 0;
X
X	if (lseek(KmemFd, NlistInfo[NL_LBOLT].n_value, 0) == -1L)
X		{
X		DisplayAdd(stderr, "kmem lbolt lseek error\n");
X		return 0;
X		}
X	if (read(KmemFd, (char *)&lbolt , sizeof(lbolt)) < 0)
X		{
X		DisplayAdd(display, "kmem lbolt read error\n");
X		return 0;
X		}
X
X	BootTime = time((time_t *)0) - lbolt / Hertz;
X	if (BootTime < 0)
X		DisplayAdd(display, "very strange boottime\n");
X
X	return 1;
X	}
X
Xstatic int UptimeFn(display)
X
XFILE *display;
X
X	{
X	time_t uptime;
X	int days, hours, minutes, seconds;
X	char buf[64];
X
X	uptime = time((time_t *)0) - BootTime;
X	days = uptime / (60 * 60 * 24);
X	uptime -= days * (60 * 60 * 24);
X	hours = uptime / (60 * 60);
X	uptime -= hours * (60 * 60);
X	minutes = uptime / 60;
X	uptime -= minutes * 60;
X	seconds = uptime;
X	sprintf(buf, "Uptime: %d+%.2d:%.2d:%.2d\n", days, hours, minutes,
X	    seconds);
X	DisplayAdd(display, buf);
X
X	return 1;
X	}
SHAR_EOF
chmod 0644 wup.c || echo "restore of wup.c fails"
exit 0



More information about the Comp.unix.i386 mailing list