* Includes termios.h in sys/ioctl.h, for TIOCGWINSZ.

* added watch command, which executes a program periodically, showing output full screen. 
* added watch to the image.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@30900 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Jérôme Duval
2009-05-28 20:16:35 +00:00
parent 5f447d9b4c
commit 7abb735ac6
4 changed files with 286 additions and 1 deletions
+1 -1
View File
@@ -60,7 +60,7 @@ SYSTEM_BIN = "[" addattr alert arp base64 basename bash bc beep bootman bzip2
tr traceroute translate trash true truncate tsort tty
uname unchop unexpand unmount uniq unlink unrar unshar unzip unzipsfx
<bin>updatedb uptime urlwrapper useradd uudecode uuencode
vdir version vim vmstat waitfor wc wget whoami xargs xres yes
vdir version vim vmstat waitfor watch wc wget whoami xargs xres yes
zdiff zforce zgrep zip zipcloak <bin>zipgrep zipnote zipsplit zmore znew
;
+2
View File
@@ -5,6 +5,8 @@
#ifndef _SYS_IOCTL_H
#define _SYS_IOCTL_H
#include <termios.h>
/* These only work on sockets for now */
#define FIONBIO 0xbe000000
#define FIONREAD 0xbe000001
+6
View File
@@ -5,6 +5,7 @@ SetSubDirSupportedPlatformsBeOSCompatible ;
UsePrivateHeaders app shared storage support usb ;
UsePrivateSystemHeaders ;
SubDirHdrs $(HAIKU_TOP) src add-ons kernel file_cache ;
UseLibraryHeaders ncurses ;
local haiku-utils_rsrc = [ FGristFiles haiku-utils.rsrc ] ;
@@ -170,6 +171,11 @@ StdBinCommands
filepanel.cpp
: be tracker : $(haiku-utils_rsrc) ;
# standard commands that need libncurses.a
StdBinCommands
watch.c
: libncurses.a : $(haiku-utils_rsrc) ;
SubInclude HAIKU_TOP src bin addattr ;
SubInclude HAIKU_TOP src bin bash ;
SubInclude HAIKU_TOP src bin bc ;
+277
View File
@@ -0,0 +1,277 @@
/* watch -- execute a program repeatedly, displaying output fullscreen
*
* Based on the original 1991 'watch' by Tony Rems <[email protected]>
* (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 <[email protected]>.
*
* Changes by Albert Cahalan, 2002-2003.
*/
#define VERSION "0.2.0"
#include <ctype.h>
#include <getopt.h>
#include <signal.h>
#include <ncurses.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/ioctl.h>
#include <time.h>
#include <unistd.h>
#include <locale.h>
/* #include "proc/procps.h" */
static struct option longopts[] = {
{"differences", optional_argument, 0, 'd'},
{"help", no_argument, 0, 'h'},
{"interval", required_argument, 0, 'n'},
{"no-title", no_argument, 0, 't'},
{"version", no_argument, 0, 'v'},
{0, 0, 0, 0}
};
static char usage[] =
"Usage: %s [-dhntv] [--differences[=cumulative]] [--help] [--interval=<n>] [--no-title] [--version] <command>\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;
static int show_title = 2; // number of lines used, 2 or 0
#define min(x,y) ((x) > (y) ? (y) : (x))
//static void do_usage(void) NORETURN;
static void do_usage(void)
{
fprintf(stderr, usage, progname);
exit(1);
}
//static void do_exit(int status) NORETURN;
static void do_exit(int status)
{
if (curses_started)
endwin();
exit(status);
}
/* signal handler */
//static void die(int notused) NORETURN;
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 */
setlocale(LC_ALL, "");
progname = argv[0];
while ((optc = getopt_long(argc, argv, "+d::hn:vt", 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 't':
show_title = 0;
break;
case 'n':
{
char *str;
interval = strtol(optarg, &str, 10);
if (!*optarg || *str)
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=<seconds>\t\tseconds to wait between updates\n", stderr);
fputs(" -v, --version\t\t\t\tprint the version number\n", stderr);
fputs(" -t, --no-title\t\t\tturns off showing the header\n", stderr);
exit(0);
}
if (optind >= argc)
do_usage();
command = strdup(argv[optind++]);
command_length = strlen(command);
for (; optind < argc; optind++) {
char *endp;
int s = strlen(argv[optind]);
command = realloc(command, command_length + s + 2); /* space and \0 */
endp = command + command_length;
*endp = ' ';
memcpy(endp + 1, argv[optind], s);
command_length += 1 + s; /* space then string length */
command[command_length] = '\0';
}
get_terminal_size();
/* Catch keyboard interrupts so we can put tty back in a sane state. */
signal(SIGINT, die);
signal(SIGTERM, die);
signal(SIGHUP, die);
signal(SIGWINCH, winch_handler);
/* Set up tty for curses use. */
curses_started = 1;
initscr();
nonl();
noecho();
cbreak();
for (;;) {
time_t t = time(NULL);
char *ts = ctime(&t);
int tsl = strlen(ts);
char *header;
FILE *p;
int x, y;
int oldeolseen = 1;
if (screen_size_changed) {
get_terminal_size();
resizeterm(height, width);
clear();
/* redrawwin(stdscr); */
screen_size_changed = 0;
first_screen = 1;
}
if (show_title) {
// left justify interval and command,
// right justify time, clipping all to fit window width
asprintf(&header, "Every %ds: %.*s",
interval, min(width - 1, command_length), command);
mvaddstr(0, 0, header);
if (strlen(header) > (size_t) (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 = show_title; y < height; y++) {
int eolseen = 0, tabpending = 0;
for (x = 0; x < width; x++) {
int c = ' ';
int attr = 0;
if (!eolseen) {
/* if there is a tab pending, just spit spaces until the
next stop instead of reading characters */
if (!tabpending)
do
c = getc(p);
while (c != EOF && !isprint(c)
&& c != '\n'
&& c != '\t');
if (c == '\n')
if (!oldeolseen && x == 0) {
x = -1;
continue;
} else
eolseen = 1;
else if (c == '\t')
tabpending = 1;
if (c == EOF || c == '\n' || c == '\t')
c = ' ';
if (tabpending && (((x + 1) % 8) == 0))
tabpending = 0;
}
move(y, x);
if (option_differences) {
int oldch = inch();
char oldc = oldch & A_CHARTEXT;
attr = !first_screen
&& (c != oldc
||
(option_differences_cumulative
&& (oldch & A_ATTRIBUTES)));
}
if (attr)
standout();
addch(c);
if (attr)
standend();
}
oldeolseen = eolseen;
}
pclose(p);
first_screen = 0;
refresh();
sleep(interval);
}
endwin();
return 0;
}