null/demo.local.php
[gitlive] / Spawn.js
index 313703b..4d9f202 100644 (file)
--- a/Spawn.js
+++ b/Spawn.js
@@ -31,7 +31,7 @@ var GLib      = imports.gi.GLib;
 *
 *
 *  CRITICAL - needs this change to gir in GLib-2.0.gir g_spawn_async_with_pipes
-*
+*  Fixed in Ubuntu 12.10
     <parameter name="argv" transfer-ownership="none">
          <array c:type="gchar**">
             <type name="utf8"/>
@@ -43,8 +43,9 @@ var GLib      = imports.gi.GLib;
           </array>
         </parameter>
 *
-*
-*<method name="read_line"
+*  ALSO in GLib-2.0.gir
+
+<method name="read_line"
               c:identifier="g_io_channel_read_line"
               throws="1">
         <return-value transfer-ownership="none">
@@ -63,7 +64,7 @@ var GLib      = imports.gi.GLib;
         </parameters>
       </method>
 *
-*
+* run g-ir-compile -o /usr/lib/girepostitory-1.0/GLib-2.0.typelib GLib-2.0.gir
 *
 * 
 */
@@ -108,7 +109,7 @@ Spawn.prototype = {
     cwd: false,
     args: false,
     exceptions : false,
-    debug : true,
+    debug : false,
     /**
      * @property output {String} resulting output
      */
@@ -125,8 +126,6 @@ Spawn.prototype = {
      * @property pid {Number} pid of child process (of false if it's not running)
      */
     pid : false,
-    
-    
     /**
      * @property in_ch {GLib.IOChannel} input io channel
      */
@@ -139,15 +138,13 @@ Spawn.prototype = {
      * @property err_ch {GLib.IOChannel} stderr io channel
      */
     err_ch : false,
-    
     /**
      * 
      * @method run
      * Run the configured command.
-     * 
+     * result is applied to object properties (eg. 'output' or 'stderr')
+     * @returns {Object} self.
      */
-    
-    
     run : function()
     {
         
@@ -161,17 +158,28 @@ Spawn.prototype = {
             print("cd " + this.cwd +";" + this.args.join(" "));
         }
         
-        GLib.spawn_async_with_pipes(this.cwd, this.args, this.env, 
+        var gret = GLib.spawn_async_with_pipes(this.cwd, this.args, this.env, 
             GLib.SpawnFlags.DO_NOT_REAP_CHILD + GLib.SpawnFlags.SEARCH_PATH , 
             null, null, ret);
-            
-       print(JSON.stringify(ret));    
+        
+               var isSeed = true;
+               if (typeof(Seed) == 'undefined') {
+                       ret = {
+                               child_pid : gret[1],
+                               standard_input : gret[2],
+                           standard_output: gret[3], 
+                           standard_error: gret[4]
+                       };
+                       isSeed = false; 
+               }
+               
+       //print(JSON.stringify(gret));    
         this.pid = ret.child_pid;
         
         if (this.debug) {
             print("PID: " + this.pid);
         }
-        
+         
         
        
         GLib.child_watch_add(GLib.PRIORITY_DEFAULT, this.pid, function(pid, result) {
@@ -182,13 +190,14 @@ Spawn.prototype = {
             _this.read(_this.out_ch);
             _this.read(_this.err_ch);
             
+                       
             GLib.spawn_close_pid(_this.pid);
             _this.pid = false;
             if (_this.ctx) {
                 _this.ctx.quit();
             }
             tidyup();
-           print("DONE TIDYUP");
+           //print("DONE TIDYUP");
             if (_this.listeners.finish) {
                 _this.listeners.finish.call(this, _this.result);
             }
@@ -216,22 +225,20 @@ Spawn.prototype = {
         }
         
         
-        this.in_ch = GLib.io_channel_unix_new(ret.standard_input);
-        this.out_ch = GLib.io_channel_unix_new(ret.standard_output);
-        this.err_ch = GLib.io_channel_unix_new(ret.standard_error);
+        this.in_ch = new GLib.IOChannel.unix_new(ret.standard_input);
+        this.out_ch = new GLib.IOChannel.unix_new(ret.standard_output);
+        this.err_ch = new GLib.IOChannel.unix_new(ret.standard_error);
         
         // make everything non-blocking!
         
         
       
-        if ( this.async) {
-            // this seems to hang our  input.
-            this.in_ch.set_flags (GLib.IOFlags.SET_MASK);
-        
-            this.out_ch.set_flags (GLib.IOFlags.SET_MASK);
-            this.err_ch.set_flags (GLib.IOFlags.SET_MASK);
-        }
-       
+                       // using NONBLOCKING only works if io_add_watch
+          //returns true/false in right conditions
+          this.in_ch.set_flags (GLib.IOFlags.NONBLOCK);
+          this.out_ch.set_flags (GLib.IOFlags.NONBLOCK);
+          this.err_ch.set_flags (GLib.IOFlags.NONBLOCK);
+                       
 
       
         // add handlers for output and stderr.
@@ -255,10 +262,20 @@ Spawn.prototype = {
         
         // call input.. 
         if (this.pid !== false) {
-            // child can exit before we get this far..
+            // child can exit before 1we get this far..
             if (this.listeners.input) {
+                               print("Trying to call listeners");
                 try {
                     this.write(this.listeners.input.call(this));
+                    // this probably needs to be a bit smarter...
+                   //but... let's close input now..
+                   this.in_ch.close();
+                   _this.in_ch = false;
+                  
+                   
+                   
+                   
+                   
                 } catch (e) {
                     tidyup();
                     throw e;
@@ -271,8 +288,7 @@ Spawn.prototype = {
         if (this.async && this.pid) {
             return this;
         }
-        
-        
+         
         // start mainloop if not async..
         
         if (this.pid !== false) {
@@ -280,10 +296,10 @@ Spawn.prototype = {
                 print("starting main loop");
             }
            
-            this.ctx = new GLib.MainLoop.c_new (null, false);
+            this.ctx = isSeed ? new GLib.MainLoop.c_new (null, false) : GLib.MainLoop.new (null, false);;
             this.ctx.run(false); // wait fore exit?
             
-            print("main_loop done!");
+            //print("main_loop done!");
         } else {
             tidyup(); // tidyup get's called in main loop. 
         }
@@ -308,12 +324,19 @@ Spawn.prototype = {
         if (!this.in_ch) {
             return 0; // input is closed
         }
-        var ret = {};
-        var res = this.in_ch.write_chars(str, str.length);
+       //print("write: " + str);
+       // NEEDS GIR FIX! for return value.. let's ignore for the time being..
+       //var ret = {};
+        //var res = this.in_ch.write_chars(str, str.length, ret);
+       var res = this.in_ch.write_chars(str, str.length);
+       
+       //print("write_char retunred:" + JSON.stringify(res) +  ' ' +JSON.stringify(ret)  );
+       
         if (res != GLib.IOStatus.NORMAL) {
             throw "Write failed";
         }
-        return ret.bytes_written;
+        //return ret.value;
+        return str.length;
         
     },
     
@@ -329,17 +352,13 @@ Spawn.prototype = {
         var _this = this;
         
        
-       var start_status = ch.get_buffer_condition();
-       
-        print(JSON.stringify(start_status, null,4));
-       
         //print(JSON.stringify(ch, null,4));
         while (true) {
  
             var x =   {};
             var status = ch.read_line( x);
-            //print(JSON.stringify(status));
-           // print(JSON.stringify(x));
+            // print('status: '  +JSON.stringify(status));
+            // print(JSON.stringify(x));
              switch(status) {
                 case GLib.IOStatus.NORMAL:
                
@@ -363,10 +382,13 @@ Spawn.prototype = {
                     
                     //this.ctx.iteration(true);
                    continue;
-                case GLib.IOStatus.AGAIN:   
+                case GLib.IOStatus.AGAIN:
+                   //print("Should be called again.. waiting for more data..");
+                   return true;
                     break;
                 case GLib.IOStatus.ERROR:    
-                case GLib.IOStatus.EOF:   
+                case GLib.IOStatus.EOF:
+                   return false;
                    break;
                 
             }
@@ -374,7 +396,7 @@ Spawn.prototype = {
         }
        
         //print("RETURNING");
-         return true;
+         return false; // allow it to be called again..
     }
     
 };