summaryrefslogtreecommitdiff
path: root/appl/cmd/styxmon.b
diff options
context:
space:
mode:
authorCharles.Forsyth <devnull@localhost>2006-12-22 17:07:39 +0000
committerCharles.Forsyth <devnull@localhost>2006-12-22 17:07:39 +0000
commit37da2899f40661e3e9631e497da8dc59b971cbd0 (patch)
treecbc6d4680e347d906f5fa7fca73214418741df72 /appl/cmd/styxmon.b
parent54bc8ff236ac10b3eaa928fd6bcfc0cdb2ba46ae (diff)
20060303a
Diffstat (limited to 'appl/cmd/styxmon.b')
-rw-r--r--appl/cmd/styxmon.b110
1 files changed, 110 insertions, 0 deletions
diff --git a/appl/cmd/styxmon.b b/appl/cmd/styxmon.b
new file mode 100644
index 00000000..0e5cb412
--- /dev/null
+++ b/appl/cmd/styxmon.b
@@ -0,0 +1,110 @@
+implement Styxmon;
+
+include "sys.m";
+ sys: Sys;
+include "draw.m";
+include "styx.m";
+ styx: Styx;
+ Tmsg, Rmsg: import styx;
+include "sh.m";
+include "arg.m";
+
+Styxmon: module {
+ init: fn(nil: ref Draw->Context, argv: list of string);
+};
+
+badmod(p: string)
+{
+ sys->fprint(sys->fildes(2), "styxmon: cannot load %s: %r\n", p);
+ raise "fail:bad module";
+}
+
+showdata := 0;
+init(ctxt: ref Draw->Context, argv: list of string)
+{
+ sys = load Sys Sys->PATH;
+ styx = load Styx Styx->PATH;
+ if(styx == nil)
+ badmod(Styx->PATH);
+ styx->init();
+ arg := load Arg Arg->PATH;
+ if(arg == nil)
+ badmod(Arg->PATH);
+ arg->init(argv);
+ arg->setusage("usage: styxmon [-d] cmd [arg...]");
+ while((opt := arg->opt()) != 0){
+ case opt{
+ 'd' =>
+ showdata = 1;
+ * =>
+ arg->usage();
+ }
+ }
+ argv = arg->argv();
+ if(argv == nil)
+ arg->usage();
+ fd0 := sys->fildes(0);
+ fd1 := popen(ctxt, argv);
+ sync := chan of int;
+ spawn msgtx(fd0, fd1, sync, "tmsg");
+ <-sync;
+ spawn msgtx(fd1, fd0, sync, "rmsg");
+ <-sync;
+}
+
+msgtx(f0, f1: ref Sys->FD, sync: chan of int, what: string)
+{
+ sys->pctl(Sys->NEWFD|Sys->NEWNS, 2 :: f0.fd :: f1.fd :: nil);
+ sync <-= 1;
+ f0 = sys->fildes(f0.fd);
+ f1 = sys->fildes(f1.fd);
+ stderr := sys->fildes(2);
+ for (;;) {
+ (d, err) := styx->readmsg(f0, 0);
+ if(d == nil){
+ if(err != nil)
+ sys->fprint(stderr, "styxmon: error from %s: %s\n", what, err);
+ else
+ sys->fprint(stderr, "styxmon: eof from %s\n", what);
+ exit;
+ }
+ if(styx->istmsg(d)){
+ (n, m) := Tmsg.unpack(d);
+ if(n != len d){
+ sys->fprint(stderr, "styxmon: %s message error (%d/%d)\n", what, n, len d);
+ }else{
+ sys->fprint(stderr, "%s\n", m.text());
+ }
+ }else{
+ (n, m) := Rmsg.unpack(d);
+ if(n != len d){
+ sys->fprint(stderr, "styxmon: %s message error (%d/%d)\n", what, n, len d);
+ if(m != nil)
+ sys->fprint(stderr, "err: %s\n", m.text());
+ }else{
+ sys->fprint(stderr, "%s\n", m.text());
+ }
+ }
+ sys->write(f1, d, len d);
+ }
+}
+
+popen(ctxt: ref Draw->Context, argv: list of string): ref Sys->FD
+{
+ sync := chan of int;
+ fds := array[2] of ref Sys->FD;
+ sys->pipe(fds);
+ spawn runcmd(ctxt, argv, fds[0], sync);
+ <-sync;
+ return fds[1];
+}
+
+runcmd(ctxt: ref Draw->Context, argv: list of string, stdin: ref Sys->FD, sync: chan of int)
+{
+ sys->pctl(Sys->FORKFD, nil);
+ sys->dup(stdin.fd, 0);
+ stdin = nil;
+ sync <-= 0;
+ sh := load Sh Sh->PATH;
+ sh->run(ctxt, argv);
+}