title: Weird stdout/stderr indefinite loop with vala async exec / pipe example
body: <p>I tried out the example about exec and spawning, when running this with vala or compiling with valac, I get an endless loop of the output below. Is that normal? Incidentally, this is on OS X, normally I am on Linux and I can test it later on Linux.
  Vala version 0.40.9 installed with brew, using glib version 2.58.0 also installed with brew.</p>
  
  <pre><code>out: (null)stderr: (null)stdout: (null)stderr: (null)stdout: (null)stderr: (null)stdout: (null)stderr: (null)stdout: (null)stderr: (null)stdout: (null)stderr: (null)stdout: (null)stderr: (null)stdout: (null)stderr: (null)stdout: (null)stderr: (null)stdout: (null)stderr: (null)stdout: (null)stderr: (null)stdout: (null)stderr: (null)stdout: (null)stderr: (null)stdout: (null)stderr: (null)stdout: (null)stderr: (null)stdout: (null)stderr: (null)stdout: (null)stderr: (null)stdout: (null)stderr: (null)stdout: (null)stderr: (null)stdout: (null)stderr: (null)stdout: (null)stderr: (null)stdout: (null)stderr: (null)stdout: (null)stderr: (null)stdout: (null)stderr: (null)stdout: (null)stderr: (null)stdout: (null)stderr: (null)stdout: (null)stderr: (null)stdout: (null)stderr: (null)stdout: (null)stderr: (null)stdout: (null)stderr: (null)stdout: (null)stderr: (null)stdout: (null)stderr: (null)stdout: (null)stderr: (null)stdout: (null)stderr: (null)stdout: (null)stde
  </code></pre>
  
  <p>Edit: When running the same example on Ubuntu Xenial it worked as expected, but it is also using vala 0.30.1 by default. Is that just a way too old version? But at least now I saw what the example should look like.</p>
  
  <p>Edit2: The code used is 'Spawn with pipes, async' from <a href="https://valadoc.org/glib-2.0/GLib.Process.spawn_async_with_pipes.html" rel="nofollow noreferrer">https://valadoc.org/glib-2.0/GLib.Process.spawn_async_with_pipes.html</a> without any modifications, just copy pasted.</p>
  
  <pre><code>private static bool process_line (IOChannel channel, IOCondition condition, string stream_name) {
      if (condition == IOCondition.HUP) {
          print ("%s: The fd has been closed.\n", stream_name);
          return false;
      }
  
      try {
          string line;
          channel.read_line (out line, null, null);
          print ("%s: %s", stream_name, line);
      } catch (IOChannelError e) {
          print ("%s: IOChannelError: %s\n", stream_name, e.message);
          return false;
      } catch (ConvertError e) {
          print ("%s: ConvertError: %s\n", stream_name, e.message);
          return false;
      }
  
      return true;
  }
  
  public static int main (string[] args) {
      MainLoop loop = new MainLoop ();
      try {
          string[] spawn_args = {"ls", "-l", "-h"};
          string[] spawn_env = Environ.get ();
          Pid child_pid;
  
          int standard_input;
          int standard_output;
          int standard_error;
  
          Process.spawn_async_with_pipes ("/",
              spawn_args,
              spawn_env,
              SpawnFlags.SEARCH_PATH | SpawnFlags.DO_NOT_REAP_CHILD,
              null,
              out child_pid,
              out standard_input,
              out standard_output,
              out standard_error);
  
          // stdout:
          IOChannel output = new IOChannel.unix_new (standard_output);
          output.add_watch (IOCondition.IN | IOCondition.HUP, (channel, condition) =&gt; {
              return process_line (channel, condition, "stdout");
          });
  
          // stderr:
          IOChannel error = new IOChannel.unix_new (standard_error);
          error.add_watch (IOCondition.IN | IOCondition.HUP, (channel, condition) =&gt; {
              return process_line (channel, condition, "stderr");
          });
  
          ChildWatch.add (child_pid, (pid, status) =&gt; {
              // Triggered when the child indicated by child_pid exits
              Process.close_pid (pid);
              loop.quit ();
          });
  
          loop.run ();
      } catch (SpawnError e) {
          print ("Error: %s\n", e.message);
      }
      return 0;
  }
  </code></pre>
  
  <p>The bug report is here: <a href="https://gitlab.gnome.org/GNOME/glib/issues/1512" rel="nofollow noreferrer">https://gitlab.gnome.org/GNOME/glib/issues/1512</a></p>