shithub: svcfs

Download patch

ref: b512993b0e23a11ec1de50ebc0b7fee19cf994a9
parent: 49e08b52aee80d61b1302dcf7fe28e96dd0a3973
author: Michael Misch <michaelmisch1985@gmail.com>
date: Sun Jul 7 08:43:46 EDT 2024

Add in tabs, unread counts, and fix a few error

--- a/TODO
+++ b/TODO
@@ -16,10 +16,3 @@
 ## Notifications:
 
 - Create and update them, integrate with tabs
-- Install fmt for printing
-
-## Tabs:
-
-- list available buffers with unread counts, add notify `!` when applicable
-- Install fmt for printing
-- Clearing unreads on the rwakeupall
--- a/alt.h
+++ b/alt.h
@@ -8,7 +8,9 @@
 	char	title[1024];
 	char	status[1024];
 	char	aside[1024];
-	int	fd;
+	int	fd;	// feed
+	int	tag;	// feed
+	int	unread;
 	Channel	*cmds;
 	Notify	*notify;
 	Buffer	*next;
@@ -23,9 +25,13 @@
 
 Buffer *bufferCreate(Channel*);
 Buffer *bufferSearch(Buffer*, char*);
+Buffer *bufferSearchTag(Buffer*, ulong);
 char *bufferDrop(Buffer*, char*);
 char *bufferPush(Buffer*, char*);
 void bufferDestroy(Buffer*);
+
+int Tconv(Fmt*);
+int Nconv(Fmt*);
 
 void* emalloc(int);
 char* estrdup(char*);
--- a/buffer.c
+++ b/buffer.c
@@ -49,6 +49,8 @@
 	b = emalloc(sizeof(*b));
 	b->name = estrdup(name);
 	b->notify = nil;
+	b->unread = 0;
+	b->tag = -1;
 	b->rz.l = b;
 	memset(b->title, 0, sizeof(b->title));
 	memset(b->status, 0, sizeof(b->status));
@@ -74,6 +76,16 @@
 	return nil;
 }
 
+Buffer *
+bufferSearchTag(Buffer *base, ulong tag)
+{
+	Buffer *sp;
+	for(sp = base; sp; sp = sp->next)
+		if(sp->tag == tag)
+			return sp;
+	return nil;
+}
+
 Buffer*
 bufferCreate(Channel *cmds)
 {
@@ -85,6 +97,8 @@
 	memset(b->status, 0, sizeof(b->status));
 	memset(b->aside, 0, sizeof(b->aside));
 	b->cmds = cmds;
+	b->tag = -1;
+	b->unread = 0;
 	b->notify = nil;
 	b->next = nil;
 	b->rz.l = b;
--- a/client.c
+++ b/client.c
@@ -38,6 +38,7 @@
 struct Clfid
 {
 	int	level;
+	int	tag;
 	Client	*cl;
 };
 
@@ -52,6 +53,7 @@
 
 static Client client[256];
 static Buffer *root;
+int flushtag;
 static int nclient;
 static int time0;
 static Srv *fs;
@@ -215,6 +217,7 @@
 	int n;
 
 	f = r->fid->aux;
+	n = 0;
 	switch(f->level){
 	case Qcroot:
 		dirread9p(r, rootgen, f->cl);
@@ -231,15 +234,20 @@
 		srvrelease(fs);
 		qlock(b);
 Again:
-		n = pread(f->cl->fd, buf, sizeof(buf), r->ifcall.offset);
-		if(n){
-			// cut off the EOF
-			r->ofcall.count = n;
-			memmove(r->ofcall.data, buf, n);
-		} else{
-			rsleep(&b->rz);
-			goto Again;
-		}
+		// Check if we have a tag here, abort early if so.
+		if(b->tag != flushtag){	
+			n = pread(f->cl->fd, buf, sizeof(buf), r->ifcall.offset);
+			if(n){
+				// cut off the EOF
+				r->ofcall.count = n;
+				memmove(r->ofcall.data, buf, n);
+			} else {
+				b->unread = 0;
+				rsleep(&b->rz);
+				goto Again;
+			}
+		} else
+			flushtag = -1;
 		qunlock(b);
 		memset(buf, 0, sizeof(buf));
 		srvacquire(fs);
@@ -254,6 +262,7 @@
 			respond(r, nil);
 			return;	
 		}
+		break;
 	case Qstatus:
 		if(f->cl->current && f->cl->current->status){
 			memset(buf, 0, sizeof(buf));
@@ -260,6 +269,7 @@
 			snprint(buf, sizeof(buf), "%s", f->cl->current->status);
 			goto String;
 		}
+		break;
 	case Qaside:
 		if(f->cl->current && f->cl->current->aside){
 			memset(buf, 0, sizeof(buf));
@@ -266,17 +276,24 @@
 			snprint(buf, sizeof(buf), "%s", f->cl->current->aside);
 			goto String;
 		}
+		break;
 	case Qnotify:
 		if(f->cl->current && f->cl->current->notify){
 			memset(buf, 0, sizeof(buf));
-			for(np = f->cl->current->notify; np->next; np = np->next)
-				// TODO: Move to fmt specifier for these
-				snprint(buf, sizeof(buf), "%s\n", np->data);
+			for(np = f->cl->current->notify; np; np = np->next)
+				n = snprint(buf + n, sizeof(buf), "%!\n", np);
 			goto String;
 		}
-	//case Qtabs:
-	// Iterate through base and show up all 'o them
-		
+		break;
+	case Qtabs:
+		if(f->cl->current){
+			memset(buf, 0, sizeof(buf));
+			for(b = root->next; b; b = b->next){
+				n = snprint(buf + n, sizeof(buf), "%t\n", b);
+			}
+			goto String;
+		}
+		break;
 	}
 	if(!f->cl->current)
 		respond(r, "no buffer selected");
@@ -303,6 +320,9 @@
 			if(f->cl->fd)
 				close(f->cl->fd);
 			f->cl->current = bufferSearch(root, s);
+			if(!f->cl->current)
+				respond(r, "No buffer for selected");
+			f->cl->current->tag = r->tag;
 			memset(path, sizeof(path), 0);
 			snprint(path, sizeof(path), "%s/%s/%s", logdir, root->name, s);
 			f->cl->fd = open(path, OREAD);
@@ -343,6 +363,13 @@
 void
 clflush(Req *r)
 {
+	Buffer *b;
+	flushtag = r->tag;
+	if(b = bufferSearchTag(root, flushtag)){
+		qlock(b);
+		rwakeup(&b->rz);
+		qunlock(b);
+	}
 	respond(r, nil);
 }
 
@@ -365,6 +392,7 @@
 	root = emalloc(sizeof(*root));
 	USED(root);
 	root = (Buffer*)s->aux;
+	flushtag = -1;
 	fs = s;
 	time0 = time(0);
 }
--- a/fs.c
+++ b/fs.c
@@ -50,8 +50,8 @@
 void
 threadmain(int argc, char *argv[])
 {
-	// We could use quotefmtinstall here
-	// add in tabs at very least
+	fmtinstall('t', Tconv);
+	fmtinstall('!', Nconv);
 	user = getuser();
 	mtpt = "/mnt/alt";
 	logdir = "/tmp/alt";
--- a/mkfile
+++ b/mkfile
@@ -13,6 +13,7 @@
 	client.$O\
 	service.$O\
 	notification.$O\
+	tabs.$O\
 
 </sys/src/cmd/mkmany
 
--- a/notification.c
+++ b/notification.c
@@ -1,0 +1,16 @@
+#include <u.h>
+#include <libc.h>
+#include <fcall.h>
+#include <thread.h>
+#include <9p.h>
+
+#include "alt.h"
+
+int
+Nconv(Fmt *fp)
+{
+	Notify *n;
+
+	n = va_arg(fp->args, Notify*);
+	return fmtstrcpy(fp, n->data);
+}
--- a/service.c
+++ b/service.c
@@ -327,9 +327,8 @@
 			data[strlen(data)] = '\n';
 			pwrite(b->fd, data, strlen(data), d->length);
 			free(d);
-			if(rwakeupall(&b->rz)){
-				print("Unlocking all threads\n");
-			}
+			if(rwakeupall(&b->rz) == 0)
+				b->unread++;
 			qunlock(b);
 			return nil;
 		}
--