9fans - fans of the OS Plan 9 from Bell Labs
 help / color / mirror / Atom feed
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




             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).