ref: ab79325966de7ae86d5ed5f470930f103e252e6a
parent: d47a99e0e2c8268d0d15d2748643387ed1c967a2
author: Michael Misch <michaelmisch1985@gmail.com>
date: Sun Feb 8 03:13:33 EST 2026
Update so feed and the main ctl work about the same
--- a/TODO
+++ b/TODO
@@ -9,12 +9,6 @@
exec /bin/exportfs -r /mnt/oftc
```
-## Client
-
-- Add in command to toggle markup
-- Reads on feed do not close cleanly when buffers change
-- Make sure reads block so we can just cat /path/to/feed
-
## Notifications:
- Create and update, clear when read
--- a/client.c
+++ b/client.c
@@ -237,34 +237,35 @@
case Qfeed:
// Catch EOF
if(f->cl->fd < 0 || !f->cl->current){- r->ofcall.count = 0;
- r->ofcall.data[0] = 0;
- respond(r, nil);
+ respond(r, "no feed");
return;
}
srvrelease(fs);
b = f->cl->current;
Again:
- // Check if we have a tag here, abort early if so.
- if(b->tag != flushtag){- memset(buf, 0, sizeof(buf));
- n = pread(f->cl->fd, buf, sizeof(buf), r->ifcall.offset);
- if(n > 0){- // cut off the EOF
- buf[n] = 0;
- readstr(r, buf);
- } else {- qlock(&b->l);
- b->unread = 0;
- rsleep(&b->rz);
- qunlock(&b->l);
- goto Again;
- }
- } else
+ if(b->tag == flushtag){flushtag = -1;
- srvacquire(fs);
- respond(r, nil);
- return;
+ r->ofcall.count = 0;
+ srvacquire(fs);
+ respond(r, nil);
+ return;
+ }
+ n = pread(f->cl->fd, r->ofcall.data, r->ifcall.count, r->ifcall.offset);
+ if(n > 0){+ r->ofcall.count = n;
+ srvacquire(fs);
+ respond(r, nil);
+ return;
+ } else if(n < 0) {+ srvacquire(fs);
+ responderror(r);
+ return;
+ }
+ qlock(&b->l);
+ b->unread = 0;
+ rsleep(&b->rz);
+ qunlock(&b->l);
+ goto Again;
case Qtitle:
if(f->cl->current && f->cl->current->title){b = f->cl->current;
--- a/service.c
+++ b/service.c
@@ -11,6 +11,7 @@
enum {Qsroot,
Qclone,
+ Qlist,
Qservices,
Qctl,
Qmax,
@@ -19,6 +20,7 @@
static char *svctab[] = {"/",
"clone",
+ "list",
nil,
"ctl",
nil,
@@ -62,6 +64,7 @@
static Srv *fs;
Service service[64];
int nservice;
+Lock svclock;
static Service*
newservice(void)
@@ -69,6 +72,7 @@
Service *svc;
int i;
+ lock(&svclock);
for(i = 0; i < nservice; i++)
if(service[i].ref == 0)
break;
@@ -84,11 +88,29 @@
svc->cmds = chancreate(sizeof(Cmd*), 8);
svc->base = bufferCreate(svc->cmds, svc->input);
svc->isInitialized = 0;
-
+ unlock(&svclock);
return svc;
}
static void
+rmservice(Service *s)
+{+ int i, found = 0;
+
+ lock(&svclock);
+ for(i = 0; i < nservice; i++){+ if(service[i].name == s->name)
+ found++;
+ /* Shift back */
+ if(found && i < nservice)
+ service[i] = service[i+1];
+ }
+ if(found)
+ nservice--;
+ unlock(&svclock);
+}
+
+static void
freeservice(Service *s)
{if(s == nil)
@@ -141,7 +163,9 @@
break;
case Qctl:
case Qclone:
+ case Qlist:
d->mode = 0666;
+ /* Fallthrough */
default:
d->name = estrdup(svctab[level]);
}
@@ -188,6 +212,7 @@
if(strcmp(name, "..")==0){ switch(f->level){case Qsroot:
+ case Qlist:
break;
case Qservices:
f->level = Qsroot;
@@ -291,9 +316,9 @@
{Cmd *cmd;
-
char buf[CmdSize];
Svcfid *f;
+ int i, n;
f = r->fid->aux;
memset(buf, 0, CmdSize);
@@ -307,24 +332,33 @@
dirread9p(r, servicegen, nil);
respond(r, nil);
return;
+ case Qlist:
+ n = 0;
+ for(i = 0; i < nservice; i++)
+ n += snprint(buf+n, sizeof(buf) - n, "%s\n", service[i].name);
+ readstr(r, buf);
+ respond(r, nil);
+ return;
case Qctl:
- // NOTE: This stays here so we always get a good ID back on the client from the initial read
+ /* NOTE: This stays here so we always get a good ID back on the client from the initial read */
if(!f->svc->isInitialized) {snprint(buf, sizeof(buf), "%d\n", SERVICEID(f->svc));
readstr(r, buf);
respond(r, nil);
+ return;
} else {- // Wait for any data/command from the client
+ /* Wait for any data/command from the client */
srvrelease(fs);
- cmd = recvp(f->svc->cmds);
+ while((cmd = recvp(f->svc->cmds)) == nil)
+ ;
srvacquire(fs);
- if(cmd){- snprint(buf, sizeof(buf), "%C", cmd);
- readstr(r, buf);
+ if(cmd->type != FlushCmd){+ n = snprint(r->ofcall.data, r->ifcall.count, "%C", cmd);
+ r->ofcall.count = n;
}
respond(r, nil);
+ return;
}
- return;
}
respond(r, "not implemented");
@@ -359,7 +393,7 @@
close(create(path, OREAD, DMDIR | 0755));
clfs.aux = f->svc->base;
f->svc->childpid = threadpostsrv(&clfs, strdup(cmd.data));
- if(f->svc->childpid >= 0){+ if(f->svc->childpid > 0){s = emalloc(10+strlen(cmd.data));
strcpy(s, "/srv/");
strcat(s, cmd.data);
@@ -366,6 +400,7 @@
d = dirstat(s);
d->mode = 0666;
if(dirwstat(s, d) < 0){+ rmservice(f->svc);
respond(r, "unable to set mode");
goto Out;
}
@@ -373,8 +408,10 @@
f->svc->isInitialized++;
r->fid->aux = f;
respond(r, nil);
- } else
+ } else {+ rmservice(f->svc);
respond(r, "Unable to post to srv");
+ }
goto Out;
}
// Ignore, something weird going on.
--
⑨