/* watch -- execute a program repeatedly, displaying output fullscreen * * Based on the original 1991 'watch' by Tony Rems * (with mods and corrections by Francois Pinard). * * Substantially reworked, new features (differences option, SIGWINCH * handling, unlimited command length, long line handling) added Apr 1999 by * Mike Coleman . */ #define VERSION "0.2.0" #include #include #include #include #include #include #include #include #include #include static struct option longopts[] = { { "differences", optional_argument, 0, 'd' }, { "help", no_argument, 0, 'h' }, { "interval", required_argument, 0, 'n' }, { "version", no_argument, 0, 'v' }, { 0, 0, 0, 0 } }; static char usage[] = "Usage: %s [-dhnv] [--differences[=cumulative]] [--help] [--interval=] [--version] \n"; static char *progname; static int curses_started = 0; static int height=24, width=80; static int screen_size_changed=0; static int first_screen=1; #define min(x,y) ((x) > (y) ? (y) : (x)) #define max(x,y) ((x) > (y) ? (x) : (y)) static void do_usage(void) { fprintf(stderr, usage, progname); exit(1); } static void do_exit(int status) { if (curses_started) endwin(); exit(status); } /* signal handler */ static void die(int notused) { (void)notused; do_exit(0); } static void winch_handler(int notused) { (void)notused; screen_size_changed = 1; } static void get_terminal_size(void) { struct winsize w; if (ioctl(2, TIOCGWINSZ, &w) == 0) { if (w.ws_row > 0) height = w.ws_row; if (w.ws_col > 0) width = w.ws_col; } } int main(int argc, char *argv[]) { int optc; int option_differences=0, option_differences_cumulative=0, option_help=0, option_version=0; int interval=2; char *command; int command_length=0; /* not including final \0 */ progname = argv[0]; while ((optc = getopt_long(argc, argv, "+d::hn:v", longopts, (int *) 0)) != EOF) { switch (optc) { case 'd': option_differences = 1; if (optarg) option_differences_cumulative = 1; break; case 'h': option_help = 1; break; case 'n': { char *s; interval = strtol(optarg, &s, 10); if (!*optarg || *s) do_usage(); } break; case 'v': option_version = 1; break; default: do_usage(); break; } } if (option_version) { fprintf (stderr, "%s\n", VERSION); if (!option_help) exit(0); } if (option_help) { fprintf(stderr, usage, progname); fputs(" -d, --differences[=cumulative]\thighlight changes between updates\n", stderr); fputs("\t\t(cumulative means highlighting is cumulative)\n", stderr); fputs(" -h, --help\t\t\t\tprint a summary of the options\n", stderr); fputs(" -n, --interval=\t\tseconds to wait between updates\n", stderr); fputs(" -v, --version\t\t\t\tprint the version number\n", stderr); exit(0); } if (optind >= argc) do_usage(); command = strdup(argv[optind++]); command_length = strlen(command); for (;optind width - tsl - 1) mvaddstr(0, width - tsl - 4, "... "); mvaddstr(0, width - tsl + 1, ts); free(header); if (!(p = popen(command, "r"))) { perror("popen"); do_exit(2); } for (y=2; y