Compare commits
No commits in common. "56c17f8131f82c7fd529521c1aba38ecb148ded8" and "f725e8b4336ec58db54ae945fc7523bd06ae59a9" have entirely different histories.
56c17f8131
...
f725e8b433
4 changed files with 8 additions and 303 deletions
|
@ -36,7 +36,7 @@ plumb start window rc -c '''echo % mail '''$0'; mail '$0
|
||||||
# audio
|
# audio
|
||||||
type is text
|
type is text
|
||||||
data matches '[a-zA-Z¡-0-9_\-.,/]+'
|
data matches '[a-zA-Z¡-0-9_\-.,/]+'
|
||||||
data matches '([a-zA-Z¡-0-9_\-.,/]+)\.(mp3|MP3|ogg|OGG|flac|FLAC|wav|WAV|au|AU|mid|MID|mus|MUS|m3u|M3U|pls|PLS|opus|OPUS)'
|
data matches '([a-zA-Z¡-0-9_\-.,/]+)\.(mp3|MP3|ogg|OGG|flac|FLAC|wav|WAV|au|AU|mid|MID|mus|MUS|m3u|M3U|pls|PLS)'
|
||||||
arg isfile $0
|
arg isfile $0
|
||||||
plumb to audio
|
plumb to audio
|
||||||
plumb start window -scroll play $file
|
plumb start window -scroll play $file
|
||||||
|
@ -44,7 +44,7 @@ plumb start window -scroll play $file
|
||||||
# image files go to page
|
# image files go to page
|
||||||
type is text
|
type is text
|
||||||
data matches '[a-zA-Z¡-0-9_\-.,/]+'
|
data matches '[a-zA-Z¡-0-9_\-.,/]+'
|
||||||
data matches '([a-zA-Z¡-0-9_\-.,/]+)\.(jpe?g|JPE?G|gif|GIF|tiff?|TIFF?|ppm|PPM|bit|BIT|png|PNG|pgm|PGM|bmp|BMP|yuv|YUV|tga|TGA|webp|WEBP|img|IMG)'
|
data matches '([a-zA-Z¡-0-9_\-.,/]+)\.(jpe?g|JPE?G|gif|GIF|tiff?|TIFF?|ppm|PPM|bit|BIT|png|PNG|pgm|PGM|bmp|BMP|yuv|YUV|tga|TGA)'
|
||||||
arg isfile $0
|
arg isfile $0
|
||||||
plumb to image
|
plumb to image
|
||||||
plumb client page -wi
|
plumb client page -wi
|
||||||
|
@ -107,12 +107,12 @@ data matches '([a-zA-Z¡-
|
||||||
plumb start rc -c 'man -b '$2' '$1'
|
plumb start rc -c 'man -b '$2' '$1'
|
||||||
|
|
||||||
# RFC references are looked up in /lib/rfc and passed to editor
|
# RFC references are looked up in /lib/rfc and passed to editor
|
||||||
type is text
|
type is text
|
||||||
data matches '[Rr][Ff][Cc] ?([0-9]+)'
|
data matches 'RFC ?([0-9]+)'
|
||||||
arg isfile /lib/rfc/rfc$1.html
|
arg isfile /lib/rfc/rfc$1
|
||||||
data set file:///$file
|
data set $file
|
||||||
plumb to web
|
plumb to edit
|
||||||
plumb client window $browser -a
|
plumb client window $editor
|
||||||
|
|
||||||
# start rule for images without known suffixes
|
# start rule for images without known suffixes
|
||||||
dst is image
|
dst is image
|
||||||
|
|
|
@ -1,14 +0,0 @@
|
||||||
</$objtype/mkfile
|
|
||||||
|
|
||||||
TARG=watch
|
|
||||||
OFILES=$TARG.$O
|
|
||||||
BIN=$home/bin/$objtype
|
|
||||||
MAN=/sys/man/1
|
|
||||||
|
|
||||||
</sys/src/cmd/mkone
|
|
||||||
|
|
||||||
install:V: man
|
|
||||||
|
|
||||||
uninstall:V:
|
|
||||||
rm -f $BIN/$TARG
|
|
||||||
rm -f $MAN/$TARG
|
|
|
@ -1,213 +0,0 @@
|
||||||
#include <u.h>
|
|
||||||
#include <libc.h>
|
|
||||||
#include <regexp.h>
|
|
||||||
|
|
||||||
typedef struct List List;
|
|
||||||
struct List {
|
|
||||||
List *next;
|
|
||||||
union {
|
|
||||||
Dir;
|
|
||||||
Reprog *re;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
char pwd[1024];
|
|
||||||
int period = 1000;
|
|
||||||
int noregroup = 0;
|
|
||||||
int once = 0;
|
|
||||||
List *expl;
|
|
||||||
List *filel;
|
|
||||||
|
|
||||||
void
|
|
||||||
usage(void)
|
|
||||||
{
|
|
||||||
fprint(2, "usage: %s [-G] [[-e expr] ...] [-t sec] [cmd]\n", argv0);
|
|
||||||
exits("usage");
|
|
||||||
}
|
|
||||||
|
|
||||||
void*
|
|
||||||
emalloc(ulong sz)
|
|
||||||
{
|
|
||||||
void *v = malloc(sz);
|
|
||||||
if(v == nil)
|
|
||||||
sysfatal("malloc: %r");
|
|
||||||
setmalloctag(v, getcallerpc(&sz));
|
|
||||||
memset(v, 0, sz);
|
|
||||||
return v;
|
|
||||||
}
|
|
||||||
char*
|
|
||||||
estrdup(char *s)
|
|
||||||
{
|
|
||||||
if((s = strdup(s)) == nil)
|
|
||||||
sysfatal("strdup: %r");
|
|
||||||
setmalloctag(s, getcallerpc(&s));
|
|
||||||
return s;
|
|
||||||
}
|
|
||||||
|
|
||||||
char*
|
|
||||||
join(char **arg)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
char *s, *p;
|
|
||||||
|
|
||||||
s = estrdup("");
|
|
||||||
for(i = 0; arg[i]; i++){
|
|
||||||
p = s;
|
|
||||||
if((s = smprint("%s %s", s, arg[i])) == nil)
|
|
||||||
sysfatal("smprint: %r");
|
|
||||||
free(p);
|
|
||||||
}
|
|
||||||
return s;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
eadd(char *exp)
|
|
||||||
{
|
|
||||||
List *r;
|
|
||||||
|
|
||||||
r = emalloc(sizeof(*r));
|
|
||||||
r->re = regcomp(exp);
|
|
||||||
r->next = expl;
|
|
||||||
expl = r;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
fadd(Dir *d)
|
|
||||||
{
|
|
||||||
List *f;
|
|
||||||
|
|
||||||
f = emalloc(sizeof(*f));
|
|
||||||
f->Dir = *d;
|
|
||||||
f->next = filel;
|
|
||||||
filel = f;
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
tracked(char *name)
|
|
||||||
{
|
|
||||||
List *r;
|
|
||||||
|
|
||||||
for(r = expl; r; r = r->next)
|
|
||||||
if(regexec(r->re, name, nil, 0))
|
|
||||||
return 1;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
changed(Dir *d)
|
|
||||||
{
|
|
||||||
List *f;
|
|
||||||
|
|
||||||
for(f = filel; f; f = f->next)
|
|
||||||
if(f->type == d->type)
|
|
||||||
if(f->dev == d->dev)
|
|
||||||
if(f->qid.path == d->qid.path)
|
|
||||||
if(f->qid.type == d->qid.type)
|
|
||||||
if(f->qid.vers == d->qid.vers)
|
|
||||||
return 0;
|
|
||||||
else{
|
|
||||||
f->Dir = *d;
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
fadd(d);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
watch(void)
|
|
||||||
{
|
|
||||||
static int first = 1;
|
|
||||||
long fd, n;
|
|
||||||
Dir *d, *p;
|
|
||||||
|
|
||||||
for(;;){
|
|
||||||
sleep(period);
|
|
||||||
if((fd = open(pwd, OREAD)) < 0)
|
|
||||||
sysfatal("open: %r");
|
|
||||||
if((n = dirreadall(fd, &d)) < 0)
|
|
||||||
sysfatal("dirreadall: %r");
|
|
||||||
close(fd);
|
|
||||||
for(p = d; n--; p++){
|
|
||||||
if(tracked(p->name)){
|
|
||||||
if(first){
|
|
||||||
fadd(p);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if(changed(p)){
|
|
||||||
free(d);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
first = 0;
|
|
||||||
free(d);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
rc(char *cmd)
|
|
||||||
{
|
|
||||||
Waitmsg *m;
|
|
||||||
|
|
||||||
switch(fork()){
|
|
||||||
case -1: sysfatal("fork: %r");
|
|
||||||
case 0:
|
|
||||||
execl("/bin/rc", "rc", "-c", cmd, nil);
|
|
||||||
sysfatal("execl: %r");
|
|
||||||
}
|
|
||||||
if((m = wait()) && m->msg[0])
|
|
||||||
fprint(2, "watch: %s\n", m->msg);
|
|
||||||
free(m);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
regroup(void)
|
|
||||||
{
|
|
||||||
char *cmd;
|
|
||||||
|
|
||||||
cmd = smprint("cat /proc/%d/noteid >/proc/%d/noteid",
|
|
||||||
getppid(), getpid());
|
|
||||||
rc(cmd);
|
|
||||||
free(cmd);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
main(int argc, char *argv[])
|
|
||||||
{
|
|
||||||
int t;
|
|
||||||
char *unit;
|
|
||||||
char *cmd;
|
|
||||||
|
|
||||||
cmd = "mk";
|
|
||||||
ARGBEGIN{
|
|
||||||
case 'e':
|
|
||||||
eadd(EARGF(usage())); break;
|
|
||||||
case 't':
|
|
||||||
t = strtol(EARGF(usage()), &unit, 10);
|
|
||||||
if(t < 0)
|
|
||||||
t = -t;
|
|
||||||
if(unit != nil && strncmp(unit, "ms", 2) == 0)
|
|
||||||
period = t;
|
|
||||||
else
|
|
||||||
period = t*1000;
|
|
||||||
break;
|
|
||||||
case 'G':
|
|
||||||
noregroup = 1; break;
|
|
||||||
case '1':
|
|
||||||
once = 1; break;
|
|
||||||
default: usage();
|
|
||||||
}ARGEND;
|
|
||||||
if(expl == nil)
|
|
||||||
eadd("\.[chsy]$");
|
|
||||||
if(argc > 0)
|
|
||||||
cmd = join(argv);
|
|
||||||
if(getwd(pwd, sizeof pwd) == nil)
|
|
||||||
sysfatal("getwd: %r");
|
|
||||||
|
|
||||||
if(noregroup == 0) regroup();
|
|
||||||
for(;;){
|
|
||||||
watch();
|
|
||||||
rc(cmd);
|
|
||||||
if(once) exits(nil);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,68 +0,0 @@
|
||||||
.TH WATCH 1
|
|
||||||
.SH NAME
|
|
||||||
watch \- run a command on file change
|
|
||||||
.SH SYNOPSIS
|
|
||||||
.B watch
|
|
||||||
[
|
|
||||||
.B -G
|
|
||||||
] [
|
|
||||||
.B -t
|
|
||||||
sec
|
|
||||||
] [[
|
|
||||||
.B -e
|
|
||||||
pattern
|
|
||||||
] ... ] [
|
|
||||||
.B command
|
|
||||||
]
|
|
||||||
.SH DESCRIPTION
|
|
||||||
.PP
|
|
||||||
Run
|
|
||||||
.IR command
|
|
||||||
.RB ( mk
|
|
||||||
by default) when a change to files
|
|
||||||
in the current directory is detected.
|
|
||||||
.PP
|
|
||||||
The options are as follows:
|
|
||||||
.TF "-e pattern"
|
|
||||||
.TP
|
|
||||||
.BI -e pattern
|
|
||||||
Watch files matching a
|
|
||||||
.IR pattern ;
|
|
||||||
it may be given multiple times and
|
|
||||||
defaults to
|
|
||||||
.BR \e.[chsy]$
|
|
||||||
.TP
|
|
||||||
.BI -t period
|
|
||||||
Sets the polling
|
|
||||||
.IR period
|
|
||||||
in seconds (one second by default).
|
|
||||||
\'ms' can be appended to the value
|
|
||||||
to specify time in miliseconds.
|
|
||||||
.TP
|
|
||||||
.B -G
|
|
||||||
Prevents regrouping to the parent
|
|
||||||
process' note group. The default
|
|
||||||
to regroup was chosen to make it
|
|
||||||
easy to kill
|
|
||||||
.I watch
|
|
||||||
in common use by interrupting the
|
|
||||||
parent shell.
|
|
||||||
.SH EXAMPLES
|
|
||||||
.EX
|
|
||||||
watch -e '\e.man$' 'mk install; window man -P prog' &
|
|
||||||
.EE
|
|
||||||
.SH SEE ALSO
|
|
||||||
.SH SOURCE
|
|
||||||
.B git://code.a-b.xyz/watch
|
|
||||||
.SH BUGS
|
|
||||||
.I Watch
|
|
||||||
will not react on file removal.
|
|
||||||
.PP
|
|
||||||
.I Qid.vers
|
|
||||||
is watched for changes, which is
|
|
||||||
not maintained by every file server.
|
|
||||||
.PP
|
|
||||||
The polling period is actually
|
|
||||||
.I sec
|
|
||||||
plus the time it takes to run
|
|
||||||
.IR command .
|
|
Loading…
Reference in a new issue