home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
AmigActive 13
/
AACD13.ISO
/
AACD
/
System
/
Sysmon
/
src
/
ShowSys.c
< prev
next >
Wrap
C/C++ Source or Header
|
2000-08-01
|
13KB
|
453 lines
/*
** $RCSfile: ShowSys.c,v $
** $Filename: ShowSys.c $
** $Revision: 1.5 $
** $Date: 2000/06/27 19:58:03 $
**
** sysmon.library Task display command ShowSys (version 1.6)
**
** (C) Copyright 1995-2000 by Etienne Vogt
** 64/32 Division algorithm kindly provided by Thomas Richter
*/
#include <exec/alerts.h>
#include <exec/memory.h>
#include <exec/execbase.h>
#include <dos/dosextens.h>
#include <dos/var.h>
#include <dos/datetime.h>
#include <workbench/startup.h>
#include <devices/timer.h>
#define __USE_SYSBASE
#include <proto/exec.h>
#include <proto/dos.h>
#include <proto/utility.h>
#include <proto/timer.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include "sysmon.h"
#include "sysmon_protos.h"
#include "sysmon_pragmas.h"
#define TIBUFMAX 30
#define TNAMEMAX 31
#define NT_CLI NT_USER
struct tiBuffer
{ struct TaskInfo tib_tinfo;
char tib_name[TNAMEMAX];
UBYTE tib_type;
LONG tib_clinum;
ULONG tib_stacksize;
ULONG tib_sigalloc;
ULONG tib_sigwait;
ULONG tib_sigrecvd;
ULONG tib_sigexcept;
BYTE tib_pri;
UBYTE tib_flags;
UBYTE tib_state;
};
struct tiBufArray
{ struct tiBufArray *tba_Link;
struct tiBuffer tba_bufs[TIBUFMAX];
};
struct ExecBase *SysBase;
struct DosLibrary *DOSBase;
struct SysmonBase *SysmonBase;
struct Library *TimerBase;
struct timerequest myTimeReq;
static struct WBStartup *wbmsg;
static struct RDArgs *myrda;
ULONG __saveds main(void);
static void cleanexit(ULONG rc);
static char *uptimestr(struct EClockVal *clockval, ULONG clockrate);
static char *cputimestr(struct EClockVal *clockval, ULONG clockrate);
static char *taskstate(UBYTE state, ULONG sigwait);
static char *taskflags(UBYTE flags, UBYTE moreflags);
static char *tasktype(UBYTE type, LONG clinum);
static char *bstr2c(BSTR bstring);
static char *cpustr(UWORD cpuflags);
static char *filterctrl(char *string);
static ULONG EClockDivide(struct EClockVal *numerator, ULONG denominator);
APTR SPrintf(STRPTR buffer, STRPTR format, ...);
void KPrintf(STRPTR format, ...);
void freetibufs(struct tiBufArray *tibufs);
static UBYTE version[] = "$VER: ShowSys 1.6 (1.8.2000)";
static UBYTE template[] = "FULL/S";
#define OPT_FULL 0
#define OPTMAX 1
ULONG __saveds main(void) /* No startup code */
{
struct Process *myproc;
ULONG EClockRate;
struct tiBufArray *tibufs;
LONG opts[OPTMAX];
SysBase = *(struct ExecBase **)4;
DOSBase = NULL;
SysmonBase = NULL;
TimerBase = NULL;
wbmsg = NULL;
myrda = NULL;
myproc = (struct Process *)FindTask(NULL);
if ((DOSBase = (struct DosLibrary *)OpenLibrary("dos.library",36)) == NULL)
{ Alert(AT_Recovery|AG_OpenLib|AO_DOSLib);
return 100;
}
if (!(myproc->pr_CLI)) /* If started from WB, exit cleanly */
{ WaitPort(&(myproc->pr_MsgPort));
wbmsg = (struct WBStartup *)GetMsg(&(myproc->pr_MsgPort));
cleanexit(20);
}
if ((SysmonBase = (struct SysmonBase *)OpenLibrary("sysmon.library",1)) == NULL)
{ if (DOSBase->dl_lib.lib_Version >= 36) PutStr("ShowSys : Couldn't open sysmon.library V1+.\n");
cleanexit(20);
}
if (OpenDevice(TIMERNAME, UNIT_ECLOCK, (struct IORequest *)&myTimeReq, 0L))
{ Alert(AT_Recovery|AG_OpenDev|AO_TimerDev);
cleanexit(100);
}
else
{ char Workbench[8], NodeName[16];
struct EClockVal UpTime;
struct DateTime SysTime;
UBYTE strDate[LEN_DATSTRING], strTime[LEN_DATSTRING];
memset((char *)opts, 0, sizeof(opts));
if ((myrda = ReadArgs(template, opts, NULL)) == NULL)
{ PrintFault(IoErr(),"ShowSys");
cleanexit(20);
}
TimerBase = (struct Library *)myTimeReq.tr_node.io_Device;
EClockRate = ReadEClock(&UpTime);
if (GetVar("Workbench", Workbench, sizeof(Workbench) - 1, GVF_GLOBAL_ONLY) > 0)
Printf("AmigaOS %s", Workbench);
else PutStr("AmigaOS ?????");
if (GetVar("HostName", NodeName, sizeof(NodeName) - 1, GVF_GLOBAL_ONLY) > 0)
Printf(" at %s", NodeName);
else PutStr(" at ????? ");
DateStamp(&SysTime.dat_Stamp);
SysTime.dat_Format = FORMAT_DOS;
SysTime.dat_Flags = 0;
SysTime.dat_StrDay = NULL;
SysTime.dat_StrDate = strDate;
SysTime.dat_StrTime = strTime;
if (DateToStr(&SysTime)) Printf(" %s %s", SysTime.dat_StrDate, SysTime.dat_StrTime);
else Printf(" ");
Printf(" UpTime :%s\n", uptimestr(&UpTime, EClockRate));
}
Printf("Address Name State Pri CPU [%.5s] Type\n",cpustr(SysBase->AttnFlags));
if (opts[OPT_FULL]) Printf("> Stack SigAlloc SigWait SigRecvd SigExcpt Flags Dispatch\n");
if ((tibufs = AllocVec(sizeof(struct tiBufArray), MEMF_PUBLIC | MEMF_CLEAR)) == NULL)
{ PutStr("ShowSys : No memory for TaskInfo buffers.\n");
cleanexit(20);
}
else
{ struct TaskInfo *tinfo = NULL;
struct tiBufArray *tba = tibufs;
struct tiBuffer *buf;
int j, i = 0, numtask = 0;
smLockTaskTable(LTTF_READ);
while (tinfo = smNextTaskInfo(tinfo))
{ struct Task *task;
struct CommandLineInterface *cli;
char *comname;
int n;
numtask++;
buf = &tba->tba_bufs[i];
memcpy(buf, tinfo, sizeof(struct TaskInfo));
task = tinfo->ti_Task;
if (task->tc_Node.ln_Name) strcpy(buf->tib_name, filterctrl(task->tc_Node.ln_Name));
else strcpy(buf->tib_name, "<< No Name >>");
buf->tib_flags = task->tc_Flags;
buf->tib_state = task->tc_State;
buf->tib_sigalloc = task->tc_SigAlloc;
buf->tib_sigwait = task->tc_SigWait;
buf->tib_sigrecvd = task->tc_SigRecvd;
buf->tib_sigexcept = task->tc_SigExcept;
if (buf->tib_state == TS_WAIT && task->tc_SigWait == 0) buf->tib_state = TS_STOP;
buf->tib_pri = task->tc_Node.ln_Pri;
buf->tib_type = task->tc_Node.ln_Type;
if (buf->tib_type == NT_PROCESS && (cli = BADDR(((struct Process *)task)->pr_CLI)))
{ buf->tib_clinum = ((struct Process *)task)->pr_TaskNum;
buf->tib_type = NT_CLI;
buf->tib_stacksize = cli->cli_DefaultStack * sizeof(ULONG);
if (cli->cli_Module && (comname = bstr2c(cli->cli_CommandName)) && (n = strlen(buf->tib_name)) < TNAMEMAX - 4)
{ comname = filterctrl(FilePart(comname));
strcat(buf->tib_name, " (");
strncat(buf->tib_name, comname, TNAMEMAX - n - 4);
strcat(buf->tib_name, ")");
}
}
else if (buf->tib_type == NT_PROCESS) buf->tib_stacksize = ((struct Process *)task)->pr_StackSize;
else buf->tib_stacksize = (ULONG)task->tc_SPUpper - (ULONG)task->tc_SPLower;
if (++i == TIBUFMAX)
{ struct tiBufArray *tba1;
if (tba1 = AllocVec(sizeof(struct tiBufArray), MEMF_PUBLIC | MEMF_CLEAR))
{ tba->tba_Link = tba1;
tba = tba1;
i = 0;
}
else
{ smUnLockTaskTable(LTTF_READ);
freetibufs(tibufs);
Printf("ShowSys : No memory for TaskInfo buffers.\n");
cleanexit(20);
}
}
}
smUnLockTaskTable(LTTF_READ);
for (j = 0, tba = tibufs, i = 0 ; j < numtask ; j++)
{ buf = &tba->tba_bufs[i];
Printf("%08lx %-30.30s %-5s %4ld %16s %-8s\n", buf->tib_tinfo.ti_Task,
buf->tib_name, taskstate(buf->tib_state, buf->tib_sigwait), buf->tib_pri,
cputimestr(&buf->tib_tinfo.ti_CPUTime, EClockRate),
tasktype(buf->tib_type, buf->tib_clinum));
if (opts[OPT_FULL]) Printf(">%7lu %08lx %08lx %08lx %08lx %8s %10lu\n", buf->tib_stacksize,
buf->tib_sigalloc, buf->tib_sigwait, buf->tib_sigrecvd, buf->tib_sigexcept,
taskflags(buf->tib_flags, buf->tib_tinfo.ti_Flags), buf->tib_tinfo.ti_DispCount);
if (CheckSignal(SIGBREAKF_CTRL_C))
{ PutStr("*** BREAK ***\n");
break;
}
if (++i == TIBUFMAX)
{ tba = tba->tba_Link;
i = 0;
}
}
freetibufs(tibufs);
}
cleanexit(0);
}
static void cleanexit(ULONG rc)
{
if (TimerBase) CloseDevice((struct IORequest *)&myTimeReq);
if (SysmonBase) CloseLibrary((struct Library *)SysmonBase);
if (myrda) FreeArgs(myrda);
if (wbmsg)
{ Forbid();
ReplyMsg((struct Message *)wbmsg);
}
if (DOSBase) CloseLibrary((struct Library *)DOSBase);
Exit(rc);
}
static char *uptimestr(struct EClockVal *clockval, ULONG clockrate)
{ static char buffer[16];
ULONG seconds;
UWORD updays, uphours, upminutes, upseconds;
seconds = EClockDivide(clockval, clockrate);
updays = seconds / (24*60*60);
seconds %= 24*60*60;
uphours = seconds / (60*60);
seconds %= 60*60;
upminutes = seconds / 60;
upseconds = seconds % 60;
SPrintf(buffer, "%4lu %02lu:%02lu:%02lu", updays, uphours, upminutes, upseconds);
return buffer;
}
static char *cputimestr(struct EClockVal *clockval, ULONG clockrate)
{ static char buffer[18];
ULONG seconds;
UWORD cpudays, cpuhours, cpuminutes, cpuseconds, cpumillis;
seconds = EClockDivide(clockval, clockrate);
cpudays = seconds / (24*60*60);
seconds %= 24*60*60;
cpuhours = seconds / (60*60);
seconds %= 60*60;
cpuminutes = seconds / 60;
cpuseconds = seconds % 60;
cpumillis = clockval->ev_lo / (clockrate / 1000);
SPrintf(buffer, "%3lu %02lu:%02lu:%02lu.%03lu", cpudays, cpuhours, cpuminutes, cpuseconds, cpumillis);
return buffer;
}
static ULONG EClockDivide(struct EClockVal *numerator, ULONG denominator)
{ int bits;
ULONG d1,d2,d3;
d1 = 0x0;
d2 = numerator->ev_hi;
d3 = numerator->ev_lo;
for (bits = 0; bits < 64; bits++)
{ /* now left-shift d1,d2,d3 */
d1 <<= 1;
if (d2 & 0x80000000) d1 |= 0x1;
d2 <<= 1;
if (d3 & 0x80000000) d2 |= 0x1;
d3 <<= 1;
if (d1 >= denominator)
{ d1 -= denominator;
d3 |= 0x1;
}
}
/* fill in the remainder */
numerator->ev_lo = d1;
/* return the quotient, or the low part of it, at least */
return d3;
}
static char *taskflags(UBYTE flags, UBYTE moreflags)
{ static char buffer[9];
buffer[0] = (flags & TF_LAUNCH) ? 'L' : '-';
buffer[1] = (flags & TF_SWITCH) ? 'S' : '-';
buffer[2] = (flags & TF_EXCEPT) ? 'E' : '-';
buffer[3] = (flags & TF_STACKCHK) ? 'C' : '-';
buffer[4] = (flags & TF_ETASK) ? 'X' : '-';
buffer[5] = (flags & TF_PROCTIME) ? 'P' : '-';
buffer[6] = (moreflags & TIF_INEXCEPT) ? 'I' : '-';
buffer[7] = (moreflags & TIF_WAKEUP) ? 'W' : '-';
buffer[8] = '\0';
return buffer;
}
static char *taskstate(UBYTE state, ULONG sigwait)
{
switch(state)
{ case TS_INVALID:
return "INVLD";
case TS_ADDED:
return "ADDED";
case TS_RUN:
return "RUN";
case TS_READY:
return "READY";
case TS_WAIT:
if (sigwait == 0) return "STOP";
else if (sigwait == SIGF_ABORT) return "SWABO";
else if (sigwait == SIGF_CHILD) return "SWCHI";
else if (sigwait == SIGF_SINGLE) return "SWSIN";
else if (sigwait == SIGF_INTUITION) return "SWINT";
else if (sigwait == SIGF_NET) return "SWNET";
else if (sigwait == SIGF_DOS) return "SWDOS";
else if (sigwait == SIGBREAKF_CTRL_C) return "SWBRC";
else if (sigwait == SIGBREAKF_CTRL_D) return "SWBRD";
else if (sigwait == SIGBREAKF_CTRL_E) return "SWBRE";
else if (sigwait == SIGBREAKF_CTRL_F) return "SWBRF";
else return "WAIT";
case TS_EXCEPT:
return "EXCPT";
case TS_REMOVED:
return "REMVD";
case TS_STOP:
return "STOP";
case TS_FROZEN:
return "FROZN";
case TS_HIBERNATE:
return "HIBER";
case TS_PAGEFLTWAIT:
return "PGFWT";
case TS_WAITAND:
return "WAITA";
case TS_TRAP:
return "TRAP";
case TS_FREEWAIT:
return "FREWT";
default:
return "?????";
}
}
static char *tasktype(UBYTE type, LONG clinum)
{ static char buffer[10];
switch(type)
{ case NT_TASK:
SPrintf(buffer,"Task");
break;
case NT_PROCESS:
SPrintf(buffer,"Process");
break;
case NT_CLI:
SPrintf(buffer,"Cli %-4ld",clinum);
break;
default:
SPrintf(buffer,"???");
break;
}
return buffer;
}
#define AFB_68060 7
#define AFF_68060 (1L<<7)
static char *cpustr(UWORD cpuflags)
{
if (cpuflags & AFF_68060) return "68060";
else if (cpuflags & AFF_68040) return "68040";
else if (cpuflags & AFF_68030) return "68030";
else if (cpuflags & AFF_68020) return "68020";
else if (cpuflags & AFF_68010) return "68010";
else return "68000";
}
static char *bstr2c(BSTR bstring)
{ static char buffer[256];
char *ptr;
int n;
if ((ptr = BADDR(bstring)) == NULL || (n = *ptr++) == 0) return NULL;
strncpy(buffer, ptr, n + 1);
return buffer;
}
static char *filterctrl(char *string)
{ static char buffer[TNAMEMAX];
int i;
for (i = 0 ; *string && i < TNAMEMAX - 1 ; i++, string++)
{ if ((*string & 0x7f) < ' ') buffer[i] = '.';
else buffer[i] = *string;
}
buffer[i] = 0;
return buffer;
}
APTR SPrintf(STRPTR buffer, STRPTR format, ...)
{ return smVSPrintf(buffer, format, &format + 1);
}
void KPrintf(STRPTR format, ...)
{ smVKPrintf(format, &format + 1);
}
void freetibufs(struct tiBufArray *tibufs)
{ struct tiBufArray *nexttba;
do
{ nexttba = tibufs->tba_Link;
FreeVec(tibufs);
} while (tibufs = nexttba);
}