xref: /plan9/acme/bin/source/win/pipe.c (revision afb30c3eb94b92629560c385d0152410d412fdfb)
17dd7cddfSDavid du Colombier #include <u.h>
27dd7cddfSDavid du Colombier #include <libc.h>
39a747e4fSDavid du Colombier #include <fcall.h>
47dd7cddfSDavid du Colombier #include <thread.h>
59a747e4fSDavid du Colombier #include <9p.h>
67dd7cddfSDavid du Colombier #include "dat.h"
77dd7cddfSDavid du Colombier 
87dd7cddfSDavid du Colombier typedef struct Wpid Wpid;
97dd7cddfSDavid du Colombier struct Wpid
107dd7cddfSDavid du Colombier {
117dd7cddfSDavid du Colombier 	int		pid;
127dd7cddfSDavid du Colombier 	Window	*w;
137dd7cddfSDavid du Colombier 	Wpid		*next;
147dd7cddfSDavid du Colombier };
157dd7cddfSDavid du Colombier 
167dd7cddfSDavid du Colombier void	pipectl(void*);
177dd7cddfSDavid du Colombier 
187dd7cddfSDavid du Colombier int	pipefd;
197dd7cddfSDavid du Colombier Wpid	*wpid;
207dd7cddfSDavid du Colombier int	snarffd;
219a747e4fSDavid du Colombier Channel *newpipechan;
227dd7cddfSDavid du Colombier 
239a747e4fSDavid du Colombier int
newpipewin(int pid,char * p)247dd7cddfSDavid du Colombier newpipewin(int pid, char *p)
257dd7cddfSDavid du Colombier {
269a747e4fSDavid du Colombier 	int id;
277dd7cddfSDavid du Colombier 	Window *w;
287dd7cddfSDavid du Colombier 	Wpid *wp;
297dd7cddfSDavid du Colombier 
307dd7cddfSDavid du Colombier 	w = newwindow();
317dd7cddfSDavid du Colombier 	winname(w, p);
327dd7cddfSDavid du Colombier 	wintagwrite(w, "Send ", 5);
337dd7cddfSDavid du Colombier 	wp = emalloc(sizeof(Wpid));
347dd7cddfSDavid du Colombier 	wp->pid = pid;
357dd7cddfSDavid du Colombier 	wp->w = w;
369a747e4fSDavid du Colombier 	wp->next = wpid;	/* BUG: this happens in fsread proc (we don't use wpid, so it's okay) */
377dd7cddfSDavid du Colombier 	wpid = wp;
389a747e4fSDavid du Colombier 	id = w->id;
399a747e4fSDavid du Colombier 	sendp(newpipechan, w);
409a747e4fSDavid du Colombier 	return id;
417dd7cddfSDavid du Colombier }
427dd7cddfSDavid du Colombier 
437dd7cddfSDavid du Colombier int
pipecommand(Window * w,char * s)447dd7cddfSDavid du Colombier pipecommand(Window *w, char *s)
457dd7cddfSDavid du Colombier {
467dd7cddfSDavid du Colombier 	ulong q0, q1;
477dd7cddfSDavid du Colombier 	char tmp[32], *t;
487dd7cddfSDavid du Colombier 	int n, k;
497dd7cddfSDavid du Colombier 
507dd7cddfSDavid du Colombier 	while(*s==' ' || *s=='\t' || *s=='\n')
517dd7cddfSDavid du Colombier 		s++;
527dd7cddfSDavid du Colombier 	if(strcmp(s, "Delete")==0){
537dd7cddfSDavid du Colombier 		windel(w, 1);
547dd7cddfSDavid du Colombier 		threadexits(nil);
557dd7cddfSDavid du Colombier 		return 1;
567dd7cddfSDavid du Colombier 	}
577dd7cddfSDavid du Colombier 	if(strcmp(s, "Del")==0){
587dd7cddfSDavid du Colombier 		if(windel(w, 0))
597dd7cddfSDavid du Colombier 			threadexits(nil);
607dd7cddfSDavid du Colombier 		return 1;
617dd7cddfSDavid du Colombier 	}
627dd7cddfSDavid du Colombier 	if(strcmp(s, "Send") == 0){
637dd7cddfSDavid du Colombier 		if(w->addr < 0)
647dd7cddfSDavid du Colombier 			w->addr = winopenfile(w, "addr");
657dd7cddfSDavid du Colombier 		ctlprint(w->ctl, "addr=dot\n");
667dd7cddfSDavid du Colombier 		seek(w->addr, 0UL, 0);
677dd7cddfSDavid du Colombier 		if(read(w->addr, tmp, 2*12) == 2*12){
687dd7cddfSDavid du Colombier 			q0 = atol(tmp+0*12);
697dd7cddfSDavid du Colombier 			q1 = atol(tmp+1*12);
707dd7cddfSDavid du Colombier 			if(q0 == q1){
717dd7cddfSDavid du Colombier 				t = nil;
727dd7cddfSDavid du Colombier 				k = 0;
737dd7cddfSDavid du Colombier 				if(snarffd > 0){
747dd7cddfSDavid du Colombier 					seek(0, snarffd, 0);
757dd7cddfSDavid du Colombier 					for(;;){
769a747e4fSDavid du Colombier 						t = realloc(t, k+8192+2);
777dd7cddfSDavid du Colombier 						if(t == nil)
78*afb30c3eSDavid du Colombier 							error("alloc failed: %r\n");
797dd7cddfSDavid du Colombier 						n = read(snarffd, t+k, 8192);
807dd7cddfSDavid du Colombier 						if(n <= 0)
817dd7cddfSDavid du Colombier 							break;
827dd7cddfSDavid du Colombier 						k += n;
837dd7cddfSDavid du Colombier 					}
847dd7cddfSDavid du Colombier 					t[k] = 0;
857dd7cddfSDavid du Colombier 				}
867dd7cddfSDavid du Colombier 			}else{
879a747e4fSDavid du Colombier 				t = emalloc((q1-q0)*UTFmax+2);
887dd7cddfSDavid du Colombier 				winread(w, q0, q1, t);
899a747e4fSDavid du Colombier 				k = strlen(t);
907dd7cddfSDavid du Colombier 			}
919a747e4fSDavid du Colombier 			if(t!=nil && t[0]!='\0'){
929a747e4fSDavid du Colombier 				if(t[k-1]!='\n' && t[k-1]!='\004'){
939a747e4fSDavid du Colombier 					t[k++] = '\n';
949a747e4fSDavid du Colombier 					t[k] = '\0';
959a747e4fSDavid du Colombier 				}
967dd7cddfSDavid du Colombier 				sendit(t);
979a747e4fSDavid du Colombier 			}
987dd7cddfSDavid du Colombier 			free(t);
997dd7cddfSDavid du Colombier 		}
1007dd7cddfSDavid du Colombier 		return 1;
1017dd7cddfSDavid du Colombier 	}
1027dd7cddfSDavid du Colombier 	return 0;
1037dd7cddfSDavid du Colombier }
1047dd7cddfSDavid du Colombier 
1057dd7cddfSDavid du Colombier void
pipectl(void * v)1067dd7cddfSDavid du Colombier pipectl(void *v)
1077dd7cddfSDavid du Colombier {
1087dd7cddfSDavid du Colombier 	Window *w;
1097dd7cddfSDavid du Colombier 	Event *e;
1107dd7cddfSDavid du Colombier 
1117dd7cddfSDavid du Colombier 	w = v;
1127dd7cddfSDavid du Colombier 	proccreate(wineventproc, w, STACK);
1137dd7cddfSDavid du Colombier 
1149a747e4fSDavid du Colombier 	windormant(w);
1157dd7cddfSDavid du Colombier 	winsetaddr(w, "0", 0);
1167dd7cddfSDavid du Colombier 	for(;;){
1177dd7cddfSDavid du Colombier 		e = recvp(w->cevent);
1187dd7cddfSDavid du Colombier 		switch(e->c1){
1197dd7cddfSDavid du Colombier 		default:
1207dd7cddfSDavid du Colombier 		Unknown:
1219a747e4fSDavid du Colombier 			fprint(2, "unknown message %c%c\n", e->c1, e->c2);
1227dd7cddfSDavid du Colombier 			break;
1237dd7cddfSDavid du Colombier 
1247dd7cddfSDavid du Colombier 		case 'E':	/* write to body; can't affect us */
1257dd7cddfSDavid du Colombier 			break;
1267dd7cddfSDavid du Colombier 
1277dd7cddfSDavid du Colombier 		case 'F':	/* generated by our actions; ignore */
1287dd7cddfSDavid du Colombier 			break;
1297dd7cddfSDavid du Colombier 
1307dd7cddfSDavid du Colombier 		case 'K':	/* ignore */
1317dd7cddfSDavid du Colombier 			break;
1327dd7cddfSDavid du Colombier 
1337dd7cddfSDavid du Colombier 		case 'M':
1347dd7cddfSDavid du Colombier 			switch(e->c2){
1357dd7cddfSDavid du Colombier 			case 'x':
1367dd7cddfSDavid du Colombier 			case 'X':
1377dd7cddfSDavid du Colombier 				execevent(w, e, pipecommand);
1387dd7cddfSDavid du Colombier 				break;
1397dd7cddfSDavid du Colombier 
1407dd7cddfSDavid du Colombier 			case 'l':	/* reflect all searches back to acme */
1417dd7cddfSDavid du Colombier 			case 'L':
1427dd7cddfSDavid du Colombier 				if(e->flag & 2)
1437dd7cddfSDavid du Colombier 					recvp(w->cevent);
1447dd7cddfSDavid du Colombier 				winwriteevent(w, e);
1457dd7cddfSDavid du Colombier 				break;
1467dd7cddfSDavid du Colombier 
1477dd7cddfSDavid du Colombier 			case 'I':	/* modify away; we don't care */
1487dd7cddfSDavid du Colombier 			case 'i':
1497dd7cddfSDavid du Colombier 			case 'D':
1507dd7cddfSDavid du Colombier 			case 'd':
1517dd7cddfSDavid du Colombier 				break;
1527dd7cddfSDavid du Colombier 
1537dd7cddfSDavid du Colombier 			default:
1547dd7cddfSDavid du Colombier 				goto Unknown;
1557dd7cddfSDavid du Colombier 			}
1567dd7cddfSDavid du Colombier 		}
1577dd7cddfSDavid du Colombier 	}
1587dd7cddfSDavid du Colombier }
1597dd7cddfSDavid du Colombier 
1607dd7cddfSDavid du Colombier void
newpipethread(void *)1619a747e4fSDavid du Colombier newpipethread(void*)
1627dd7cddfSDavid du Colombier {
1639a747e4fSDavid du Colombier 	Window *w;
1647dd7cddfSDavid du Colombier 
1659a747e4fSDavid du Colombier 	while(w = recvp(newpipechan))
1669a747e4fSDavid du Colombier 		threadcreate(pipectl, w, STACK);
1677dd7cddfSDavid du Colombier }
1687dd7cddfSDavid du Colombier 
1697dd7cddfSDavid du Colombier void
startpipe(void)1707dd7cddfSDavid du Colombier startpipe(void)
1717dd7cddfSDavid du Colombier {
1729a747e4fSDavid du Colombier 	newpipechan = chancreate(sizeof(Window*), 0);
1739a747e4fSDavid du Colombier 	threadcreate(newpipethread, nil, STACK);
1747dd7cddfSDavid du Colombier 	snarffd = open("/dev/snarf", OREAD|OCEXEC);
1757dd7cddfSDavid du Colombier }
176