[SOLVED] Re: Cannot get pipes to work with glibmm
Hi, Sorry to flood the list with my broken pipes stories but I finally found a way to get this to work! hurray! Here is a solution. The following code just spawn a shell to which you can send commands. #include glibmm.h #include gtkmm/main.h #include vector #include string #include iostream Glib::RefPtrGlib::IOChannel ch_stdout; bool callback(Glib::IOCondition cond) { Glib::ustring buf; ch_stdout-read_line(buf); //ch_stdout-read_to_end(buf) would never //return for an unknown reason std::coutbuf; return true; } int main(int argc, char** argv) { Gtk::Main kit(argc,argv); int fd_stdout, fd_stdin; Glib::Pid pid; std::vectorstd::string arguments; arguments.push_back(sh); Glib::spawn_async_with_pipes(Glib::get_current_dir(),arguments, Glib::SPAWN_SEARCH_PATH | Glib::SPAWN_CHILD_INHERITS_STDIN, sigc::slotvoid(), pid,/*fd_stdin*/0,fd_stdout); ch_stdout=Glib::IOChannel::create_from_fd(fd_stdout); Glib::signal_io().connect(sigc::ptr_fun(callback), ch_stdout,Glib::IO_IN); kit.run(); return 0; } To summerize what I did to get it to work: - The output Glib::IOChannel must be flushed for the data to be actually written in the pipe (not shown in the example). I know this looks trivial but it took me a while to figure it out since it's never mentionned in the reference documentation. - for the watch function, connect the input Glib::IOChannel directly using: Glib::signal_io().connect(const sigc::slotbool,IOCondition, const IOChannel, IOCondition, int); rather than using the version taking the file descriptor instead of the IOChannel. - Read a line at a time in the callback function. If there is more to be read, the callback function will be called again anyway. I think this is quite weird that Glib::IOChannel::read_to_end can be in a condition where it never returns and would call it a bug! Note that this is not a c++ binding issue since trying to do the same in C did produce the same result. I hope this might be of use to someone! Cheers! Le dimanche 18 octobre 2009 à 19:32 +0200, Bastien Dalla Piazza a écrit : Hi again, I partially solved my problem: One needs to call Glib::IOChannel::flush() after writing on outgoing pipe for the message to be passed. For the ingoing pipe, it is necessary to add a watch function using for instance Glib::io_signal().connect(sigc::mem_fun(object,Object::callback),ingoing_fd, Glib::IO_IN); I'm running into an other problem: Using the abow call, the function bool Object::callback(Glib::IOCondition cond) will be called each time the Glib::IO_IN condition is set on the ingoing pipe, that is when there is something to read. But trying to read in the above callback function using Glib::IOChannel::read_to_end results in an infinite loop (at least it looks like it). The Glib::IOChannel::read_line still works so I tried the following workaround: Glib::ustring store,buf; while(ingoing-get_condition() Glib::IO_IN){ ingoing-readline(buf); store.append(buf); } The while loop seems to finish, but then my callback function keeps being called over and over again by the main loop (Gtk::Main::run()), as if the Glib::IO_IN condition was never unset although the above while loop did finish. Am I doing things in an unexpected way, or is it possible there is a bug in Glib::IOChannel ? Thanks! Le samedi 17 octobre 2009 à 17:37 +0200, Bastien Dalla Piazza a écrit : Hi, I don't know if this is the correct mailing list so redirect me if not. In a Gtkmm project, I'm using Glib::spawn_async_with_pipes to execute and control a child process (gnugo in the example). But I cannot get it to work! For example: In the following code, I just redirect the gnugo stdin and stdout to my program: #include glibmm.h #include vector #include string #include iostream int main(int argc, char** argv) { Glib::init(); int fd_stdin, fd_stdout; //file descriptors Glib::Pid pid; Glib::RefPtrGlib::IOChannel ch_stdin, ch_stdout; std::vectorstd::string arguments; arguments.push_back(gnugo); arguments.push_back(--mode); arguments.push_back(gtp); /spawn gnugo Glib::spawn_async_with_pipes(Glib::get_current_dir(), arguments,Glib::SPAWN_SEARCH_PATH, sigc::slotvoid(), pid,fd_stdin,fd_stdout); //create the IOChannel from the file descriptors ch_stdin=Glib::IOChannel::create_from_fd(fd_stdin); ch_stdout=Glib::IOChannel::create_from_fd(fd_stdout); Glib::ustring input,output; //a stupid loop to test whether
Re: Cannot get pipes to work with glibmm
Hi again, I partially solved my problem: One needs to call Glib::IOChannel::flush() after writing on outgoing pipe for the message to be passed. For the ingoing pipe, it is necessary to add a watch function using for instance Glib::io_signal().connect(sigc::mem_fun(object,Object::callback),ingoing_fd, Glib::IO_IN); I'm running into an other problem: Using the abow call, the function bool Object::callback(Glib::IOCondition cond) will be called each time the Glib::IO_IN condition is set on the ingoing pipe, that is when there is something to read. But trying to read in the above callback function using Glib::IOChannel::read_to_end results in an infinite loop (at least it looks like it). The Glib::IOChannel::read_line still works so I tried the following workaround: Glib::ustring store,buf; while(ingoing-get_condition() Glib::IO_IN){ ingoing-readline(buf); store.append(buf); } The while loop seems to finish, but then my callback function keeps being called over and over again by the main loop (Gtk::Main::run()), as if the Glib::IO_IN condition was never unset although the above while loop did finish. Am I doing things in an unexpected way, or is it possible there is a bug in Glib::IOChannel ? Thanks! Le samedi 17 octobre 2009 à 17:37 +0200, Bastien Dalla Piazza a écrit : Hi, I don't know if this is the correct mailing list so redirect me if not. In a Gtkmm project, I'm using Glib::spawn_async_with_pipes to execute and control a child process (gnugo in the example). But I cannot get it to work! For example: In the following code, I just redirect the gnugo stdin and stdout to my program: #include glibmm.h #include vector #include string #include iostream int main(int argc, char** argv) { Glib::init(); int fd_stdin, fd_stdout; //file descriptors Glib::Pid pid; Glib::RefPtrGlib::IOChannel ch_stdin, ch_stdout; std::vectorstd::string arguments; arguments.push_back(gnugo); arguments.push_back(--mode); arguments.push_back(gtp); /spawn gnugo Glib::spawn_async_with_pipes(Glib::get_current_dir(), arguments,Glib::SPAWN_SEARCH_PATH, sigc::slotvoid(), pid,fd_stdin,fd_stdout); //create the IOChannel from the file descriptors ch_stdin=Glib::IOChannel::create_from_fd(fd_stdin); ch_stdout=Glib::IOChannel::create_from_fd(fd_stdout); Glib::ustring input,output; //a stupid loop to test whether the pipes work while(true){ std::cininput; ch_stdin-write(input.append(\n)); ch_stdout-read_to_end(output); std::coutoutputstd::endl; } } Any idea what I am doing wrong? Thanks! ___ gtk-app-devel-list mailing list gtk-app-devel-list@gnome.org http://mail.gnome.org/mailman/listinfo/gtk-app-devel-list
Cannot get pipes to work with glibmm
Hi, I don't know if this is the correct mailing list so redirect me if not. In a Gtkmm project, I'm using Glib::spawn_async_with_pipes to execute and control a child process (gnugo in the example). But I cannot get it to work! For example: In the following code, I just redirect the gnugo stdin and stdout to my program: #include glibmm.h #include vector #include string #include iostream int main(int argc, char** argv) { Glib::init(); int fd_stdin, fd_stdout; //file descriptors Glib::Pid pid; Glib::RefPtrGlib::IOChannel ch_stdin, ch_stdout; std::vectorstd::string arguments; arguments.push_back(gnugo); arguments.push_back(--mode); arguments.push_back(gtp); /spawn gnugo Glib::spawn_async_with_pipes(Glib::get_current_dir(), arguments,Glib::SPAWN_SEARCH_PATH, sigc::slotvoid(), pid,fd_stdin,fd_stdout); //create the IOChannel from the file descriptors ch_stdin=Glib::IOChannel::create_from_fd(fd_stdin); ch_stdout=Glib::IOChannel::create_from_fd(fd_stdout); Glib::ustring input,output; //a stupid loop to test whether the pipes work while(true){ std::cininput; ch_stdin-write(input.append(\n)); ch_stdout-read_to_end(output); std::coutoutputstd::endl; } } Any idea what I am doing wrong? Thanks! ___ gtk-app-devel-list mailing list gtk-app-devel-list@gnome.org http://mail.gnome.org/mailman/listinfo/gtk-app-devel-list
Glib::ustring, error while reading an utf-8 encoded file
Hi everybody, I don't have experience about charset issues so I tried the following to experiment: (it's in C++ using glibmm and giomm but I guess the problem is not related to that, it's just I don't understand something.) * #include giomm.h #include iostream #include glibmm.h #include string int main(int argc, char** argv) { Glib::init(); Gio::init(); if(argc!=2) return 1; //open a file to read Glib::RefPtrGio::File file=Gio::File::create_for_path(argv[1]); Glib::RefPtrGio::DataInputStream fin=Gio::DataInputStream::create(file-read()); std::string line; //try to read. try{ int i=1; while(fin-read_line(line)){ std::couti: as-is: \line\std::endl; std::couti: through Glib::ustring: \Glib::ustring(line)\std::endl; ++i; } } catch(Glib::ConvertError error){ std::coutstd::endlGlib::ConvertError: error.what()std::endl; } return 0; } *** Feading this utf-8 encoded file to the above program: *** First line: plain text. deuxième ligne: des accents ici et là... *** results in: 1: as-is: First line: plain text. 1: through Glib::ustring: First line: plain text. 2: as-is: deuxième ligne: des accents ici et là... 2: through Glib::ustring: Glib::ConvertError: Invalid byte sequence in conversion input my locale is using utf-8 (fr_CH). The question is: How to import the file content in an Glib::ustring when already knowing its encoding (not necessarily utf-8 though)? I'm writing an application which will likely have to deal with asian characters so I need to find out! Thanks a lot! Bastien ___ gtk-app-devel-list mailing list gtk-app-devel-list@gnome.org http://mail.gnome.org/mailman/listinfo/gtk-app-devel-list