Re: How does one pipe output from process to text buffer? <-- FIXED

2006-12-31 Thread tomas
-BEGIN PGP SIGNED MESSAGE-
Hash: SHA1

On Sun, Dec 31, 2006 at 10:45:59AM -0500, Tony Freeman wrote:
> On Sun, 2006-12-31 at 05:43 +, [EMAIL PROTECTED] wrote:

[NONBLOCK]

> Thank you again!  That was exactly the answer :-)  The application does
> not freeze at all now.
> 
> Excellent!

Great. And I learnt in the process: I'd expected spawn_async_with_pipes
to give us nonblocking file descs :-)

Regards -- and happy new year
- -- tomás
-BEGIN PGP SIGNATURE-
Version: GnuPG v1.4.1 (GNU/Linux)

iD8DBQFFl90DBcgs9XrR2kYRAg1wAJ9JuuN8Ax+PdTsC3vWaGZsbPPTN1gCbBtwH
GKeG++Bqxyw31FS81BYtgPo=
=JEFD
-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

Re: How does one pipe output from process to text buffer? <-- FIXED

2006-12-31 Thread Tony Freeman
On Sun, 2006-12-31 at 05:43 +, [EMAIL PROTECTED] wrote:
> -BEGIN PGP SIGNED MESSAGE-
> Hash: SHA1
> 
> On Sat, Dec 30, 2006 at 12:15:33AM -0500, Tony Freeman wrote:
> > Thanks everyone, I have this working now :-)  Special thanks to Tomas!
> 
> happy it helped :-)
> 
> Still strange that it blocks, though. Perhaps
> g_spawn_async_with_pipes(...) gives you channels in blocking mode (I'd
> doubt that, but I don't know for sure).
> 
> You might try this out e.g. with
> 
>   g_io_channel_set_flags(gioout,
>  G_IO_FLAG_NONBLOCK | g_io_channel_get_flags(gioout)),
>  &err); /* or NULL, if you live on the edge */
> 
> right after the gioout = g_io_channel_unix_new(...)
> 
> Regards
> - -- tomás

Thank you again!  That was exactly the answer :-)  The application does
not freeze at all now.

Excellent!


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,
NULL );
gioout = g_io_channel_unix_new(stdout);
g_io_channel_set_flags(gioout, G_IO_FLAG_NONBLOCK, NULL);
g_io_channel_get_flags(gioout);


-- Tony


___
gtk-app-devel-list mailing list
gtk-app-devel-list@gnome.org
http://mail.gnome.org/mailman/listinfo/gtk-app-devel-list

Re: How does one pipe output from process to text buffer? <-- FIXED

2006-12-30 Thread James Scott Jr
On Sun, 2006-12-31 at 05:43 +, [EMAIL PROTECTED] wrote:

> -BEGIN PGP SIGNED MESSAGE-
> Hash: SHA1
> 
> On Sat, Dec 30, 2006 at 12:15:33AM -0500, Tony Freeman wrote:
> > Thanks everyone, I have this working now :-)  Special thanks to Tomas!
> 
> happy it helped :-)
> 
> Still strange that it blocks, though. Perhaps
> g_spawn_async_with_pipes(...) gives you channels in blocking mode (I'd
> doubt that, but I don't know for sure).
> 
> You might try this out e.g. with
> 
>   g_io_channel_set_flags(gioout,
>  G_IO_FLAG_NONBLOCK | g_io_channel_get_flags(gioout)),
>  &err); /* or NULL, if you live on the edge */
> 
> right after the gioout = g_io_channel_unix_new(...)
> 

g_io_channel_...() could be buffering the input/output.  try adding a
g_io_channel_set_encoding(gioout, NULL, NULL); after the
g_io_channel_new() call.  Also, the following text may provide some
insight.

"The default encoding for GIOChannel is UTF-8. If your application is
reading output from a command using via pipe, you may need to set the
encoding to the encoding of the current locale (see g_get_charset())
with the g_io_channel_set_encoding() function.

If you want to read raw binary data without interpretation, then call
the g_io_channel_set_encoding() function with NULL for the encoding
argument."

James,


> Regards
> - -- tomás
> -BEGIN PGP SIGNATURE-
> Version: GnuPG v1.4.1 (GNU/Linux)
> 
> iD8DBQFFl04NBcgs9XrR2kYRAlG+AJ9LCauFArjjFzraf0GTLQ4Z+6oOUQCdFYt6
> US5gnFcIbPS44N0OoxYrvA4=
> =8p1T
> -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
___
gtk-app-devel-list mailing list
gtk-app-devel-list@gnome.org
http://mail.gnome.org/mailman/listinfo/gtk-app-devel-list

Re: How does one pipe output from process to text buffer? <-- FIXED

2006-12-30 Thread tomas
-BEGIN PGP SIGNED MESSAGE-
Hash: SHA1

On Sat, Dec 30, 2006 at 12:15:33AM -0500, Tony Freeman wrote:
> Thanks everyone, I have this working now :-)  Special thanks to Tomas!

happy it helped :-)

Still strange that it blocks, though. Perhaps
g_spawn_async_with_pipes(...) gives you channels in blocking mode (I'd
doubt that, but I don't know for sure).

You might try this out e.g. with

  g_io_channel_set_flags(gioout,
 G_IO_FLAG_NONBLOCK | g_io_channel_get_flags(gioout)),
 &err); /* or NULL, if you live on the edge */

right after the gioout = g_io_channel_unix_new(...)

Regards
- -- tomás
-BEGIN PGP SIGNATURE-
Version: GnuPG v1.4.1 (GNU/Linux)

iD8DBQFFl04NBcgs9XrR2kYRAlG+AJ9LCauFArjjFzraf0GTLQ4Z+6oOUQCdFYt6
US5gnFcIbPS44N0OoxYrvA4=
=8p1T
-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

Re: How does one pipe output from process to text buffer? <-- FIXED

2006-12-29 Thread Tony Freeman
Thanks everyone, I have this working now :-)  Special thanks to Tomas!

The program still freezes for a very brief moment, but then it comes
quickly back to life with wonderful data spilling onto the notebook
pages. 


Here's the target function:


void on_confirm_okbutton_clicked (GtkWidget *widget, gpointer data)
{
gchar *tmp_ssh_command;
gchar **ssh_command;
gint i = 0;
gint count = g_strv_length(serverlist);

/* remove any existing notebook pages */
remove_notebook_pages(GTK_NOTEBOOK(notebook1));

/* start a process for each server */
for (i=0; ihttp://mail.gnome.org/mailman/listinfo/gtk-app-devel-list


Re: How does one pipe output from process to text buffer?

2006-12-28 Thread tomas
-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-deve

Re: How does one pipe output from process to text buffer?

2006-12-28 Thread Tony Freeman
On Wed, 2006-12-27 at 06:17 +, [EMAIL PROTECTED] wrote: 
> On Tue, Dec 26, 2006 at 10:41:33PM -0500, Tony Freeman wrote:
> > Hello,
> > 
> > I need some example code or a tutorial for how to pipe output from a
> > process to a GtkTextBuffer.
> > 
> > The idea of this program is to spawn off 6 or more ssh commands and have
> > the output go to it's own textbuffer in it's assigned notebook page.
> > 
> > This is what I have so far.  Now I need the output from the process to
> > go to it's respective text buffer.
> > 
> > 
> > void on_confirm_okbutton_clicked (GtkWidget *widget, gpointer data)
> > {
> > /* 
> >  * Globals used:
> >  *  serverlist : string array of server names
> >  *  command: the options to send to mainscript program
> >  *  notebook1  : notebook widget
> >  */
> [...]
> > /* now fire off the process and redirect output
> >  * to our textbuffer */
> > GPid pid;
> > g_spawn_async_with_pipes( NULL,
> >   ssh_command, 
> >   NULL, 
> >   G_SPAWN_CHILD_INHERITS_STDIN,
> >   NULL,
> >   NULL,
> >   &pid,
> >   NULL, NULL, NULL,
> >   NULL );
> > }
> 
> This looks like the interesting part. First of all, I doubt
> G_SPAWN_CHILD_INHERITS_STDIN is what you are after. I guess you'll have
> to give each child its own file descriptors (possibly all three, to let
> the user see possible errors), like so:
> 
> | GPid pid;
> | gint stdin, stdout, stderr;
> | g_spawn_async_with_pipes( NULL,/* workdir */
> |   ssh_command, /* argv */
> |   NULL,/* envp */
> |   NULL,/* flags */
> |   NULL,/* child setup func */
> |   NULL,/* --- udata */
> |   &pid,
> |   &stdin, &stdout, &stderr,
> |   NULL );  /* error */
> 
> Now you'll have to catch whatever comes from stdout and stderr and
> append it to the text buffer of the text widget (possibly making sure
> that the in and err part don't get too messed up, and possibly making
> nifty things like painting the errors in red :-). Likewise, you'll have
> to (somehow) collect user input, sending it via stdin to the process
> (when it is ready to take input).
> 
> To this purpose, you may wrap the descriptors in GIOChannels and watch
> the channels with g_io_add_watch(), which is just a fancy way to use the
> select() system call. I'll sketch this with stdin (the others work
> analogously). In a full-fledged version you'll typically want to collect
> all this stuff in a struct which you may attach to the corresponding
> notebook widget, so you may easily find all those thingies in callbacks,
> etc -- like so:
> 
> |  typedef struct {
> |GIOChannel *stdin;
> |GIOChannel *stdout;
> |GIOChannel *stderr;
> |/* other useful things like the text widget go here */
> |  } ssh_slave;
> 
> Now comes the fun part. After the spawn_async() (and after checking for
> errors ;-) you do:
> 
> |  ssh_slave *slave = g_new(ssh_slave, 1);
> |  slave->stdin = g_io_channel_unix_new(stdin);
> |  GIOFunc watch_slave;
> |  g_io_channel_add_watch_full(ch_stdin, G_IO_IN, watch_slave, slave);
> 
> 
> Then you define your watch function (I'd use the same function for all
> three channels, but I'm a really, really lazy person ;-)
> 
> | gboolean watch_slave(GIOChannel *src, GIOCondition *cond, gpointer udata)
> | {
> |   ssh_slave *slave = (ssh_slave *) udata; /* hopefully ;-) */
> |   gchar buf[1024]; /* or another meaningful size */
> |   GIOstatus st;
> |   GIOError *err;
> | 
> |   /* this is for stdin, stderr: */
> |   st = g_io_channel_read_chars(src, buf, sizeof(buf), &got, &err);
> |   /* handle errors */
> |   ...
> |   /* append whatever you got to the text widget, which you can hopefully
> |  pull from slave */
> |   ...
> |   /* Do likewise for stdout. You might have a buffer of pending chars
> |  hidden in slave->xxx and add/remove the "write watch" depending
> |  on whether there is write pending (otherwise the program will hog
> |  CPU spinning here). */
> |   ...
> |   return TRUE; /* typically. Return FALSE if you want the watch removed */
> | }
> 
> That's at least how I go about this. Hope it gives you some ideas.
> 
> Regards
> - -- tomás

Thanks!

I'm getting really close now!  Thanks for your help.

Currently, I have the program doing what I want but for one thing ... it

Re: How does one pipe output from process to text buffer?

2006-12-27 Thread tomas
-BEGIN PGP SIGNED MESSAGE-
Hash: SHA1

On Wed, Dec 27, 2006 at 12:02:01PM +0200, Zeeshan Ali wrote:
> Hello Tomas!
> 
> >> Just a thought: Wouldn't it be a better idea to use a library

[...]

> 2. The API is a bit different in the upcoming release: 0.2.

Yes, it seemed to me too that the author was eliminating "side tracks".

> >In Tony's case, he might have to extract the fd from the SSH_SESSION
> >object [...]

>   I have already thought of implementing a GIOChannel based on the
> libssh's CHANNEL object [...]

Tough call :-)

It'd be a foreigner in both lands. That's why I'd go for extracting the
fd from the CHANNEL object and stuffing it into a GIOChannel. They can
co-exist peacefully (of course you will use the ssh_* functions to
operate the CHANNEL when GIO* signals any conditions. It's not really
that much code and I prefer to have that explicit in my app.

I've done it already with an asynchronous libpq interface. It's quite
feasible to keep things neat and clean.

Regarding your other post... for non-POSIX systems, I dunno (lucky me!).
How does Windows select()?

Regards
- -- tomás
-BEGIN PGP SIGNATURE-
Version: GnuPG v1.4.1 (GNU/Linux)

iD8DBQFFkmEMBcgs9XrR2kYRApK+AJ0WQ4XXs2WXV4IlLQNIkiEHXS5N2gCfVndI
0CGLQcxkzWl96oKO8noqeBM=
=/uY7
-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

Re: How does one pipe output from process to text buffer?

2006-12-27 Thread Zeeshan Ali
Hi again!

On 12/27/06, Zeeshan Ali <[EMAIL PROTECTED]> wrote:
> > In Tony's case, he might have to extract the fd from the SSH_SESSION
> > object (is there an interface for that?) to be able to stuff it into a
> > GIOChannel (not very difficult. I've done it with a database socket). On
> > the plus side, Tony would just have *one* socket to watch (read and
> > write side), and errors would (assumedly) come through call results or
> > whatever.

   And regarding the use of fds, keep in mind that they are unix
specific so libssh might not provide an interface to the fd being used
by the CHANNEL. Even if it does, it might not be a good idea to use
that if you intend to keep/make your application very portable (one of
the primary reasons to use glib).

-- 
Regards,

Zeeshan Ali
Design Engineer, SW
Open Source Software Operations
Nokia Multimedia
___
gtk-app-devel-list mailing list
gtk-app-devel-list@gnome.org
http://mail.gnome.org/mailman/listinfo/gtk-app-devel-list


Re: How does one pipe output from process to text buffer?

2006-12-27 Thread Zeeshan Ali
Hello Tomas!

> > Just a thought: Wouldn't it be a better idea to use a library
> > instead of a command when one is available: libssh
> > (http://www.0xbadc0de.be/libssh:libssh).
>
> Thanks. Didn't know about that. Just from a cursory glance at the doc:
>
>  * what I like
>clean, abstract interface

Yes! me too.

>  * what I don't
>namespace pollution (besides the prefix ssh_ they use options_
>channel_ and what not).

I agree but keep in mind that:

1. The developer is a very friendly guy and takes user feedback very
seriously so you can suggest this to him and he'll do whatever seems
appropriate to change things for good.

2. The API is a bit different in the upcoming release: 0.2.

> In Tony's case, he might have to extract the fd from the SSH_SESSION
> object (is there an interface for that?) to be able to stuff it into a
> GIOChannel (not very difficult. I've done it with a database socket). On
> the plus side, Tony would just have *one* socket to watch (read and
> write side), and errors would (assumedly) come through call results or
> whatever.

   I have already thought of implementing a GIOChannel based on the
libssh's CHANNEL object and i already discussed the possbility of
having that in the libssh itself with the developer but he wasn't
particularly interested in glib's mainloop integration so i have put
it in the TODO list of my project. It would be doing that now if there
were some documentation on how to implement your own GIOChannel but
the glib docs seems to even abstract the GIOChannel structure even so
i'll have to get into the sources.

-- 
Regards,

Zeeshan Ali
Design Engineer, SW
Open Source Software Operations
Nokia Multimedia
___
gtk-app-devel-list mailing list
gtk-app-devel-list@gnome.org
http://mail.gnome.org/mailman/listinfo/gtk-app-devel-list


Re: How does one pipe output from process to text buffer?

2006-12-27 Thread tomas
-BEGIN PGP SIGNED MESSAGE-
Hash: SHA1

On Wed, Dec 27, 2006 at 10:33:38AM +0200, Zeeshan Ali wrote:
> On 12/27/06, Tony Freeman <[EMAIL PROTECTED]> wrote:
> > Hello,
> 
>Hi!
> 
> > I need some example code or a tutorial for how to pipe output from a
> > process to a GtkTextBuffer.
> >
> > The idea of this program is to spawn off 6 or more ssh commands and have
> > the output go to it's own textbuffer in it's assigned notebook page.
> 
> Just a thought: Wouldn't it be a better idea to use a library
> instead of a command when one is available: libssh
> (http://www.0xbadc0de.be/libssh:libssh).

Thanks. Didn't know about that. Just from a cursory glance at the doc:

 * what I like
   clean, abstract interface

 * what I don't
   namespace pollution (besides the prefix ssh_ they use options_
   channel_ and what not).

In Tony's case, he might have to extract the fd from the SSH_SESSION
object (is there an interface for that?) to be able to stuff it into a
GIOChannel (not very difficult. I've done it with a database socket). On
the plus side, Tony would just have *one* socket to watch (read and
write side), and errors would (assumedly) come through call results or
whatever.

Regards
- -- tomás
-BEGIN PGP SIGNATURE-
Version: GnuPG v1.4.1 (GNU/Linux)

iD8DBQFFkj8cBcgs9XrR2kYRAlN0AJwKODpdT3BJZ9F2UExgZH2k+0tU5wCfZp/E
g0VzNvQRfiGJr8tt1Iu6jJ8=
=cyCm
-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

Re: How does one pipe output from process to text buffer?

2006-12-27 Thread Zeeshan Ali
On 12/27/06, Tony Freeman <[EMAIL PROTECTED]> wrote:
> Hello,

   Hi!

> I need some example code or a tutorial for how to pipe output from a
> process to a GtkTextBuffer.
>
> The idea of this program is to spawn off 6 or more ssh commands and have
> the output go to it's own textbuffer in it's assigned notebook page.

Just a thought: Wouldn't it be a better idea to use a library
instead of a command when one is available: libssh
(http://www.0xbadc0de.be/libssh:libssh).

-- 
Regards,

Zeeshan Ali
Design Engineer, SW
Open Source Software Operations
Nokia Multimedia
___
gtk-app-devel-list mailing list
gtk-app-devel-list@gnome.org
http://mail.gnome.org/mailman/listinfo/gtk-app-devel-list


Re: How does one pipe output from process to text buffer?

2006-12-26 Thread tomas
-BEGIN PGP SIGNED MESSAGE-
Hash: SHA1

On Tue, Dec 26, 2006 at 10:41:33PM -0500, Tony Freeman wrote:
> Hello,
> 
> I need some example code or a tutorial for how to pipe output from a
> process to a GtkTextBuffer.
> 
> The idea of this program is to spawn off 6 or more ssh commands and have
> the output go to it's own textbuffer in it's assigned notebook page.
> 
> This is what I have so far.  Now I need the output from the process to
> go to it's respective text buffer.
> 
> 
> void on_confirm_okbutton_clicked (GtkWidget *widget, gpointer data)
> {
>   /* 
>* Globals used:
>*  serverlist : string array of server names
>*  command: the options to send to mainscript program
>*  notebook1  : notebook widget
>*/
[...]
>   /* now fire off the process and redirect output
>* to our textbuffer */
>   GPid pid;
>   g_spawn_async_with_pipes( NULL,
> ssh_command, 
> NULL, 
> G_SPAWN_CHILD_INHERITS_STDIN,
> NULL,
> NULL,
> &pid,
> NULL, NULL, NULL,
> NULL );
>   }

This looks like the interesting part. First of all, I doubt
G_SPAWN_CHILD_INHERITS_STDIN is what you are after. I guess you'll have
to give each child its own file descriptors (possibly all three, to let
the user see possible errors), like so:

|   GPid pid;
|   gint stdin, stdout, stderr;
|   g_spawn_async_with_pipes( NULL,/* workdir */
| ssh_command, /* argv */
| NULL,/* envp */
| NULL,/* flags */
| NULL,/* child setup func */
| NULL,/* --- udata */
| &pid,
| &stdin, &stdout, &stderr,
| NULL );  /* error */

Now you'll have to catch whatever comes from stdout and stderr and
append it to the text buffer of the text widget (possibly making sure
that the in and err part don't get too messed up, and possibly making
nifty things like painting the errors in red :-). Likewise, you'll have
to (somehow) collect user input, sending it via stdin to the process
(when it is ready to take input).

To this purpose, you may wrap the descriptors in GIOChannels and watch
the channels with g_io_add_watch(), which is just a fancy way to use the
select() system call. I'll sketch this with stdin (the others work
analogously). In a full-fledged version you'll typically want to collect
all this stuff in a struct which you may attach to the corresponding
notebook widget, so you may easily find all those thingies in callbacks,
etc -- like so:

|  typedef struct {
|GIOChannel *stdin;
|GIOChannel *stdout;
|GIOChannel *stderr;
|/* other useful things like the text widget go here */
|  } ssh_slave;

Now comes the fun part. After the spawn_async() (and after checking for
errors ;-) you do:

|  ssh_slave *slave = g_new(ssh_slave, 1);
|  slave->stdin = g_io_channel_unix_new(stdin);
|  GIOFunc watch_slave;
|  g_io_channel_add_watch_full(ch_stdin, G_IO_IN, watch_slave, slave);


Then you define your watch function (I'd use the same function for all
three channels, but I'm a really, really lazy person ;-)

| gboolean watch_slave(GIOChannel *src, GIOCondition *cond, gpointer udata)
| {
|   ssh_slave *slave = (ssh_slave *) udata; /* hopefully ;-) */
|   gchar buf[1024]; /* or another meaningful size */
|   GIOstatus st;
|   GIOError *err;
| 
|   /* this is for stdin, stderr: */
|   st = g_io_channel_read_chars(src, buf, sizeof(buf), &got, &err);
|   /* handle errors */
|   ...
|   /* append whatever you got to the text widget, which you can hopefully
|  pull from slave */
|   ...
|   /* Do likewise for stdout. You might have a buffer of pending chars
|  hidden in slave->xxx and add/remove the "write watch" depending
|  on whether there is write pending (otherwise the program will hog
|  CPU spinning here). */
|   ...
|   return TRUE; /* typically. Return FALSE if you want the watch removed */
| }

That's at least how I go about this. Hope it gives you some ideas.

Regards
- -- tomás
-BEGIN PGP SIGNATURE-
Version: GnuPG v1.4.1 (GNU/Linux)

iD8DBQFFkhAHBcgs9XrR2kYRAhHNAJ49QPnWhdsb6pq/E+U2IZZM4HNeTQCeLnWv
tG4pXP/VVo+bJpjOp4DTQ0k=
=je6g
-END PGP SIGNATURE-

___
gtk-app-devel-list mailing list
gtk-app-devel-list@gnome.org
http://mail.gnome

How does one pipe output from process to text buffer?

2006-12-26 Thread Tony Freeman
Hello,

I need some example code or a tutorial for how to pipe output from a
process to a GtkTextBuffer.

The idea of this program is to spawn off 6 or more ssh commands and have
the output go to it's own textbuffer in it's assigned notebook page.

This is what I have so far.  Now I need the output from the process to
go to it's respective text buffer.


void on_confirm_okbutton_clicked (GtkWidget *widget, gpointer data)
{
/* 
 * Globals used:
 *  serverlist : string array of server names
 *  command: the options to send to mainscript program
 *  notebook1  : notebook widget
 */

gchar *tmp_ssh_command;
gchar **ssh_command;
gint i = 0;
gint count = g_strv_length(serverlist);

/* remove any existing notebook pages */
remove_notebook_pages(GTK_NOTEBOOK(notebook1));

/* start a process for each server */
for (i=0; ihttp://mail.gnome.org/mailman/listinfo/gtk-app-devel-list