ref: 05d9123a707dec0eaa0ab079b94e69cdb750c6db
dir: /appl/alphabet/grid/local.b/
implement Local,Gridmodule;
include "sys.m";
sys: Sys;
include "draw.m";
include "sh.m";
include "alphabet/reports.m";
reports: Reports;
report, quit, Report: import reports;
include "alphabet/endpoints.m";
endpoints: Endpoints;
Endpoint: import endpoints;
include "alphabet/grid.m";
grid: Grid;
Value: import grid;
Local: module {};
types(): string
{
return "fe-v";
}
init()
{
sys = load Sys Sys->PATH;
reports = checkload(load Reports Reports->PATH, Reports->PATH);
endpoints = checkload(load Endpoints Endpoints->PATH, Endpoints->PATH);
endpoints->init();
grid = checkload(load Grid Grid->PATH, Grid->PATH);
grid->init();
}
run(nil: chan of string, r: ref Reports->Report,
opts: list of (int, list of ref Grid->Value), args: list of ref Grid->Value): ref Grid->Value
{
spawn localproc((hd args).e().i, f := chan of ref Sys->FD, opts!=nil, r.start("local"));
return ref Value.Vf(f);
}
localproc(ec: chan of Endpoint, f: chan of ref Sys->FD, verbose: int, errorc: chan of string)
{
ep := <-ec;
if(ep.addr == nil){
# error should already have been printed (XXX is that the right way to do it?)
f <-= nil;
<-f;
quit(errorc);
}
if(verbose)
report(errorc, sys->sprint("endpoint %q at %q: %s", ep.id, ep.addr, ep.about));
(fd0, err) := endpoints->open(nil, ep);
if(fd0 == nil){
report(errorc, sys->sprint("error: local: cannot open endpoint (%q %q): %s", ep.addr, ep.id, err));
f <-= nil;
<-f;
quit(errorc);
}
f <-= fd0;
fd1 := <-f;
if(fd1 == nil)
quit(errorc);
buf := array[Sys->ATOMICIO] of byte;
{
while((n := sys->read(fd0, buf, len buf)) > 0){
#sys->print("local read %d bytes\n", n);
sys->write(fd1, buf, n);
}
#sys->print("local eof %d\n", n);
sys->write(fd1, array[0] of byte, 0);
if(n < 0)
report(errorc, sys->sprint("read error: %r"));
} exception e {
"write on closed pipe" =>
report(errorc, "write on closed pipe");
;
}
quit(errorc);
}
checkload[T](m: T, path: string): T
{
if(m != nil)
return m;
raise sys->sprint("fail:cannot load %s: %r", path);
}