monitor.c -- a system status monitor
Prentiss Riddle
riddle at ut-sally.UUCP
Wed Oct 26 14:24:58 AEST 1983
/*
* monitor 831017 Prentiss Riddle
*
* system status monitor
*
* compilation: "cc -o monitor monitor.c -lcurses -ltermlib"
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*
* This routine is intended primarily to be used as an aid in debugging
* multi-process systems, programs manipulating a lot of files in a direc-
* tory, and the like. I like to be running a program I'm working on at one
* terminal while "monitor" is running on the next one to tell me what's
* going on. What it does is run a specified command over and over again,
* displaying one screenful of the process's output at all times and using
* cursor optimization to update the display with a minimum of distractions.
*
* NOTE: monitor runs in an infinite loop -- the only way to exit is with
* the "break" key!
*
*
* USAGE: monitor [-] [-t] [-s sleep] [command]
*
* - yields a "usage" message.
*
* -t causes the clock time to appear in the upper right-
* hand corner of the display.
*
* -s sleep specifies the number of seconds to sleep between execu-
* tions of the "command".
* Default: 15.
*
* command command to be repeatedly executed. If it contains
* pipes, semicolons or metacharacters it should be
* quoted.
* Default: 'ps -ua'
*
*
* EXAMPLES:
*
* The command
*
* monitor -t -s 0 ps -aux
*
* continuously displays the time of day and the first screenful of the
* list of all processes on the system. A more specialized command
*
* monitor 'ls -aCF ; echo "" ; ps -u'
*
* keeps me informed about the contents of my current working directory
* and the status of all of my processes.
*
* The program also has other potential applications. People here at UT
* who want to keep their terminals from being timed out often run shell
* scripts equivalent to the following:
*
* monitor -s 100 w
*
* Finally, you can drive yourself crazy with:
*
* monitor -t -s 5 'echo "" ; /usr/games/fortune'
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*
* Address comments and complaints to:
*
* Prentiss Riddle
*
* 1216-B W. 22nd
* Austin, TX 78705
*
* {ihnp4,kpno,ctvax}!ut-sally!riddle
* riddle at ut-sally.UUCP
*
*/
#include <curses.h>
#include <signal.h>
#define DEFTFLAG FALSE /* default "-t" option flag */
#define DEFSLEEP 15 /* default sleep time */
#define DEFCOM "ps -u" /* default command */
#define BIGSTRING 160 /* length of long strings */
FILE *stream; /* input stream from child process */
main( argc, argv )
int argc;
char *argv[];
{
int atoi(); /* ascii-to-integer function */
int die(); /* function to die gracefully on interrupt */
FILE *popen(); /* (system) open a pipe to a child process */
long time(); /* (system) system time in seconds */
char *ctime(); /* (system) time and date as an ascii string */
long systime; /* result from "time()" */
char *datetime; /* result from "ctime()" */
char justtime[9]; /* clock time (without date) */
char c; /* current character */
int i; /* counter */
int x,y; /* screen coordinates */
char line[BIGSTRING]; /* a line of output from the child proces */
int tflag; /* logical flag for the "-t" option */
int sleepytime; /* seconds to sleep between commands */
char command[BIGSTRING]; /* command to be executed */
char *usage = "usage: monitor [-] [-t] [-s sleep] [command]\n";
/*
* Get arguments and flags. Set defaults first.
*/
tflag = DEFTFLAG;
sleepytime = DEFSLEEP;
strcpy ( command, DEFCOM );
for (i = 1; i < argc && argv[i][0] == '-'; i++) {
if ( strcmp(argv[i],"-t") == 0 ) {
tflag = !tflag;
} else if ( strcmp(argv[i],"-s") == 0 ) {
if ( i >= argc || ! atoi ( argv[++i], &sleepytime ) ) {
fprintf ( stderr,
"monitor: missing sleep argument\n" );
fprintf ( stderr, "%s", usage );
exit(1);
}
} else if ( strcmp(argv[i],"-") == 0 ) {
printf ( "%s", usage );
exit(0);
} else {
fprintf ( stderr,
"monitor: unknown argument %s\n", argv[i] );
fprintf ( stderr, "%s", usage );
exit(1);
}
}
/* collapse any remaining args into "command" */
if ( i < argc )
for ( command[0] = '\0'; i < argc; i++ ) {
append ( command, argv[i] );
append ( command, " " );
}
/* echo the settings */
fprintf (stderr, "monitor ");
if (tflag) fprintf (stderr, "-t ");
fprintf (stderr, "-s %d %s\n", sleepytime, command);
/*
* Initialize things for "curses".
*/
signal ( SIGINT, die );
initscr();
noecho();
nonl();
leaveok ( stdscr, FALSE );
scrollok ( stdscr, FALSE );
/*
* Infinite loop.
*/
while ( TRUE ) {
/* perform the command and copy it to the screen. */
stream = popen ( command, "r" );
y = 0;
do {
x = 0;
while ( x < COLS-1 && (c = getc(stream)) != '\n'
&& c != EOF )
line[x++] = c;
line[x] = '\0';
while ( c != EOF && c != '\n' )
c = getc(stream);
mvaddstr ( y++, 0, line );
clrtoeol();
} while ( y < LINES && c != EOF );
clrtobot();
pclose ( stream );
/* print the time */
if ( tflag ) {
systime = time(0);
datetime = ctime ( &systime );
substr ( datetime, 11, 18, justtime );
move ( 0, COLS-13 );
standout();
addstr ( justtime );
standend();
}
/* flag it if the screen wouldn't hold everything */
if ( y >= LINES ) {
move ( 0, COLS-4 );
standout();
addstr ( "..." );
standend();
}
/* have "curses" refresh the screen and rest up for next time. */
refresh();
if (sleepytime > 0)
sleep ( sleepytime );
}
}
int atoi ( a, i )
/*
* Ascii-to-integer converter.
* Returns "1" if conversion successful, "0" if it fails.
*/
char a[];
int *i;
{
int j;
char c;
*i = 0;
for (j = 0; (c = a[j]) != '\0'; j++) {
if ( c >= '0' && c <= '9' )
*i = 10 * *i + c - '0';
else
return ( 0 );
}
return ( 1 );
}
append ( str1, str2 )
/*
* Copies str2 to the end of str1.
* str2 had better be big enough!
*/
char *str1,*str2;
{
int i,j;
/* find the end of str1 */
for ( i = 0 ; str1[i] != '\0' ; i++ ) ;
/* do the append */
for ( j = 0 ; (str1[i++] = str2[j++]) != '\0' ; ) ;
}
die() {
/*
* routine to die gracefully upon interrupt.
*/
/* handle the interrupt */
signal ( SIGINT, SIG_IGN );
/* close curses */
move ( LINES-1, 0 );
/*DEBUG addch ( ' ' ); DEBUG*/
refresh();
endwin();
/* close the "system" process */
pclose ( stream );
/* bye-bye */
exit(0);
}
substr ( str, f, t, sub )
/*
* Copies str[f..t] to sub[]. Copying stops if a '\0' is encountered.
* If t < 0 it is assumed to be infinite.
* There had better be enough space in sub[] for the result!
*/
int f, t;
char str[], sub[];
{
char c;
int i,j;
if (t < 0) t = 32000;
i = f;
j = 0;
while ( i <= t && (c = str[i]) != '\0' ) {
sub[j] =c;
++i;
++j;
}
sub[j] = '\0';
}
More information about the Comp.sources.unix
mailing list