X-Git-Url: http://git.roojs.org/?p=gitlive;a=blobdiff_plain;f=Spawn.vala;h=738ea44d6721d406cb253e35dc852d1d74a3d3ac;hp=2c13854b8b30f63a9364a772f2dbfeccb7d6f65f;hb=0b86050bdbbbd2985f7078ca9036be0196455398;hpb=a6c480470962be00961f233c5964678707cedefb diff --git a/Spawn.vala b/Spawn.vala index 2c13854b..738ea44d 100644 --- a/Spawn.vala +++ b/Spawn.vala @@ -60,7 +60,7 @@ static int main (string[] args) { public delegate void SpawnOutput(string line); public delegate void SpawnErr(string line); public delegate string SpawnInput(); -public delegate void SpawnFinish(int result); +public delegate void SpawnFinish(int result, string output); public class SpawnConfig { @@ -74,7 +74,7 @@ public class SpawnConfig { public SpawnOutput output; public SpawnErr stderr; public SpawnInput input; - public SpawnFinish finish; + // defaults.. public SpawnConfig(string cwd, string[] args, @@ -93,18 +93,19 @@ public class SpawnConfig { input = null; } - + + public void setHandlers( SpawnOutput? output, SpawnErr? stderr, - SpawnInput? input, - SpawnFinish? finish + SpawnInput? input + ) { this.output = output; this.stderr = stderr; this.input = input; - this.finish = finish; + } @@ -152,7 +153,9 @@ public class Spawn : Object if (this.cfg.args.length < 0) { throw new SpawnError.NO_ARGS("No arguments"); } - this.run(); + if (!this.cfg.async) { + this.run((res, output) => { }); + } } @@ -197,6 +200,9 @@ public class Spawn : Object */ int out_src = -1; + + unowned SpawnFinish on_finished; + /** * * @method run @@ -204,10 +210,10 @@ public class Spawn : Object * result is applied to object properties (eg. '?' or 'stderr') * @returns {Object} self. */ - public void run() throws SpawnError, GLib.SpawnError, GLib.IOChannelError + public void run( SpawnFinish finished_cb) throws SpawnError, GLib.SpawnError, GLib.IOChannelError { - + this.on_finished = finished_cb; err_src = -1; out_src = -1; int standard_input; @@ -217,7 +223,7 @@ public class Spawn : Object if (this.cfg.debug) { - stdout.printf("cd %s; %s" , this.cfg.cwd , string.joinv(" ", this.cfg.args)); + stdout.printf("cd %s; %s\n" , this.cfg.cwd , string.joinv(" ", this.cfg.args)); } Process.spawn_async_with_pipes ( @@ -238,7 +244,7 @@ public class Spawn : Object if (this.cfg.debug) { - stdout.printf("PID: %d" ,this.pid); + stdout.printf("PID: %d\n" ,this.pid); } this.ref(); // additional ref - cleared on tidyup... @@ -260,29 +266,7 @@ public class Spawn : Object - ChildWatch.add (this.pid, (w_pid, result) => { - - this.result = result; - if (this.cfg.debug) { - stdout.printf("child_watch_add : result:%d ", result); - } - - this.read(this.out_ch); - this.read(this.err_ch); - - - Process.close_pid(this.pid); - this.pid = -1; - if (this.ctx != null) { - this.ctx.quit(); - this.ctx = null; - } - this.tidyup(); - //print("DONE TIDYUP"); - if (this.cfg.finish != null) { - this.cfg.finish(this.result); - } - }); + ChildWatch.add (this.pid, this.on_child_watch); @@ -294,13 +278,15 @@ public class Spawn : Object this.out_src = (int) this.out_ch.add_watch ( IOCondition.OUT | IOCondition.IN | IOCondition.PRI | IOCondition.HUP | IOCondition.ERR , (channel, condition) => { - return this.out_ch != null ? this.read(this.out_ch) : true; + return this.read(channel); + //return this.out_ch != null ? this.read(this.out_ch) : true; } ); this.err_src = (int) this.err_ch.add_watch ( IOCondition.OUT | IOCondition.IN | IOCondition.PRI | IOCondition.HUP | IOCondition.ERR , (channel, condition) => { - return this.err_ch != null ? this.read(this.err_ch) : true; + return this.read(channel); + //return this.err_ch != null ? this.read(this.err_ch) : true; } ); @@ -316,7 +302,7 @@ public class Spawn : Object //but... let's close input now.. this.in_ch.shutdown(true); this.in_ch = null; - + } catch (Error e) { this.tidyup(); @@ -330,42 +316,74 @@ public class Spawn : Object } // async - if running - return.. if (this.cfg.async && this.pid > -1) { + //this.ref(); return; } // start mainloop if not async.. if (this.pid > -1) { - print("starting main loop"); + //print("starting main loop"); //if (this.cfg.debug) { // // } - this.ctx = new MainLoop (); + this.ctx = new MainLoop (); this.ctx.run(); // wait fore exit? - print("main_loop done!"); + //print("main_loop done!"); } else { this.tidyup(); // tidyup get's called in main loop. } + if (this.cfg.exceptions && this.result != 0) { - - throw new SpawnError.EXECUTE_ERROR(this.stderr); + var errstr = string.joinv(" ", this.cfg.args) + "\n"; + errstr += this.output; + errstr += this.output.length > 0 ? "\n" : ""; + errstr += this.stderr; + //print("Throwing execute error:%s\n", errstr); + throw new SpawnError.EXECUTE_ERROR(errstr); //this.toString = function() { return this.stderr; }; ///throw new Exception this; // we throw self... } - // finally throw, or return self.. - return; } + void on_child_watch(GLib.Pid w_pid, int result) { + + this.result = result; + if (this.cfg.debug) { + stdout.printf("child_watch_add : result:%d\n", result); + } + + this.read(this.out_ch); + this.read(this.err_ch); + + + Process.close_pid(this.pid); + this.pid = -1; + if (this.ctx != null) { + this.ctx.quit(); + this.ctx = null; + + } + //print("child process done - running callback, then tidyup"); + this.on_finished(this.result, this.output + (this.output.length > 0 ? "\n" : "") + this.stderr); + // this.unref(); + this.tidyup(); + + //print("DONE TIDYUP"); + + + } + private void tidyup() { - + //print("Tidyup\n"); if (this.pid > -1) { Process.close_pid(this.pid); // hopefully kills it.. this.pid = -1; @@ -375,7 +393,7 @@ public class Spawn : Object if (this.out_ch != null) this.out_ch.shutdown(true); if (this.err_ch != null) this.err_ch.shutdown(true); } catch (Error e) { - // error shutting donw. + // error shutting down } // blank out channels this.in_ch = null; @@ -386,7 +404,7 @@ public class Spawn : Object //if (this.out_src > -1 ) GLib.source_remove(this.out_src); this.err_src = -1; this.out_src = -1; - this.unref(); + //this.unref(); } @@ -426,7 +444,7 @@ public class Spawn : Object { string prop = (ch == this.out_ch) ? "output" : "stderr"; // print("prop: " + prop); - + //print ("spawn.read: %s\n", prop); //print(JSON.stringify(ch, null,4)); while (true) { @@ -441,19 +459,22 @@ public class Spawn : Object try { var cond = ch.get_buffer_condition(); - if ((cond & GLib.IOCondition.ERR) > 0) { - return false; - } - if ((cond & GLib.IOCondition.IN) < 1) { - return false; - } + //if ((cond & GLib.IOCondition.ERR) > 0) { + // return false; + //} + //if ((cond & GLib.IOCondition.IN) < 1) { + // return false; + //} status = ch.read_line( out buffer, out len, out term_pos ); } catch (Error e) { //FIXme return false; } - + if (buffer == null) { + return false; + } + //print("got buffer of %s\n", buffer); // print('status: ' +JSON.stringify(status)); // print(JSON.stringify(x)); switch(status) { @@ -474,14 +495,13 @@ public class Spawn : Object } //_this[prop] += x.str_return; //if (this.cfg.debug) { - stdout.printf("%s : %s", prop , buffer); + // stdout.printf("%s : %s", prop , buffer); //} if (this.cfg.async) { if ( Gtk.events_pending()) { Gtk.main_iteration(); } - } //this.ctx.iteration(true);