Tcl Source Code

View Ticket
Bounty program for improvements to Tcl and certain Tcl packages.
Ticket UUID: 525783
Title: Need optional full flush on [exit] for serial
Type: RFE Version: None
Submitter: dgp Created on: 2002-03-05 04:03:07
Subsystem: 25. Channel System Assigned To: ferrieux
Priority: 5 Medium Severity:
Status: Closed Last Modified: 2012-07-04 04:34:55
Resolution: Fixed Closed By: ferrieux
    Closed on: 2012-07-03 21:33:02
Previously reported as Tk Bug 525778, tclsh has the
same problem on Solaris 8:

# FILE: test.tcl 
for {set i 0} {$i < [lindex $argv 0]} {incr i} { 
  puts $i 

$ tclsh8.3 test.tcl 5
$ tclsh8.4 test.tcl 5
<no output>

$ tclsh8.3 test.tcl 500
$ tclsh8.4 test.tcl 5

I'm assigning to "Channel System" because I think
that must be where the bug lies.  tclsh calls
Tcl_FSEvalFile() within Tcl_Main() and wish calls
Tcl_EvalFile() within Tk_Main(), so they don't have
code in common, but show the same misbehavior.
User Comments: ferrieux added on 2012-07-04 04:34:55:
Hum, 398 of course, not 348.

ferrieux added on 2012-07-04 04:33:02:
OK, closing as fixed by TIP 348: those who want the data to be flushed with insistence on serial lines (possibly blocking for a long time) should set the channel to blocking mode prior to closing/exiting; those who want a timely exit at the cost of possible data loss should set it to nonblocking mode.

dkf added on 2012-07-04 02:59:17:
Probably not, other than that compared to everything else they are horribly slow so people _never_ seem to agree on whether to block for them to flush on exit or not.

If you think this FRQ is superseded, just close it. :-)

ferrieux added on 2012-07-03 22:34:43:
IMO, the "-closemode" of TIP 160 is obsoleted by TIP 398, simply by switching the (serial) channel to blocking or nonblocking before closing. Am I missing something linked with the special nature of serial lines ?

dkf added on 2012-07-03 15:26:17:
IP - Comment Removed:

dkf added on 2012-07-03 15:25:57:
IP - Comment Removed:

dkf added on 2012-07-03 15:25:47:
IP - Comment Removed:

dkf added on 2012-07-03 15:25:25:
This appears to be entangled with TIP #398 concerns...

davygrvy added on 2005-11-06 05:50:35:
Logged In: YES 

Pat, please help, I can't do Tcl programming stuff at this

dkf added on 2003-10-22 22:27:03:
Logged In: YES 

Dropping the prio; it's in the TIP process now

dkf added on 2003-10-17 17:46:25:
Logged In: YES 

See TIP#160

dgp added on 2002-06-25 21:34:07:
Logged In: YES 

restored assignements lost in Tracker move.

dkf added on 2002-06-25 21:30:20:
Logged In: YES 

This is really an FRQ now

schroedter added on 2002-06-24 18:08:44:
Logged In: YES 

As the author of the recent serial port changes (TIP#35) I'm supporting Donal's proposal of an additional fconfigure 

    fconfigure $fd -onclose wait/discard

This option should be general for *all* Tcl channels with the obvious default=wait (or flush).
Please note that this cannot be done by the channel driver's [fconfigure] part because the channels driver cannot 
easily distinguish between a "normal flush" and a "flush-on-close" situation. 
Currently Tcl's channel system performs a blocking write before closing/exiting

    - Put the channel into blocking mode and
    - Write out all pending data

This should be avoided by calling [fconfigure $chan -onclose discard]. It's really bad that a channel intentionally 
configured by the user as non-blocking becomes blocking at close. I assume that this could also be useful for 
other channels (sockets ?).


dkf added on 2002-06-24 17:08:30:
Logged In: YES 

The current situation results in bugs for the smallest
number of people; a lot more people use Tcl from a terminal
on Unix than use serial ports under Unix!  A comment of mine
below (the -onclose option) contains the germ of a TIP to
fully resolve this matter (I know of no way to determine
what the best action is by default, and that is really an OS
design decision that I agree with in principle, so this
really belongs in the hands of programmers) and I might get
around to doing something about it in the future.  Or I
might not.  Either way, no reason to hold back the b1
release waiting on this.

dgp added on 2002-06-22 07:30:04:
Logged In: YES 

hot potato back to you.

all my problems are resolved.

andreas_kupries added on 2002-06-22 00:23:54:
Logged In: YES 

In a way. See below. Jeff did provide and commit a fix, but he 
is not completely satisfied with it. The std* channels have the 
correct behaviour, but true serial channels might not get 
completely auto-flushed when exiting.

So the bug as reported is fixed, with problems in a different 

dgp added on 2002-06-22 00:03:42:
Logged In: YES 

I can no longer reproduce the problem with the HEAD sources.
Is this matter closed?

andreas_kupries added on 2002-05-11 00:05:10:
Logged In: YES 

I remember that Jeff did some changes ...
Changelog ...

2002-03-05  Jeff Hobbs  <[email protected]>

* unix/tclUnixChan.c: initial remedy for [Bug 
#525783] flush
problem introduced by TIP #35.  This may not 
satisfy true serial
channels, but it restores the correct flushing of 
std* channels on

dgp added on 2002-05-10 23:53:05:
Logged In: YES 

Did this get resolved?

dkf added on 2002-03-06 20:18:16:
Logged In: YES 

The problem with tcflush on exit is that it can nuke output
in the OS buffers that came from stderr (say "sayonara" to
debugging messages!)  Further investigation found that this
could still happen even with some fairly elaborate measures
to prevent it (like barring tcflush from operating on FDs 0,
1 and 2) because it is a race between the data being grabbed
by the tty and displayed, and the tcflush on an unrelated
channel (you'll need the [open [exec tty]] addition
mentioned below to enable this behaviour.)

So as to make sure that people just using Tcl normally would
not see the problem, and given the short timescale we were
working on w.r.t. the 8.4a4 release, the tcflush was changed
to a tcdrain (whose behaviour meets more what non-serial
people think of by a flush!) even though this is clearly not
what you were intending when you wrote the code.  A better
fix will require application-input (since both behaviours
are right in certain circumstances) which means there's room
for another thing to [fconfigure], e.g.

   fconfigure $fd -onclose wait/discard

(Reset semantics probably ought to be handled in the same
way, because they are equally surprising when they hit the
controlling terminal and both styles of behaviour can be
considered to be correct in some circumstances.)

schroedter added on 2002-03-06 19:48:52:
Logged In: YES 

This problem was probably introduced by two changes:
1. stdin/stdout are now handled by the TTY driver
2. The TIP#35 changes (Add serial port handshake support)

There is no doubt, that TCL-exit should not stall if a serial port output is blocked.
This can happen with handshake support. 
This could also happen even before the TIP#35 changes, when the serial port handshake is activated by 
using "stty" settings.

At exit the channel driver sets all unflushed channels to blocking mode and waits until the output is flushed 
(maybe forever). That's why the serial port driver now calls "tcflush".
For a serial port this is okay, for stdin/stdout this maybe bad.

Anyway Tcl's behaviour on exit needs further discussion.

hobbs added on 2002-03-06 04:01:49:
File Added - 18840: 525783.patch

hobbs added on 2002-03-06 04:01:48:
Logged In: YES 

Attached is my recommend patch (already commited for others 
to test) to 8.4a4.  This removes use of tcflush and reverts 
to always calling FileOutputProc for now.

hobbs added on 2002-03-06 03:07:58:
Logged In: YES 

A much more reliable test script is:

set size [lindex $argv 0]
if {![string is int -strict $size]} { set size 100 }
for {set i 0} {$i < $size} {incr i} {
    puts $i
puts stderr done

by adding in the data on the extra channel, that seems to 
add enough perturbation to the tty's to always show the bug.

However, simply changing "tcflush(...)" to "tcdrain((fd))" 
solves all the problems that I can repeat.

dkf added on 2002-03-05 23:46:33:
Logged In: YES 

However, things still foul up if you add
   open [exec tty]
to the script.  Need fstat() to detect and avoid that. :^(

dkf added on 2002-03-05 23:40:48:
File Deleted - 18826: 

File Added - 18835: flush3.patch

dkf added on 2002-03-05 23:40:47:
Logged In: YES 

That was only a partial fix; here's a better one

dkf added on 2002-03-05 18:22:28:
File Added - 18826: flush.patch

dkf added on 2002-03-05 18:22:27:
Logged In: YES 

Easy fix: exclude stdout and stderr from the magical
flushing in TtyCloseProc() using the attached patch.

dkf added on 2002-03-05 16:50:09:
Logged In: YES 

This looks to be TIP#35 related (which stopped serial lines
from being flushed on [close] because the operation might
block indefinitely), combined with other changes which made
stdio channels be recognised as serial channels when used
interactively.  Both of these make perfect sense in
themselves, but they interact badly.  Yuck.

I suppose the correct thing to do is to do the flush on
close only for stdio channels to ttys; i.e. when the fd is 1
or 2...

dgp added on 2002-03-05 13:29:21:
Logged In: YES 

Confirmed.  The changes to unix/tclUnixChan.c
on 2002-Feb-27 are what broke things.  If this
can't be fixed quickly, I recommend reverting
to Revision 1.29 before releasing 8.4a4.

dgp added on 2002-03-05 12:55:14:
Logged In: YES 

Sources on Feb 15 worked fine too.  This is a recently
introduced issue.

dgp added on 2002-03-05 11:35:27:
Logged In: YES 

tclsh 8.4a3 works properly, so the
bug has been introduced since that release.