Plan 9 from Bell Labs’s /usr/web/sources/contrib/nemo/sys/src/cmd/ox/plumb.c

Copyright © 2021 Plan 9 Foundation.
Distributed under the MIT License.
Download the Plan 9 distribution.


#include <u.h>
#include <libc.h>
#include <thread.h>
#include <omero.h>
#include <error.h>
#include <b.h>
#include <plumb.h>
#include <ctype.h>
#include "ox.h"

static int	plumbeditfd = -1;
static int	plumbexecfd = -1;
static Channel*	plumbeditc;
static Channel*	plumbexecc;


int
addr2ln(Edit* e, char* addr)
{
	char*	fn;
	char*	cmd;
	char	buf[60];
	char*	s;
	Xcmd*	x;

	if (!addr[0] || !e->gtext || !e->gtext->repl)
		return 0;
	fn = smprint("%s/data", e->gtext->repl->path);
	cmd = smprint("grep -n '%s'", addr);
	x = allocxcmd(nil, "/", cmd, nil);
	x->infd[0] = open(fn, OREAD);
	pipe(x->outfd);
	x->pidc = chancreate(sizeof(ulong), 0);
	procrfork(xcmdproc, x, 16*1024, RFFDG|RFNOTEG);
	x->pid = recvul(x->pidc);
	chanfree(x->pidc);
	free(cmd);
	free(fn);
	close(x->infd[0]);
	close(x->outfd[1]);
	memset(buf, 0, sizeof(buf));
	read(x->outfd[0], buf, sizeof(buf));
	close(x->outfd[0]);
	s = strchr(buf ,':');
	if (s)
		*s = 0;
	freexcmd(x);
	if (buf[0] && isdigit(buf[0]))
		return atoi(buf);
	else
		return 0;
}

static void
plumbfile(Plumbmsg* m)
{
	char*	a;
	Edit*	e;
	char*	k;
	char*	path;

	path = cleanpath(m->data, m->wdir);
	e = editfile(path, 0);
	free(path);
	if (e == nil)
		return;
	openpanelctl(e->gcol);
	panelctl(e->gcol, "show\nnomin\n");
	closepanelctl(e->gcol);
	a = plumblookup(m->attr, "addr");
	if (a){
		if (a[0] == '/')
			k = smprint(":%d", addr2ln(e, a+1));
		else if (a[0])
			k = smprint(":%s", a);
		else
			k = nil;
		if (k)
			look(e, k, nil);
		free(k);
	}
}

static void
plumbdata(Plumbmsg* m)
{
	char*	fn;
	Edit*	e;
	char*	t;

	fn = plumblookup(m->attr, "filename");
	if (fn == nil){
		fn = estrdup("Plumb");
	}
	fn = cleanpath(fn, m->wdir);
	t = smprint("[%s]", fn);
	e = musthavemsgs(t);
	free(fn);
	free(t);
	free(e->text);
	e->text = emalloc(m->ndata + 1);
	e->text[m->ndata] = 0;
	memmove(e->text, m->data, m->ndata);
	updatetext(e);
}

static void
plumbeditthread(void*)
{
	Plumbmsg* m;
	char*	a;
	for(;;){
		m = recvp(plumbeditc);
		if (strcmp(m->type, "text")){
			plumbfree(m);
			continue;
		}
		a = plumblookup(m->attr, "action");
		if (a == nil || !strcmp(a, "showfile"))
			plumbfile(m);
		else
			plumbdata(m);
		plumbfree(m);
	}
}


static void
plumbexecthread(void*)
{
	Plumbmsg* m;
	int	i;
	Edit*	e;
	char*	path;

	for(;;){
		m = recvp(plumbexecc);
		if (strcmp(m->type, "text")){
			plumbfree(m);
			continue;
		}
		if (!strncmp(m->data, "exec ", 5))
			if (strchr(":|<>", m->data[5])){
				path = readfstr("/dev/sel");
				e = nil;
				if (path){
					for (i = 0; i < nedits; i++)
						if (edits[i] && strstr(path, edits[i]->gcolname)){
							e = edits[i];
							break;
						}
					if (e)
						run(e, m->data+5, 1, path);
					else
						externrunevent(path, "exec", m->data+5);
					free(path);
				}
			} else {
				xcmd(nil, m->wdir, m->data+5, nil, nil, nil);
			}
		plumbfree(m);
	}
}

void
plumbinit(void)
{
	plumbeditc = createportproc("edit");
	if (plumbeditc == nil)
		fprint(2,"%s: can't create edit port: %r\n", argv0);
	else
		threadcreate(plumbeditthread, 0, 8*1024);
	plumbexecc = createportproc("exec");
	if (plumbexecc == nil)
		fprint(2,"%s: can't create exec port: %r\n", argv0);
	else
		threadcreate(plumbexecthread, 0, 8*1024);
}


Bell Labs OSI certified Powered by Plan 9

(Return to Plan 9 Home Page)

Copyright © 2021 Plan 9 Foundation. All Rights Reserved.
Comments to webmaster@9p.io.