shithub: ridefs

Download patch

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