Re: showing a logfile in a Textview(like tail -f)



On 7/20/06, tomas tuxteam de <tomas tuxteam de> wrote:

On Thu, Jul 20, 2006 at 11:55:47AM +0200, rupert wrote:
> Which is the best way to create a textview that show me the actuall
logfile
> in a gtktextview?
> Currently i update a buffer with gtk_text_buffer_insert_at_cursor(data,
> line, -1);    in a timeout, the problem here is that the new text gets
> copied at the and of the old text,

Hm. Maybe gtk_text_buffer_set_text is your friend then?

>                                    i also tried gtk_text_buffer_insert,
but
> that gives me no text or a segfault.

See below

>
> This is the function that gets called by teh timeout
> out_smb_status(gpointer data){
>
>     system("smbstatus -S > /tmp/smb_status");
>
>     FILE *fp = fopen("/tmp/smb_status", "r");
>     gchar line[512];
>
>
>     if (fp)
>     {
>         while (fgets(line, sizeof(line), fp))
>         {
>         gtk_text_buffer_delete(data, 1, 512);
                                      ^^^^^^^^ Those are GtkTextIter *
                                                      too, see below.
>         gtk_text_buffer_insert_at_cursor(data, line, -1);
>         //gtk_text_buffer_insert (data, 1, line, -1);
                                         ^^^
This is the segfault.


Th second arg should be a pointer to a GtkTextIter. I doubt that your
machine has such a thing at address 1 ;-)

Besides, this business could be improved a bit ;-)

>     system("smbstatus -S > /tmp/smb_status");
>
>     FILE *fp = fopen("/tmp/smb_status", "r");

(1) you might replace those by

      FILE *fp = popen("smbstatus -S", "r");

thus obviating the need of a temp file. Anyway, using a fixed name for a
temp file is generally a bad idea. Imagine another program trying the
same :-)


works great

(2) I'd even go with a biggish buffer and use fread() (you don't need to
parse
the file line-by-line. I think), like so:

      gchar buf[4096];
      size_t got = fread(buf, 1, sizeof(buf), fp);
      gtk_buffer_set_text(data, buf, got); /* first batch */
      while(  (got = fread(buf, 1, sizeof(buf), fp))  >  0  ) { /* more
batches? */
        GtkTextIter endpos;
        gtk_text_buffer_get_end_iter(data, &endpos);
        gtk_text_buffer_insert(data, &endpos, buf, got);
      }

or something along these lines (caution: totally untested code!).


i only had to change one line to get this working,
it also displays the result of smbstatus only once and stops after one
entry,
seems to be better to go char. by char.

(3) Another think I'd try is slurping the whole file into a buffer,
reallocating as necessary and attaching it in one go to the text buffer
with one gtk_buffer_set_text(). I'd imagine that to be more efficient
since you trigger off the whole "changed" event machinery just once. May
be you could keep hold of the reallocated buffer for the next time. Or
some such.


i thought something like that,  will take a look at that

Enough. I hope this serves as inspiration

-- tomás



thx for your help, again

the whole working function, for preservation purposes...

out_smb_status(gpointer data){

       FILE *fp = popen("smbstatus -S", "r");

       if (fp)
       {
               gchar buf[4096];
               size_t got = fread(buf, 1, sizeof(buf), fp);
               gtk_text_buffer_set_text(data, buf, got);

            while(  (got = fread(buf, 1, sizeof(buf), fp))  >  0  )
          {
                    GtkTextIter endpos;
                    gtk_text_buffer_get_end_iter(data, &endpos);
                    gtk_text_buffer_insert(data, &endpos, buf, got);
      }
   }
   fclose(fp);

   return data;

}



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]