tty flush flip buffer on ldisc input queue flush
PATCH 1/1 tty flush flip buffer on ldisc input queue flush
Flush the tty flip buffer when the line discipline input queue is flushed, including the user call tcflush(TCIFLUSH/TCIOFLUSH). This prevents unexpected stale data after a user application calls tcflush().
drivers/char/tty_io.c +33 -0
@@ -365,6 +365,29 @@ static void tty_buffer_free(struct tty_s }/** +* tty_buffer_flush - flush full tty buffers +* @tty: tty to flush +* +* flush all the buffers containing receive data +* +* Locking: none +*/ + +static void tty_buffer_flush (struct tty_struct *tty) +{ +struct tty_buffer *thead; +unsigned long flags; + +spin_lock_irqsave (&tty->buf.lock, flags); +while ((thead = tty->buf.head) !=NULL ) { + tty->buf.head = thead->next; +tty_buffer_free (tty, thead); + } + tty->buf.tail =NULL ; +spin_unlock_irqrestore (&tty->buf.lock, flags); +} + +/** * tty_buffer_find - find a free tty buffer * @tty: tty owning the buffer * @size: characters wanted
@@ -1240,6 +1263,7 @@ void tty_ldisc_flush(struct tty_struct * ld->flush_buffer (tty);tty_ldisc_deref (ld); } +tty_buffer_flush (tty); }EXPORT_SYMBOL_GPL (tty_ldisc_flush);
@@ -3336,6 +3360,15 @@ int tty_ioctl(struct inode * inode, strucase TIOCMBIC :case TIOCMBIS :return tty_tiocmset (tty, file, cmd, p); +case TCFLSH : +switch (arg) { +case TCIFLUSH : +case TCIOFLUSH : +/* flush tty buffer and allow ldisc to process ioctl */ +tty_buffer_flush (tty); +break ; + } +break ; }if (tty->driver->ioctl) { retval = (tty->driver->ioctl)(tty, file, cmd, arg);
PATCH 1/1 isdn/i4l: 'NO CARRIER' message lost after ldisc flush
The ISDN tty layer doesn't produce a 'NO CARRIER' message after hangup.
I suppose it broke when tty_buffer_flush() has been added to tty_ldisc_flush() in the commit below.
For isdn_tty_modem_result(RESULT_NO_CARRIER..) the message inserted via isdn_tty_at_cout() -> tty_insert_flip_char() is flushed immediately by tty_ldisc_flush() -> tty_buffer_flush(). More annoyingly, the audio abort sequence DLE-ETX is also lost.
This patch fixes only active audio connections, because I assume that nobody changes the line discipline for audio.
For non-audio connections the problem remains.
Maybe we can remove the tty_ldisc_flush() in isdn_tty_modem_result() at all because it's done at tty_close?
Quoted 16 lines · Paul Fulghum
Flush the tty flip buffer when the line discipline input queue is flushed, including the user call tcflush(TCIFLUSH/TCIOFLUSH). This prevents unexpected stale data after a user application calls
tcflush().Cc Alan Cox <[email protected]>Cc Antonino Ingargiola <[email protected]>Signed-off-by Paul Fulghum <[email protected]>drivers/char/tty_io.c +1
-0@@ -1240,6 +1263,7 @@ void tty_ldisc_flush(struct tty_struct * ld->flush_buffer (tty);tty_ldisc_deref (ld); } +tty_buffer_flush (tty);
[..]
drivers/isdn/i4l/isdn_tty.c +5 -0
@@ -2645,7 +2649,12 @@if ((info->flags &ISDN_ASYNC_CLOSING ) || (!info->tty)) {return ; } +#ifdef CONFIG_ISDN_AUDIO +if ( !info->vonline ) +tty_ldisc_flush (info->tty); +#else tty_ldisc_flush (info->tty); +#endif if ((info->flags &ISDN_ASYNC_CHECK_CD ) && (!((info->flags &ISDN_ASYNC_CALLOUT_ACTIVE ) && (info->flags &ISDN_ASYNC_CALLOUT_NOHUP )))) {
Re: [PATCH] isdn/i4l: 'NO CARRIER' message lost after ldisc flush
Quoted 3 lines
For non-audio connections the problem remains.
Maybe we can remove thetty_ldisc_flush()inisdn_tty_modem_result()at all because it's done attty_close?
I'm not sure I understand why the tty_ldisc_flush is being done in the ISDN layer at this point but this change looks fine to me.
Alan
Re: [PATCH] isdn/i4l: 'NO CARRIER' message lost after ldisc flush
From: Alan Cox <[email protected]>
Date: Thu, 3 Jan 2008 22:30:54 +0000
Quoted 6 lines
Quoted 3 lines
For non-audio connections the problem remains.
Maybe we can remove thetty_ldisc_flush()inisdn_tty_modem_result()at all because it's done attty_close?I'm not sure I understand why the
tty_ldisc_flushis being done in the ISDN layer at this point but this change looks fine to me.
I'll apply this fix to net-2.6 and push to Linus.
Thanks.