command pipelines, blocking and stderr
Available news archives: comp.lang.tcl - comp.lang.python - comp.security.firewalls - sci.crypt - comp.lang.php - comp.lang.javascript
Google
 
Web news.hping.org


comp.lang.tcl archive

command pipelines, blocking and stderr

From: David N. Welton <davidw@dedasys.com>
Date: Fri Sep 30 2005 - 11:03:03 CEST

Hello,

I've written a bit of code that is quite useful for launching commands
from Tk without locking up the application (at the end of the message),
but there's something I don't quite get. The code to close things down
is like so:

    if { [eof $fl] } {
        fconfigure $fl -blocking 1
        catch { close $fl } err

which is saying that if there is nothing more to read from the
processes's stdout, we need to close things down and report back to
whoever called us. The problem I was encountering was that without
setting the channel back to blocking before closing it, it didn't report
in 'err' the command's stderr. I sort of see the logic behind this, but
I wanted to enquire about it to see if others feel that this is the
right way to do things...

Opinions?

Thanks,

-- 
David N. Welton
- http://www.dedasys.com/davidw/
Linux, Open Source Consulting
- http://www.dedasys.com/
------------------
namespace eval runcommand {}
proc ::runcommand::runcommand {cmd} {
    variable standarderror
    variable standardout
    #puts "running $cmd"
    set standardout ""
    set standarderror ""
    set fl [open "| $cmd" r]
    fconfigure $fl -blocking 0
    fconfigure $fl -buffering none
    ::runcommand::runcommandloop $fl
    vwait ::runcommand::finished
    #puts "stdout: $standardout"
    #puts "stderr: $standarderror"
    return "Output:\n$standardout\nErrors:\n$standarderror"
}
proc ::runcommand::runcommandloop {fl} {
    variable standarderror
    variable standardout
    append standardout [read $fl]
    if { [eof $fl] } {
	fconfigure $fl -blocking 1
        catch { close $fl } err
        append standarderror $err
        after 1 [list set ::runcommand::finished 1]
        return
    }
    after 100 [list ::runcommand::runcommandloop $fl]
}
set out [runcommand::runcommand "make aaaa"]
puts $out
Received on Sat Oct 15 03:53:48 2005