From: YAMANASHI Takeshi <9.nashi@gmail.com>
To: 9fans@cse.psu.edu
Subject: Re: [9fans] watch command
Date: Wed, 20 Apr 2005 10:55:09 +0900 [thread overview]
Message-ID: <e4721b326cfb34fec63b721a4e08b316@orthanc.cc.titech.ac.jp> (raw)
Anyway, it's here:
% mk install
% watchfs main.c
"cat /n/watch/ctl" will block until a change has been made
to /n/watch/data/main.c.
KNOWN BUGS:
- it doesn't care about Tflush yet.
- it only accepts files in the current directory.
# To unbundle, run this file
echo mkfile
sed 's/.//' >mkfile <<'//GO.SYSIN DD mkfile'
-</$objtype/mkfile
-BIN=$home/bin/$objtype
-
-TARG=watchfs
-OFILES=\
- main.$O\
-
-</sys/src/cmd/mkone
//GO.SYSIN DD mkfile
echo main.c
sed 's/.//' >main.c <<'//GO.SYSIN DD main.c'
-#include <u.h>
-#include <libc.h>
-#include <auth.h>
-#include <fcall.h>
-#include <thread.h>
-#include <9p.h>
-
-int dbg;
-
-char *uname;
-Channel *cctl, *cctlwait;
-Channel *pctl, *pctlwait;
-Channel *creq;
-
-typedef struct Watchfile Watchfile;
-struct Watchfile {
- Ref;
- Qid qid;
- int fd;
- char *name;
- int dirty;
-};
-
-Watchfile wtab[10];
-int nw;
-
-void wtopen(Req*);
-void wtread(Req*);
-void wtwrite(Req*);
-void wtdestroyfid(Fid*);
-void takedown(Srv*);
-
-enum{
- Qdata= 0,
- Qctl= 1,
-
- STACK = 8192,
-};
-
-int chatty9p;
-Srv fs = {
- .open= wtopen,
- .read= wtread,
- .write= wtwrite,
- .destroyfid = wtdestroyfid,
- .end= takedown,
-};
-
-static void
-dumpQid(Dir *d)
-{
- ulong path;
- path = d->qid.path;
- fprint(2, "name=%s qid=%lux\n", d->name, path);
-}
-
-static void
-dumpWF(void)
-{
- int i;
-
- for(i=0; i<nw; i++)
- fprint(2, "dumpWF: %s %llud\n", wtab[i].name, wtab[i].qid.path);
-}
-
-Watchfile *
-findtab(ulong path)
-{
- int i;
- for(i=0; i<nw; i++)
- if(wtab[i].qid.path == path)
- return &wtab[i];
- return nil;
-}
-
-void
-wtopen(Req *r)
-{
- ulong path;
- Watchfile *wf;
-
- path = r->fid->qid.path;
- switch(path){
- case Qctl:
- case Qdata:
- respond(r, nil);
- return;
- }
-
- /* data/... */
- wf = findtab(path);
- if(wf == nil){
- respond(r, "no file");
- return;
- }
- if(dbg)
- fprint(2, "wtopen: %s %ld fd %d\n", wf->name, wf->ref, wf->fd);
-
- incref(wf);
- if(wf->fd < 0){
- wf->fd = open(wf->name, r->ifcall.mode);
- wf->dirty = 0;
- }
- if(r->ifcall.mode&OTRUNC)
- r->fid->file->length = 0;
- respond(r, nil);
-}
-
-void
-wtread(Req *r)
-{
- char buf[512];
- int n;
- ulong path;
- Watchfile *wf;
-
- path = r->fid->qid.path;
- switch(path){
- case Qdata:
- case Qctl:
- sendp(creq, r);
- return;
- }
-
- /* data/... */
- wf = findtab(r->fid->qid.path);
- if(wf == nil){
- respond(r, "no such qid");
- return;
- }
- if(wf->fd < 0){
- respond(r, "no fd");
- return;
- }
- if(dbg)
- fprint(2, "wtread: %s ref %ld fd %d\n", wf->name, wf->ref, wf->fd);
- n = pread(wf->fd, r->ofcall.data, r->ifcall.count, r->ifcall.offset);
- if(n < 0){
- rerrstr(buf, sizeof buf);
- respond(r, buf);
- return;
- }
- r->ofcall.count = n;
- respond(r, nil);
-}
-
-void
-wtwrite(Req *r)
-{
- char buf[512];
- int n;
- ulong path;
- vlong offset;
- Watchfile *wf;
-
- path = r->fid->qid.path;
- offset = r->ifcall.offset;
-
- switch(path){
- case Qdata:
- case Qctl:
- snprint(buf, sizeof buf, "not yet %lux", path);
- respond(r, buf);
- return;
- }
-
- /* data/... */
- wf = findtab(path);
- if(wf == nil){
- respond(r, "no such qid");
- return;
- }
- if(dbg)
- fprint(2, "wtwrite: %s ref %ld fd %d\n", wf->name, wf->ref, wf->fd);
-
- if(wf->fd < 0){
- respond(r, "no fd");
- return;
- }
-
- n = pwrite(wf->fd, r->ifcall.data, r->ifcall.count, r->ifcall.offset);
- if(n < 0){
- rerrstr(buf, sizeof buf);
- respond(r, buf);
- return;
- }
- if(n+offset >= r->fid->file->length)
- r->fid->file->length = n+offset;
- wf->dirty++;
- r->ofcall.count = n;
- respond(r, nil);
-
-}
-
-void
-wtdestroyfid(Fid *fid)
-{
- ulong path;
- Watchfile *wf;
-
- path = fid->qid.path;
- wf = findtab(path);
- if(wf == nil)
- return;
-
- if(dbg)
- fprint(2, "wtdestroyfid: %s ref %ld fd %d\n", wf->name, wf->ref, wf->fd);
-
- if(wf->fd >= 0){
- if(decref(wf) == 0){
- if(wf->dirty){
- sendp(cctl, wf);
- recvp(cctlwait);
- }
- close(wf->fd);
- wf->fd = -1;
- wf->dirty = 0;
- }
- }
-}
-
-Tree *
-inittree(char **argv)
-{
- Tree *tree;
- File *df;
-
- tree = alloctree(uname, uname, DMDIR|0555, nil);
- df = createfile(tree->root, "data", uname, DMDIR|0555, nil);
- createfile(tree->root, "ctl", uname, 0660, nil);
-
- for(;*argv;argv++){
- File *f;
- Dir *d;
- d = dirstat(*argv);
- if(d == nil)
- continue;
- if(dbg)
- fprint(2, "dir: name %s len %lld\n", d->name, d->length);
- f = createfile(df, *argv, uname, 0660, nil);
- wtab[nw].qid = f->qid;
- wtab[nw].name = estrdup9p(*argv);
- wtab[nw].fd = -1;
- f->length = d->length;
- nw++;
- }
-
- return tree;
-}
-
-static void
-pollthread(void*)
-{
- for(;;){
- sleep(1);
- }
-}
-
-static void
-ctlthread(void*)
-{
- int i, np = 0;
- Alt a[4];
- Req *r, *rtab[10];
- Watchfile *wf;
-
- threadsetname("ctlthread");
-
- a[0].op = CHANRCV;
- a[0].c = creq;
- a[0].v = &r;
- a[1].op = CHANRCV;
- a[1].c = cctl;
- a[1].v = &wf;
- a[2].op = CHANRCV;
- a[2].c = pctl;
- a[2].v = &wf;
- a[3].op = CHANEND;
-
- for(;;){
- switch(alt(a)){
- case 0: /* creq: someone tries to read ctl */
- rtab[np++] = r;
- break;
-
- case 1: /* cctl: ready to serve ctl */
- for(i=0; i<np; i++){
- r = rtab[i];
- snprint(r->ofcall.data, r->ifcall.count,
- "%s %llud\n", wf->name, wf->qid.path);
- r->ofcall.count = strlen(r->ofcall.data);
- respond(r, nil);
- }
- np = 0;
- sendp(cctlwait, 0);
- break;
-
- case 2: /* pctl: poll says modified */
- for(i=0; i<np; i++){
- r = rtab[i];
- snprint(r->ofcall.data, r->ifcall.count,
- "%s %llud\n", wf->name, wf->qid.path);
- r->ofcall.count = strlen(r->ofcall.data);
- respond(r, nil);
- }
- np = 0;
- sendp(pctlwait, 0);
- break;
-
- default:
- break;
- }
- }
-}
-
-void
-initctl(void)
-{
- cctl = chancreate(sizeof(void*), 0);
- cctlwait = chancreate(sizeof(void*), 0);
- pctl = chancreate(sizeof(void*), 0);
- pctlwait = chancreate(sizeof(void*), 0);
- creq = chancreate(sizeof(void*), 0);
- procrfork(ctlthread, nil, STACK, RFNAMEG);
- procrfork(pollthread, nil, STACK, RFNAMEG);
-}
-
-void
-usage(void)
-{
- fprint(2, "usage: watchfs files...\n");
-}
-
-void
-threadmain(int argc, char *argv[])
-{
-
- ARGBEGIN{
- case 'd':
- dbg++;
- break;
- case 'D':
- chatty9p++;
- break;
- }ARGEND;
-
- uname = getuser();
-
- fs.tree = inittree(&argv[0]);
- if(dbg)
- dumpWF();
-
- initctl();
- threadpostmountsrv(&fs, nil, "/n/watch", MREPL|MCREATE);
- threadexits(0);
-}
-
-void
-takedown(Srv*)
-{
- threadexitsall("done");
-}
-
-
-
-
//GO.SYSIN DD main.c
next reply other threads:[~2005-04-20 1:55 UTC|newest]
Thread overview: 26+ messages / expand[flat|nested] mbox.gz Atom feed top
2005-04-20 1:55 YAMANASHI Takeshi [this message]
-- strict thread matches above, loose matches on Subject: below --
2005-04-21 0:37 YAMANASHI Takeshi
2005-04-20 2:09 YAMANASHI Takeshi
2005-04-20 5:14 ` Ronald G. Minnich
2005-04-20 15:06 ` Ronald G. Minnich
2005-04-20 2:07 YAMANASHI Takeshi
2005-04-19 10:50 YAMANASHI Takeshi
2005-04-19 8:59 YAMANASHI Takeshi
2005-04-19 9:19 ` Fco. J. Ballesteros
2005-04-19 10:06 ` Charles Forsyth
2005-04-19 15:01 ` Ronald G. Minnich
2005-04-19 15:23 ` Fco. J. Ballesteros
2005-04-19 15:53 ` Lucio De Re
2005-04-19 15:59 ` Dan Cross
2005-04-19 16:02 ` Steve Simon
2005-04-19 16:23 ` boyd, rounin
2005-04-19 15:00 ` Ronald G. Minnich
2005-04-19 7:13 YAMANASHI Takeshi
2005-04-19 6:57 YAMANASHI Takeshi
2005-04-19 10:47 ` Abhey Shah
2005-04-19 6:49 YAMANASHI Takeshi
2005-04-19 6:50 ` Kenji Okamoto
2005-04-19 6:55 ` boyd, rounin
2005-04-19 6:17 YAMANASHI Takeshi
2005-04-19 6:37 ` Kenji Okamoto
2005-04-19 8:35 ` Fco. J. Ballesteros
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=e4721b326cfb34fec63b721a4e08b316@orthanc.cc.titech.ac.jp \
--to=9.nashi@gmail.com \
--cc=9fans@cse.psu.edu \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).