From Newsgroup: comp.lang.tcl
* meshparts <
alexandru.dadalau@meshparts.de>
| Am 18.11.2025 um 19:46 schrieb Ralf Fassel:
| > You need to take the usual configuration of channels into account:
| > - make sure to flush your output channel (or set it unbuffered) to make
| > sure any output is actually sent to the process
| > - you might need to close the 'unused' ends of the pipe in your process
| > after creating the child process (see
https://www.tcl-lang.org/man/tcl/TclCmd/chan.html#M30)
| > to get correct [eof] notifications
| > - make sure to avoid deadlocks if you send more data than the process
| > reads by setting the pipe channels non-blocking
| > R'
| Below is the current state of the code.
| I introduced a listener, so that I can output all the messages that
| are written by the process.
| But somehow, when multiple lines are written, the first and last line
| is not read.
| I tries setting all channels non-blocking and getting the result after
| "chan close" but nothing seems to help.
| Any ideas?
There is a potential for data race here: are you sure
::GeneratePartBatchRead has collected all data before you call 'close'
on the channels (add a diagnostic to stderr to see whether it has been
called)? I'd rather let ::GeneratePartBatchRead decide when to
stop: if it gets eof on the readChanId, the other side should have
closed it (note that you will need to close that channel in your
process, too, see chan manpage on 'pipe').
Also note that calling flush on an read channel ($processStdoutErr) is a
no-op, only write-channels will react to flush.
Someone with more experience in twapi will have to comment on the rest.
R'
| proc ::GeneratePartBatchRead {readChanId} {
| variable lastline
| # read the last line
| set line [gets $readChanId]
| # output to the main app
| puts $line
| # store the line for later use
| set lastline($readChanId) $line
| }
| # Open different channels for read and write
| lassign [chan pipe] processStdin writeChanId
| lassign [chan pipe] readChanId processStdoutErr
| # React when the read channel becomes readable (meaning, a new line
| # was written to the channel)
| chan event $readChanId readable "::GeneratePartBatchRead $readChanId"
| # Start the part generation process
| set res [::twapi::create_process "" -cmdline $cmdline -returnhandles 1
| -inherithandles 1 -stdchannels [list $processStdin $processStdoutErr
| $processStdoutErr]]
| # Store the process handles
| lassign $res pid tid hproc hthread
| # Wait for the process to end
| set ::twapi_pid($pid) ""
| ::twapi::wait_on_handle $hproc -executeonce 1 -async [list
| ::GlobalVarSetFromTwapiCallback ::twapi_pid($pid) ""]
| vwait ::twapi_pid($pid)
| ::twapi::close_handle $hproc
| # Get the last line written which is normally the path of the
| # generated model file
| chan flush $processStdoutErr
| set result $lastline($readChanId)
| catch {close $readChanId}
| catch {close $writeChanId}
| catch {close $processStdin}
| catch {close $processStdoutErr}
| array unset lastline $readChanId
--- Synchronet 3.21a-Linux NewsLink 1.2