9front - general discussion about 9front
 help / color / mirror / Atom feed
From: umbraticus@prosimetrum.com
To: 9front@9front.org
Subject: [9front] plumber: allow create
Date: Mon, 18 Jul 2022 22:56:00 +1200	[thread overview]
Message-ID: <ED34C191BDB57DF4E46F8173246895C1@prosimetrum.com> (raw)

This patch allows new plumb ports to be create()ed.
Currently you can add a new port by doing:

echo plumb to myport >> /mnt/plumb/rules

so this is basically a convenience, though one which seems
to be anticipated by /sys/src/libplumb/mesg.c:/creating

This means that even if you run: plumber -p /dev/mordor
you can start a rio with page, sam, zuke and see their ports
appear in /mnt/plumb, then eg. plumb -d image /cat.jpg
It may also be useful for some kinds of adhoc shenanigans,
eg. touch /mnt/plumb/bcast; then, in a bunch of windows:
	</mnt/plumb/bcast while(read -n5 >/dev/null){
		read -c `{read}
		echo
	}
and plumb -d bcast 'hello all', or something.

umbraticus

diff d4eb08a86007787b046221fa6c76788fbec1f597 uncommitted
--- a/sys/src/cmd/plumb/fsys.c
+++ b/sys/src/cmd/plumb/fsys.c
@@ -87,16 +87,15 @@
 	Qrules	= 1,
 	Qsend	= 2,
 	Qport	= 3,
-	NQID	= Qport
 };
 
 static Dirtab dir[NDIR] =
 {
-	{ ".",			QTDIR,	Qdir,			0500|DMDIR },
+	{ ".",			QTDIR,	Qdir,			0700|DMDIR },
 	{ "rules",		QTFILE,	Qrules,		0600 },
 	{ "send",		QTFILE,	Qsend,		0200 },
 };
-static int	ndir = NQID;
+static int	ndir = Qport;
 
 static int		srvfd;
 static int		mntfd;
@@ -157,19 +156,19 @@
 /*
  * Add new port.  A no-op if port already exists or is the null string
  */
-void
+uvlong
 addport(char *port)
 {
 	int i;
 
 	if(port == nil)
-		return;
-	for(i=NQID; i<ndir; i++)
+		return 0;
+	for(i=0; i<ndir; i++)
 		if(strcmp(port, dir[i].name) == 0)
-			return;
+			return i;
 	if(i == NDIR){
 		fprint(2, "plumb: too many ports; max %d\n", NDIR);
-		return;
+		return 0;
 	}
 	ndir++;
 	dir[i].name = estrdup(port);
@@ -178,6 +177,7 @@
 	nports++;
 	ports = erealloc(ports, nports*sizeof(char*));
 	ports[nports-1] = dir[i].name;
+	return i;
 }
 
 static ulong
@@ -229,7 +229,7 @@
 		error("can't write /srv/file: %r");
 	procrfork(fsysproc, nil, Stack, RFFDG);
 	close(srvfd);
-	if(mount(mntfd, -1, "/mnt/plumb", MREPL, "") == -1)
+	if(mount(mntfd, -1, "/mnt/plumb", MREPL|MCREATE, "") == -1)
 		error("can't mount /mnt/plumb: %r");
 }
 
@@ -266,7 +266,9 @@
 		if(fcall[t->type] == nil)
 			fsysrespond(t, buf, Ebadfcall);
 		else{
-			if(t->type==Tversion || t->type==Tauth)
+			if(t->type==Tversion || t->type==Tauth
+			|| t->type==Tflush || t->type==Tremove
+			|| t->type==Twstat)
 				f = nil;
 			else
 				f = newfid(t->fid);
@@ -545,7 +547,7 @@
 			err = startup(rs, e);
 		plumbfree(m);
 	}else
-		for(i=NQID; i<ndir; i++)
+		for(i=Qport; i<ndir; i++)
 			if(strcmp(m->dst, dir[i].name) == 0){
 				if(dir[i].nopen == 0){
 					err = startup(rs, e);
@@ -620,7 +622,7 @@
 	int i;
 
 	qlock(&queue);
-	for(i=NQID; i<ndir; i++)
+	for(i=Qport; i<ndir; i++)
 		flushqueue(&dir[i], t->oldtag);
 	qunlock(&queue);
 	fsysrespond(t, buf, nil);
@@ -774,9 +776,31 @@
 }
 
 static Fcall*
-fsyscreate(Fcall *t, uchar *buf, Fid*)
+fsyscreate(Fcall *t, uchar *buf, Fid *f)
 {
-	fsysrespond(t, buf, Eperm);
+	int mode;
+	mode = t->mode;
+	if(t->perm & DMDIR
+	|| (t->qid.path = addport(t->name)) < Qport
+	|| (mode & ~(OTRUNC|OCEXEC)) != OREAD){
+	/* port may have been created but only a reader gets a fid */
+		fsysrespond(t, buf, Eperm);
+		return t;
+	}
+	t->qid.type = QTFILE;
+	t->qid.vers = 0;
+	t->iounit = 0;
+	qlock(&queue);
+	f->qid = t->qid;
+	f->mode = mode;
+	f->open = 1;
+	f->dir = dir + t->qid.path;
+	f->dir->nopen++;
+	f->nextopen = f->dir->fopen;
+	f->dir->fopen = f;
+	queueheld(f->dir);
+	qunlock(&queue);
+	fsysrespond(t, buf, nil);
 	return t;
 }
 
@@ -814,7 +838,7 @@
 		if(f->qid.path == Qrules)
 			return fsysreadrules(t, buf);
 		/* read from port */
-		if(f->qid.path < NQID){
+		if(f->qid.path < Qport){
 			fsysrespond(t, buf, "internal error: unknown read port");
 			return t;
 		}
--- a/sys/src/cmd/plumb/plumber.h
+++ b/sys/src/cmd/plumb/plumber.h
@@ -77,7 +77,7 @@
 void		freeexec(Exec*);
 char*	startup(Ruleset*, Exec*);
 char*	printrules(void);
-void		addport(char*);
+uvlong	addport(char*);
 char*	writerules(char*, int);
 char*	expand(Exec*, char*, char**);
 void		makeports(Ruleset*[]);

                 reply	other threads:[~2022-07-18 10:58 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

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=ED34C191BDB57DF4E46F8173246895C1@prosimetrum.com \
    --to=umbraticus@prosimetrum.com \
    --cc=9front@9front.org \
    /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).