[comp.sources.unix] v24i084: Repeatedly execute a program under curses

rsalz@uunet.uu.net (Rich Salz) (03/27/91)

Submitted-by: Tony Rems <rembo@unisoft.com>
Posting-number: Volume 24, Issue 84
Archive-name: watch

[  I had to comment out EXTHDRS, the header dependencies for watch.o,
   and remove $(LIBS) as a dependent in $(DEST)/$(PROGRAM); you might have
   to do some fiddling, too.  It's nice to have a version of this tool
   that is not covered by obnoxious copyrights.  --r$ ]

The following program is called 'watch' it is a curses(3) based program
that allows you to specify a command such as ps(1) to "watch".  It
defaults to updating every two seconds and displays the time.  It's much
nicer than trying to type things over every couple of seconds or using a
for loop.

-------------------------cut-here------------------------------------
#! /bin/sh
# This is a shell archive, meaning:
# 1. Remove everything above the #! /bin/sh line.
# 2. Save the resulting text in a file.
# 3. Execute the file with /bin/sh (not csh) to create:
#	Makefile
#	watch.c
#	README
#	MANIFEST
#	watch.1
# This archive created: Thu Mar  7 21:57:47 1991
export PATH; PATH=/bin:/usr/bin:$PATH
if test -f 'Makefile'
then
	echo shar: "will not over-write existing file 'Makefile'"
else
cat << \SHAR_EOF > 'Makefile'
DEST	      = .

CC	      = cc

#uncomment the following line if you are using a System V machine
#CFLAGS	      = -DATT 

#EXTHDRS	      = /usr/include/curses.h \
#		/usr/include/sgtty.h \
#		/usr/include/signal.h \
#		/usr/include/stdio.h \
#		/usr/include/sys/fcntl.h \
#		/usr/include/sys/ioctl.h \
#		/usr/include/sys/ioctl.h \
#		/usr/include/sys/sgtty.h \
#		/usr/include/sys/sysmacros.h \
#		/usr/include/sys/sysmacros.h \
#		/usr/include/sys/ttychars.h \
#		/usr/include/sys/ttychars.h \
#		/usr/include/sys/ttydev.h \
#		/usr/include/sys/ttydev.h \
#		/usr/include/sys/types.h \
#		/usr/include/sys/types.h

HDRS	      =

LDFLAGS	      =

LIBS	      = -lcurses -ltermcap

LINKER	      = cc

MAKEFILE      = Makefile

FILES	      = Makefile watch.c README MANIFEST watch.1

OBJS	      = watch.o

PRINT	      = pr

PROGRAM	      = watch

SRCS	      = watch.c

all:		$(PROGRAM)

$(PROGRAM):     $(OBJS) 
		@echo -n "Loading $(PROGRAM) ... "
		@$(LINKER) $(LDFLAGS) $(OBJS) -o $(PROGRAM) $(LIBS)
		@echo "done"

clean:;		@echo "rm -f $(OBJS)"
		@rm -f $(OBJS) 

depend:;	@mkmf -f $(MAKEFILE) PROGRAM=$(PROGRAM) DEST=$(DEST)

index:;		@ctags -wx $(HDRS) $(SRCS)

install:	$(PROGRAM)
		@echo Installing $(PROGRAM) in $(DEST)
		@install -s $(PROGRAM) $(DEST)

shar:;		@echo "shar $(FILES) > $(PROGRAM).shar
		@shar $(FILES) > $(PROGRAM).shar

print:;		@$(PRINT) $(HDRS) $(SRCS)

program:        $(PROGRAM)

tags:           $(HDRS) $(SRCS); @ctags $(HDRS) $(SRCS)

update:		$(DEST)/$(PROGRAM)

$(DEST)/$(PROGRAM): $(SRCS) $(HDRS) $(EXTHDRS)
		@make -f $(MAKEFILE) DEST=$(DEST) install
###
#watch.o: /usr/include/curses.h /usr/include/stdio.h /usr/include/sgtty.h \
#	/usr/include/sys/ioctl.h /usr/include/sys/ttychars.h \
#	/usr/include/sys/ttydev.h /usr/include/sys/ttychars.h \
#	/usr/include/sys/ttydev.h /usr/include/sys/sgtty.h \
#	/usr/include/sys/ioctl.h /usr/include/signal.h \
#	/usr/include/sys/fcntl.h /usr/include/sys/types.h \
#	/usr/include/sys/sysmacros.h /usr/include/sys/sysmacros.h \
#	/usr/include/sys/types.h
SHAR_EOF
fi
if test -f 'watch.c'
then
	echo shar: "will not over-write existing file 'watch.c'"
else
cat << \SHAR_EOF > 'watch.c'
#include <curses.h>
#include <stdio.h>
#include <signal.h>
#include <sys/fcntl.h>

#ifdef ATT
#define	crmode()	cbreak()
#define bzero(s,n)	memset(s,0,n)
#endif

void	die();
extern	FILE 		*popen();
extern	int 		pclose();
extern	long		time();
extern	char		*ctime();

main(argc, argv)
int argc;
char *argv[];
{
	int hor = 1, ver = 0;
	FILE *piper;
	char buf[180];
	char cmd[128];
	int count = 1;
	long timer;
	int nsecs = 2;

	if (argc < 2) {
		fprintf(stderr, "Usage: %s command [args]\n", argv[0]);
		exit(1);
	} /* if */

	/* If -n is specified, convert the next argument to the numver
	 * for the number of seconds
	 */
	if (strcmp(argv[1], "-n") == 0) {
		nsecs = atoi(argv[2]);
		count = 3;
		if (nsecs == 0 || argc < 3) {
			fprintf(stderr, "Usage: %s command [args]\n", argv[0]);
			exit(1);
		} /* if */
	} /* if */

	/* Build command string to give to popen */
	(void)bzero(cmd, sizeof(cmd));
	strcpy(cmd, argv[count]);
	while (++count < argc) {
		strcat(cmd, " ");
		strcat(cmd, argv[count]);
	} /* while */

	/* Catch keyboard interrupts so we can
	 * put tty back in a sane state 
	 */
	(void) signal(SIGINT, die);
	(void) signal(SIGTERM, die);
	(void) signal(SIGHUP, die);

	/* Set up tty for curses use */
	initscr();
	nonl();
	noecho();
	crmode();

	while(1) { /* loop forever */

		/* Put up time interval and current time */
		move(hor, ver);
		time(&timer);
		printw("Every %d seconds\t\t%s\t\t%s", nsecs, cmd, ctime(&timer));
		hor = 3;

		/* Open pipe to command */
		if ((piper = popen(cmd, "r")) == (FILE *)NULL) {
			perror("popen");
			exit(2);
		} /* if */


		/* Read in output from the command and make sure 
	 	* that it will fit on 1 screen 
	 	*/
		while ((fgets(buf, sizeof(buf), piper) != NULL) && hor < LINES) {
			buf[COLS-1] = '\0';
			mvaddstr(hor, ver, buf);
			hor++;
		} /* while */
		refresh();

		sleep(nsecs);
		hor = 1; /* Go back to the top of screen */
		pclose(piper);

	} /* while */
} /* main */


void
die()
{
	/* Ignore interrupts while we clear the screen
	 * and reset the tty 
	 */
	(void) signal(SIGINT, SIG_IGN);
	clear(); 
	refresh(); 
	endwin();
	exit(0);
} /* die */
SHAR_EOF
fi
if test -f 'README'
then
	echo shar: "will not over-write existing file 'README'"
else
cat << \SHAR_EOF > 'README'

THE PROGRAM:
watch is a program to catch and repeatedly update the output 
from any program you want to repeatedly catch the output from.
It is a curses based program and allows you to specify the 
interval.

COMPILING IT:
watch should compile with no problems on any 4.2 BSD or later
system.  I've compiled it on a Pyramid and a Sun3 running 3.5
and one running 4.0.3.  If you uncomment the CFLAGS line in the
makefile, the program should compile on a System V3 or later 
system.  I tested it out on the Pyramid in the AT&T universe
and on an Intel 486 running SVR4.  If you still have problems,
just send mail to rembo@unisoft.com.  I'll help if I can.
SHAR_EOF
fi
if test -f 'MANIFEST'
then
	echo shar: "will not over-write existing file 'MANIFEST'"
else
cat << \SHAR_EOF > 'MANIFEST'
You should have:
	MANIFEST
	README
	Makefile
	watch.c
	watch.1
SHAR_EOF
fi
if test -f 'watch.1'
then
	echo shar: "will not over-write existing file 'watch.1'"
else
cat << \SHAR_EOF > 'watch.1'



watch(1)         Pyramid OSx Operating System          watch(1)



NAME
     watch - watch a program with update intervals

SYNOPSIS
     watch  [-n] _s_e_c_o_n_d_s _p_r_o_g_r_a_m [ _a_r_g_s ... ]

DESCRIPTION
     _w_a_t_c_h is a curses(3X) based program that allows 
     you to watch a program as it changes.  By default, it 
     updates itself every 2 seconds.  You can specify the number 
     of seconds with the -n option.  The curses packages allows 
     for quick updating of the screen through cursor 
     optimization.  The program will end with a keyboard 
     interrupt, which will leave the screen in a 
     valid yet cleared state.

EXAMPLE
     try:
	
     On BSD:
	watch -n 1 ps u

     On System V:
	watch -n 1 ps -f

SEE ALSO
     curses(3X)












Printed 11/8/90                                                 1



SHAR_EOF
fi
exit 0
#	End of shell archive

exit 0 # Just in case...
-- 
Please send comp.sources.unix-related mail to rsalz@uunet.uu.net.
Use a domain-based address or give alternate paths, or you may lose out.