try something like this (it is only a demonstration, not working code!)

key to solve problem you've encountered are

          io_stdout = null;
          io_stderr = null;

it unrefs io channel, and releases descriptors




        private IOChannel     io_stderr;
        private IOChannel     io_stdout;
        private uint          io_stderr_watch_id;
        private uint          io_stdout_watch_id;
        private Pid           child_pid;
        private uint          child_watch_id = 0;

        private void run() {
          int child_stdout;
          int child_stderr;

          Process.spawn_async_with_pipes(null, { command }, null,
SpawnFlags.SEARCH_PATH | SpawnFlags.DO_NOT_REAP_CHILD, null, out
child_pid, null, out child_stdout, out child_stderr);

          io_stdout = new IOChannel.unix_new(child_stdout);
          io_stderr = new IOChannel.unix_new(child_stderr);

          io_stdout_watch_id = io_stdout.add_watch(IOCondition.IN,
on_stdout_read);
          io_stderr_watch_id = io_stderr.add_watch(IOCondition.IN,
on_stderr_read);

          child_watch_id = ChildWatch.add(child_pid, on_child_exits);
        }

        private void on_child_exits(Pid pid, int status) {
          Process.close_pid(pid);

          GLib.Source.remove(io_stdout_watch_id);
          GLib.Source.remove(io_stderr_watch_id);

          try {
            io_stdout.shutdown(true);
          } catch(IOChannelError e) {
            warning(@"Error \"$(e.message)\" during shutting down
stdout pipe to the child process");
          }

          try {
            io_stderr.shutdown(true);
          } catch(IOChannelError e) {
            warning(@"Error \"$(e.message)\" during shutting down
stderr pipe to the child process");
          }

          io_stdout = null;
          io_stderr = null;

          cancel_child_watch();
        }


        private string? on_read(IOChannel source)   {
          string line;
          try {
            IOStatus ret = source.read_line(out line, null, null);

            switch(ret) {
              case IOStatus.ERROR:
                warning("Read error");
                kill();
                return null;

              case IOStatus.EOF:
                message("End of File");
                return null;

            }
          } catch(IOChannelError e) {
            warning(@"I/O error: $(e.message)");
            kill();
            return null;


          } catch(ConvertError e) {
            warning(@"Convert error: $(e.message)");
            return null;
          }

          return line;
        }


        private bool on_stderr_read(IOChannel source, IOCondition condition) {
          var line = on_read(source);
          if(line != null) {
            do_something(line);
          }

          return true;
        }

        private bool on_stdout_read(IOChannel source, IOCondition condition) {
          var line = on_read(source);
          if(line != null) {
            do_something(line);
          }

          return true;
        }


2012/9/24 tomw <[email protected]>:
> ok, here's a bit more meat. Hopefully this help to tackle the issue:
>
> currently I'm using Vala 0.17.6. Obviously some files are left open as
> the open file count is increasing (checking with lsof | wc -l ) until I
> get the span error:
>
> Error spawning Uptime process - Failed to create pipe for communicating
> with child process (Too many open files)
>
> thanks,
>
>
>
> /* pipetest.vala
> *  valac --pkg gio-2.0 --pkg posix pipetest.vala
> */
>
> using GLib;
>
>
> public class Pipetest.Main : Object {
>         public MainLoop main_loop;
>         public int counter = 0;
>
>
>         public  Main () {
>                 main_loop = new GLib.MainLoop (null, false);
>         }
>
>
>
>         public void run () {
>                 Timeout.add_seconds (1, get_uptime);
>                 }
>
>         public bool get_uptime () {
>                 string uptime = "";
>                 int [] pipefd = {0, 0};
>
>
>                 if (Posix.pipe(pipefd) < 0) {
>                         debug ("Error - unable to open pipe");
>                 }
>
>                 Posix.close(pipefd[1]); //closing the write end of pipe
>                 try {
>                         string[] runme = {"/usr/bin/uptime"};
>                         int input;
>                         int output;
>                         int error;
>                         Pid child_pid;
>                         bool res = Process.spawn_async_with_pipes (null,
>                                                                    runme,
>                                                                    null,
>                                                                    
> SpawnFlags.DO_NOT_REAP_CHILD,
>                                                                    null,
>                                                                    out 
> child_pid,
>                                                                    out input,
>                                                                    out 
> pipefd[0],
>                                                                    out error 
> );
>
>                         var filestream = FileStream.fdopen (pipefd[0], "r");
>                         uptime = filestream.read_line ();
>                         if (res) {
>                                 int child_status = 0;
>                                 int ret_waitpid = Posix.waitpid (child_pid, 
> out child_status, 0);
>                                 if (ret_waitpid < 0 ) {
>                                         debug ("Waitpid returned error code : 
> %d", ret_waitpid);
>                                 }
>
>                         Posix.close (pipefd[0]);
>                         Process.close_pid (child_pid);
>
>                         }
>                 } catch (SpawnError e) {
>                         debug ("Error spawning Uptime process - %s", 
> e.message);
>                 }
>
>                 debug ("%d : Uptime : %s", counter, uptime);
>                 counter++;
>
>                 return true;
>         }
>
>
>         static int main (string[] args) {
>                 var main = new Main ();
>                 main.run ();
>                 main.main_loop.run ();
>                 return 0;
>         }
>
> }
>
> --
> tomw <[email protected]>
>
> _______________________________________________
> vala-list mailing list
> [email protected]
> https://mail.gnome.org/mailman/listinfo/vala-list
_______________________________________________
vala-list mailing list
[email protected]
https://mail.gnome.org/mailman/listinfo/vala-list

Reply via email to