fileevent and buffering

From: Anthony (who_at_where.com)
Date: 03/29/05


Date: Tue, 29 Mar 2005 03:09:21 GMT

Hello all,
    I am experiencing a problem with fileevent. All I am trying to do is
open a process and read from it in a timely manner.
What I keep running into is that fileevent won't return a readable pipe
until the buffer I am trying to read has about 5k char.
I want to act on every line of stdout produced by the process I am opening
in a timely manner and not have to wait for the buffer
to fill up. I have included my sample tcl script as well as the c program I
am using as an example to drive the script. Please advise me on how to
handle this case. Is writing my own message queue an alternative to
fileevent? Thanks for your input.

-Anthony

#!/bin/sh
# the next line restarts using wish \
exec wish "$0" ${1+"$@"}

#--------------------------------------------------------------------
# Cleanup
#
proc stopProc { } {
   global pid fid
   catch {exec kill [lindex $pid 0]}
   catch {close $fid}
}

#--------------------------------------------------------------------
# Close
#
proc cleanUp { } {
   stopProc
   exit
}

#--------------------------------------------------------------------
# Show process results
#
proc showResults { line } {
  global w
  $w.lf.t insert end "$line\n"
  $w.lf.t see end
}

#--------------------------------------------------------------------
# Get process results
#
proc getResults { done } {
  global fid
  set buff [read $fid]

  if {[eof $fid]} {
    catch {close $fid}
    set ::$done 1
  }

  if {[string length $buff] > 0} {
     # I need to act on each line independently
# foreach line [split $buff \n] {
# showResults $line
       showResults $buff
       after 25
       update
# }
  }
}

#--------------------------------------------------------------------
# Start process
#

proc startProc { } {
   global fid pid
   set fid [open {|tstout &} r]
   set pid [pid $fid]
   fconfigure $fid -buffering none -blocking 0
   fileevent $fid readable [list getResults done]
   vwait done
}

#--------------------------------------------------------------------
# Main window
#
wm withdraw .

set fid ""
set pid ""

catch { destroy $w }
set w [toplevel .trd]
wm geometry $w +300+300
wm protocol $w WM_DELETE_WINDOW { cleanUp }
wm title $w "receiver simulator"
bind $w <Escape> { cleanUp }

#--------------------------------------------------------------------
# Frame and Buttons
#
frame $w.bf -pady 5
button $w.bf.exit -text "Stop" -command {stopProc} -justify center
button $w.bf.proc -text "Start" -command {startProc} -justify center

pack $w.bf.exit $w.bf.proc -side left -expand yes -pady 5

#--------------------------------------------------------------------
# Frame and Text widgets
#
labelframe $w.lf -relief groove -font "screen 12 bold" -text "results"
text $w.lf.t -font {screen 12} -relief sunken -bd 2 -yscrollcommand \
    "$w.lf.scroll set" -setgrid 1 -height 25 -autosep 1
scrollbar $w.lf.scroll -command {$w.lf.t yview}

pack $w.lf.scroll -side right -fill y
pack $w.lf.t -expand yes -fill both

#--------------------------------------------------------------------
# Pack Frames
#
pack $w.lf -side top -anchor w -expand yes -fill both
pack $w.bf -side top -anchor w -anchor w -fill x

#define __EXTENSIONS__
#include <time.h>
#include <stdio.h>

int
main (int argc, char ** argv)
{
   int rval = 0;

   unsigned int count = 0;
   struct timespec looptime = {0, 5000000};

   while (1)
   { /* output 50 bytes per line */
       printf("%05u _123456789_123456789_123456789_123456789 \n",
count++);
       nanosleep(&looptime, NULL);
   }

   return rval;
}
 


Quantcast