Skip to Content

gtk+ advanced problem

Problem in this program in this program i tried to use pipe to get the output resulted from (ls) command to text view using gtk+ and named piping to put the output in the file called (dum1) and read it from the file after making this file a fifo file using mkfifo command and read the outoput from it what i actually want to do is to make my text view like a console not write the result from ls directly to a file and then read the file what i make is forking a process the child reponsible of making the ls command and the parent read the pipe and output the result to the buffer which used by gtk to fill the text view

this method work very nice when tested it using console and printf

and i could read the pipe and print it to screen under my control

but when i entring the gui level first the button to disappeared and i got tons of error message and program crash

what is the problem

  1. include <gtk/gtk.h>
  2. include <stdio.h>
  3. include <unistd.h>
  4. include <stdlib.h>
  5. include &lt;signal.h&gt; void catch_child(int sig_num) { /* when we get here, we know there's a zombie child waiting */ int child_status; wait(&child_status); printf("child exited.\n"); } void destroy (GtkWidget * widget, gpointer data) { gtk_main_quit (); } void button_clicked (GtkWidget * widget, gpointer data) { GtkTextBuffer *buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (data)); FILE *fp; char *line = NULL; GtkTextIter *iter; size_t len = 0; ssize_t read; if (mkfifo ("dum1", 0777) < 0) g_printerr ("Error in creating pipe"); //signal(SIGCHLD, catch_child); int i = fork (); if (i==0) { system ("ls > dum1"); } else if (i> 0) { fp = fopen ("dum1", "r"); if (fp == NULL) exit (EXIT_FAILURE); while ((read = getline (&line, &len, fp)) != -1) { printf ("Retrieved line of length %zu :\n", read); gtk_text_buffer_get_end_iter(buffer,iter); gtk_text_buffer_insert(buffer,iter,line,-1); } if (line) free (line); fclose(fp); system("rm dum1"); } else { g_printerr("Error Forking process"); } } int main (int argc, char *argv[]) { gtk_init (&argc, &argv); GtkWidget *window; GtkWidget *text_view; GtkTextBuffer *buffer; GtkWidget *vbox; GtkWidget *button; /*intialization */ window = gtk_window_new (GTK_WINDOW_TOPLEVEL); gtk_window_maximize (GTK_WINDOW (window)); vbox = gtk_vbox_new (FALSE, 10); text_view = gtk_text_view_new (); buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (text_view)); button = gtk_button_new_with_label ("Test"); /*Interface Building */ gtk_container_add (GTK_CONTAINER (window), vbox); gtk_box_pack_end (GTK_BOX (vbox), button, FALSE, FALSE, 0); gtk_box_pack_end_defaults (GTK_BOX (vbox), text_view); /*signal connecting */ g_signal_connect (G_OBJECT (window), "destroy", G_CALLBACK (destroy), NULL); g_signal_connect (G_OBJECT (button), "clicked", G_CALLBACK (button_clicked), text_view); gtk_widget_show_all (window); gtk_main (); return 0; }
MSameer's picture

I assume that you want to dir

I assume that you want to direct the "ls" output to the textview. Is that correct ??

Please include your code between &lt;pre&gt; and &lt;/pre&gt; tags

MSameer's picture

Try this, Works fine here:

Try this, Works fine here:

  1. define _GNU_SOURCE /* for getline() */
  2. include &lt;gtk/gtk.h&gt;
  3. include &lt;stdio.h&gt;
  4. include &lt;stdlib.h&gt;
void destroy (GtkWidget * widget, gpointer data) { gtk_main_quit (); } void button_clicked (GtkWidget * widget, gpointer data) { GtkTextBuffer *buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (data)); FILE *fp; char *line = NULL; GtkTextIter iter; size_t len = 0; ssize_t x; fp = popen("ls", "r"); if (!fp) { perror("fopen"); return; } while ((x = getline (&line, &len, fp)) != -1) { gtk_text_buffer_get_end_iter(buffer,&iter); gtk_text_buffer_insert(buffer,&iter,line,-1); free(line); line = NULL; } pclose(fp); } int main (int argc, char *argv[]) { GtkWidget *window; GtkWidget *text_view; GtkWidget *vbox; GtkWidget *button; /*intialization */ gtk_init (&argc, &argv); window = gtk_window_new (GTK_WINDOW_TOPLEVEL); vbox = gtk_vbox_new (FALSE, 10); text_view = gtk_text_view_new (); button = gtk_button_new_with_label ("Test"); /*Interface Building */ gtk_container_add (GTK_CONTAINER (window), vbox); gtk_box_pack_end (GTK_BOX (vbox), button, FALSE, FALSE, 0); gtk_box_pack_end_defaults (GTK_BOX (vbox), text_view); /*signal connecting */ g_signal_connect (G_OBJECT (window), "destroy", G_CALLBACK (destroy), NULL); g_signal_connect (G_OBJECT (button), "clicked", G_CALLBACK (button_clicked), text_view); gtk_widget_show_all (window); gtk_main (); return 0; }

thanks

first i want to thank u a lot for ur help as usual learning form you , i learned from katoob alot , i consider it refrence to me especially in gtk+ inheritance and creating custom widget

ur code worked smoothly but it still have a small problem because i couldn't explain correctly what i want to do the code works fine when using non time consimuning command like (ls) but trying a command taking long time like building application or configuring it the gui suspend and the text view still blank untill the operation ends then all the output written at once so i add two line while reading the file to force the gtk+ to refresh the screen while (gtk_events_pending()) gtk_main_iteration();

this is lead to make my textview operate as well as a normal console meaning at the time the line should printed to screen it printed on my textview instead which at last get my goal thanks a lot but i want to revise my knowledge 1- forking process when return 0 mean i am operate as child 2- popen forking a process and create a pipe and then returned a refrence to it 3- which i should use to read from

then because i actually make this program to learn what the problem in making my own forking ,my own pipe it give the expecting result when testing it as console application

MSameer's picture

No problem, It's my pleasure.

No problem, It's my pleasure. And thanks for the good words.

I think that If you fork, The child process'll run and the parent'll have no problem updating the widget, But since fork results in each process getting a copy of the variables, I think that you can't insert text into the textview. Maybe threading'll help, I'm not sure.

1) Yes, What you said about forking is true. int x = fork(); if (x == -1) { perror("fork"); } else if (x == 0) { printf("I'm a happy child!\n"); } else { /* x > 0 */ printf("I'm a proud parent.\n"); }

2) Yes, man popen ;-)

I really don't know what are you trying to do exactly ? But I suggest that you have a look at "Advanced Linux Programming" It's a cool book.

BTW: You can now put your code between &lt;code&gt; and &lt;/code&gt;

Alaa's picture

no he cannot

please don't use the code tag until we're done debugging the thing and writing a css style for it.

cheers,

Alaa


"u know i once dream that the office of mobinil is from el 7`os :S and the one that answer u and tell u rasidak a girl called ghada"

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.


Dr. Radut | forum