home *** CD-ROM | disk | FTP | other *** search
- From: vandys@lindy.stanford.edu (Andy Valencia)
- Newsgroups: comp.sources.misc
- Subject: monitor -- monitor a command using curses
- Message-ID: <3266@ncoast.UUCP>
- Date: 21 Jul 87 01:27:10 GMT
- Sender: allbery@ncoast.UUCP
- Lines: 199
- Approved: allbery@ncoast.UUCP
- X-Archive: comp.sources.misc/8707/58
-
- Rich,
- Well, you had to ask. Here's a generalized monitoring program;
- you run it with:
- monitor -i 10 command arg arg...
- It runs the command, then displays the first n (where n is the number
- of lines on your terminal) lines of output on your screen, then cycles each
- 10 seconds (-i means interval--default is 30 seconds). I've seen this hither
- and yon for years, but I keep running into places which don't have it.
- Just compile with:
- cc -O -o monitor monitor.c -lcurses -ltermcap
- Works on my 4.2 system, will need changes for SysV.
-
- /*
- * monitor.c--utility which cyclically takes the output of a command and
- * displays it on the screen via curses(3x).
- */
- #include <stdio.h>
- #include <curses.h>
- #include <signal.h>
- #include <errno.h>
- extern int errno;
- static int numlines;
-
- /*
- * Set up curses
- */
- static void
- setup_screen(){
- static char bp[1024];
- extern char *getenv();
-
- if( getenv("TERM") == NULL ){
- fprintf(stderr,"Please set your TERM variable\n");
- exit(1);
- }
- if( tgetent(bp,getenv("TERM")) != 1 ){
- fprintf(stderr,"I can't use terminal type '%s'\n",getenv("TERM"));
- exit(1);
- }
- if( (numlines = tgetnum("li")) < 0 ){
- fprintf(stderr,"You seem to have an illegal number of lines\n");
- exit(1);
- }
- initscr();
- clear();
- refresh();
- }
-
- /*
- * Run the command, take as many lines of output as will fit on the
- * screen, paint them.
- */
- static void
- paint_screen(cmd)
- char *cmd;
- {
- char tmpf[80], buf[256];
- register char *p;
- FILE *fp;
- register c;
- int kid, kidstat, x, y;
-
- strcpy(tmpf,"/tmp/monXXXXXX");
- mktemp(tmpf);
- if( (kid = fork()) == 0 ){
-
- /*
- * The subprocess's output will go to a file; close stdout and
- * stderr, then re-open them directed to a temp file.
- */
- close(1); close(2);
- dup(creat(tmpf,0700));
-
- /*
- * Just to make sure, disable access to stdin
- */
- close(0);
-
- /*
- * Call the program, return its status
- */
- exit( system(cmd) );
- }
-
- /*
- * Wait for our kid. Kill him off if we get a signal from the user.
- */
- if( wait(&kidstat) < 0 ){
- int hold_errno = errno;
-
- endwin();
- errno = hold_errno;
- perror(cmd[0]);
- kill(kid,SIGKILL);
- unlink(tmpf);
- exit( 1 );
- }
-
- /*
- * Wait didn't return error, check if kid ran OK.
- */
- if( kidstat ){
- endwin();
- fprintf(stderr,"Problem running command\n");
- unlink(tmpf);
- exit( 1 );
- }
-
- /*
- * Suck in tmpf's contents, feed it to curses
- */
- if( (fp = fopen(tmpf,"r")) == NULL ){
- endwin();
- fprintf(stderr,"Error reading file '%s'\n",tmpf);
- exit( 1 );
- }
- unlink(tmpf);
- for( x = 0; x < numlines; ++x ){
- p = buf;
- while( (c = getc(fp)) != EOF )
- if( c == '\n' ) break;
- else *p++ = c;
- if( c == EOF ) break;
- *p = '\0';
- buf[79] = '\0';
- move(x,0);
- clrtoeol();
- addstr(buf);
- }
- for( y = x; y < numlines; ++y ){
- move(y,0);
- clrtoeol();
- }
- move(numlines-1,79);
- fclose(fp);
- refresh();
- }
-
- /*
- * Main routine: get arguments, run the thing
- */
- main(argc,argv)
- int argc;
- char **argv;
- {
- char cmd[4096];
- int interval, x;
-
- /*
- * Give'm help if they need it
- */
- if( argc < 2 ){
- fprintf(stderr,"Usage is: %s [-i <secs>] command [args...]\n",
- argv[0]);
- exit( 1 );
- }
-
- /*
- * If they specify '-i', take a user-specified interval between
- * displays, otherwise default to 30 seconds.
- */
- if( strncmp(argv[1], "-i", 2) == 0 ){
- if( argv[1][2] ){
- interval = atoi(argv[1]+2);
- argv += 2;
- } else {
- interval = atoi(argv[2]);
- argv += 3;
- }
- } else {
- interval = 30;
- ++argv;
- }
-
- /*
- * Build a command line
- */
- cmd[0] = '\0';
- for( x = 0; argv[x]; ++x ){
- strcat(cmd,argv[x]);
- strcat(cmd," ");
- }
-
- /*
- * Prepare curses
- */
- setup_screen();
-
- /*
- * Forever: paint the screen & loop
- */
- while( 1 ){
- paint_screen(cmd);
- sleep(interval);
- }
- }
-
- ------- End of Forwarded Message
-