ref: 3221d4892ddc8630678d021e7cbd5cf18de031b7
parent: 4626f9b20df8a86229a58a196eacd645e10ca690
author: B. Wilson <x@wilsonb.com>
date: Tue Jul 15 04:33:00 EDT 2025
Permit synchronous event handling
--- a/ridefs.c
+++ b/ridefs.c
@@ -387,50 +387,55 @@
void
handlemsgs(int in, Evfifo *ev, Qfile *out){
JSON *j, *v;
- char *s;
- int cmd;
- vlong off;
+ char *s, *e;
+ int cmd, t;
while(1){
- s = nil;
- readcmd(in, &cmd, &j);
+ if(readcmd(in, &cmd, &j) < 0)
+ continue;
+
+ s = e = nil;
switch(cmd){
case RAppendSessionOutput:
v = jsonbyname(j, "type");
- switch((int)v->n){
- case 11: /* echoed input */
- case 14: /* input line */
- goto end;
+ switch(t = v->n){
+ case 14: /* "normal" input line */
break;
+ default:
+ v = jsonbyname(j, "result");
+ s = v->s;
+ e = smprint("o %d %ld %lld", t, strlen(s), seek(out->fd, 0, 1));
+ break;
}
- v = jsonbyname(j, "result");
- s = v->s;
break;
case RSetPromptType:
v = jsonbyname(j, "type");
- switch((int)v->n){
- case 0: break; /* no prompt */
+ switch(t = v->n){
case 1: s = " "; break; /* normal prompt */
case 2: s = "⎕:\n "; break; /* ⎕ input */
- case 3: break; /* line editor */
- case 4: s = ""; break; /* ⍞ input */
- case 5: break; /* unforeseen */
+ case 0: /* no prompt */
+ case 3: /* line editor */
+ case 4: /* ⍞ input */
+ case 5: /* unforeseen */
+ default:
+ s = ""; break;
}
+ e = smprint("p %d %ld %lld", t, strlen(s), seek(out->fd, 0 ,1));
break;
+ default: continue;
}
- if(s == nil)
- continue;
+ if(s){
+ wlock(out);
+ fprint(out->fd, "%s", s);
+ wunlock(out);
+ }
- off = seek(out->fd, 0, 1);
- wlock(out);
- fprint(out->fd, s);
- wunlock(out);
+ if(e){
+ fprint(ev->in, "%s\n", e);
+ free(e);
+ }
- if(ev->open > 0)
- fprint(ev->in, "t%ld %lld\n", strlen(s), off);
-
- end:
jsonfree(j);
}
}
@@ -633,13 +638,13 @@
if(c->tdata.fd == 0){
if(err = rideinit(c->addr, &c->tdata.fd, &c->tctl.fd, &c->qinfo))
goto done;
+ pipe(&c->ev.in);
switch(c->ev.pid = rfork(RFPROC|RFNOWAIT|RFMEM)){
case 0:
s = smprint("/tmp/ride.%d.%d", ppid, f->client);
c->qtext.fd = create(s, ORDWR|ORCLOSE, DMREAD|DMAPPEND);
- pipe(&c->ev.in);
- handlemsgs(c->tdata.fd, &c->ev, &c->qtext);
free(s);
+ handlemsgs(c->tdata.fd, &c->ev, &c->qtext);
return;
case -1: err = "unable to fork message handler"; break;
default: break;
@@ -697,7 +702,14 @@
}
break;
case Qevent:
- r->ofcall.count = read(c->ev.out, r->ofcall.data, r->ifcall.count);
+ switch(f->pid = rfork(RFPROC|RFNOWAIT|RFMEM)){
+ case 0:
+ r->ofcall.count = read(c->ev.out, r->ofcall.data, r->ifcall.count);
+ respond(r, nil);
+ exits(nil);
+ case -1: err = "failed to fork read"; break;
+ default: return;
+ }
break;
default: err = "read prohibited"; break;
}
--- a/test
+++ b/test
@@ -61,21 +61,22 @@
echo >text ||
fail 'Could not connect to server'
- >text {
+ <event >text {
~ `{wc -c info} 0 &&
fail 'Did not receive RIDE info'
- # expect events: prompt > response > prompt
- # XXX: >/dev/null and >/fd/1 mysteriously effect different text
- <event for(n in 0 1 2) x=`{read} & evpid=$apid
- echo '⍳5' ||
+ echo '⍳5' ||
fail 'Could not send message'
- wait $evpid
- tx=' ⍳5
-0 1 2 3 4
- '
- ~ `''{cat text} $tx ||
+ cont=1
+ while(~ $cont 1){
+ ev=`{read}
+ if(~ $ev(1) o){
+ rx=`{dd -if text -ibs 1 -skip $ev(4) -count $ev(3) >[2]/dev/null}
+ cont=0
+ }
+ }
+ ~ $rx '0 1 2 3 4' ||
fail 'Did not receive expected response'
}
cd ..
--
⑨