-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 On Thu, Dec 28, 2006 at 08:10:57PM -0500, Tony Freeman wrote:
[...] > Thanks! > > I'm getting really close now! Thanks for your help. Glad it was useful. I'm keeping Zeeshan cc'ed -- he proposed using libgtk. Many things apply whether you spawn a process or use a lib (but tend to be easier with the lib; among other things you have less fds to watch ;-) > Currently, I have the program doing what I want but for one thing ... it > freezes until all my ssh commands have returned. Once control is > returned, all the notebook pages have all the proper ssh output > associated with it :-) > > I'd like to be able to click on each notebook page as the ssh commands > are running, and be able to see real-time output being written. This somehow smells like your app is waiting (or even spinning) in a callback. You can easily distinguisch waiting and spining based on how much CPU your process hogs :-) > Anyway ... > > This is what I have so far: > > [...] > > GPid pid; > gint stdout; > GIOChannel *gioout; > g_spawn_async_with_pipes( NULL, > ssh_command, > NULL, > G_SPAWN_SEARCH_PATH, > NULL, > NULL, > &pid, > NULL, &stdout, NULL, Where does the subprocess get its input from? I don't think it'll be doing anything useful this way. Maybe (just for testing purposes, and if you want to get the subproces's putput part right first) you might want to substitute the ssh command by some process which just procuces output (e.g. a shell script with echoes constantly). > NULL ); > gioout = g_io_channel_unix_new(stdout); > g_io_channel_set_encoding(gioout, NULL, NULL); > g_io_add_watch(gioout, > (G_IO_IN|G_IO_PRI|G_IO_ERR|G_IO_NVAL), > (GIOFunc)watch_out, > textview); > > [...] > > Note ... if I replace G_SPAWN_SEARCH_PATH with NULL I get a compiler > error ... so I keep it at G_SPAWN_SEARCH_PATH. > > Also ... it took me all day and night to finally brew up the combination > of (G_IO_IN|G_IO_PRI|G_IO_ERR|G_IO_NVAL). IMHO GIO_IN should suffice -- but I haven't the docs here. > I was under the die-hard > impression that I wanted to watch for G_IO_OUT (after all I want ssh > output), but it turns out I was thinking completely opposite of what > really needs to be thought? Anyway, this combination finally started > putting output in the notebook text buffers. The shell's output is *your* input :-) (note that your proces's perspective is relevant here). > > Here is the watch_out callback function: > > gboolean watch_out (GIOChannel *channel, GIOCondition condition, > gpointer data) > { > GIOStatus status = G_IO_STATUS_NORMAL; > GtkTextView *textview; > GtkTextBuffer *buffer; > gchar buf[1024]; > gchar *buftext; > gsize bytes_read; > > /* set up pointers to our textbuffer */ > textview = GTK_TEXT_VIEW((GtkWidget *)data); > buffer = gtk_text_view_get_buffer(textview); > > /* send ssh output to our gui */ > status = g_io_channel_read_chars(channel, buf, sizeof(buf), > &bytes_read, NULL); > buftext = g_strdup_printf("%s", buf); /*creates null-term str*/ No need for that. And besides, you are leaking mem. gtk_buffer_set_text accepts a length param, if I remember correctly: > gtk_text_buffer_set_text(buffer, buftext, -1); | if (bytes_read > 0) gtk_text_buffer_set_text(buff, buf, bytes_read); > > /* decide if we should close the channel */ > switch (status) { > case G_IO_STATUS_NORMAL: > return TRUE; > default: > return FALSE; > } > } > > > I've spent some time experiementing with the buf. I've reduced it down > to 64 (buf[64]) ... when the application becomes un-frozen and I can > click around in the notebook pages, I see that only the last couple of > lines of ssh output has been written to the page. > > It seems the buf[] is filling up with data and then being discarded > without writing that data to my textbuffer - until the end - at which > point it writes the data to the textbuffer as it dies away. > > Sound reasonable? How do I fix this? The callback itself looks harmless to me. I'd expect the ssh subprocess doing funny things when it doesn't get input. Besides, an ssh wants a tty (or pty; it tries to set it in raw mode to ask for a password). No idea what it'll do when fed via pipes. This is, btw where Zeeshan's proposal to use libssh makes most sense (it makes sense for other reasons as well). The flag combination G_IO_IN|G_IO_PRI|G_IO_ERR|G_IO_NVAL looks a bit strange to me. I'd put my bet in spinning: your callback is being called too often and there is nothing to read. Maybe later more, when I have access to the doc regards - -- tomás -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.1 (GNU/Linux) iD8DBQFFlKprBcgs9XrR2kYRAtb8AJ0TI8P05C6aCuMrZBHCbRWAf57ggACfafMu kQ0kDofeXwtVKGOuF2I3/zs= =yUNp -----END PGP SIGNATURE----- _______________________________________________ gtk-app-devel-list mailing list gtk-app-devel-list@gnome.org http://mail.gnome.org/mailman/listinfo/gtk-app-devel-list