Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit c5c34d48 authored by Paul Fulghum's avatar Paul Fulghum Committed by Linus Torvalds
Browse files

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().

Signed-off-by: default avatarAlan Cox <alan@redhat.com>
Cc: Antonino Ingargiola <tritemio@gmail.com>
Signed-off-by: default avatarPaul Fulghum <paulkf@microgate.com>
Cc: Theodore Ts'o <tytso@mit.edu>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent e3bf460f
Loading
Loading
Loading
Loading
+33 −0
Original line number Diff line number Diff line
@@ -368,6 +368,29 @@ static void tty_buffer_free(struct tty_struct *tty, struct tty_buffer *b)
	}
}

/**
 *	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
@@ -1248,6 +1271,7 @@ void tty_ldisc_flush(struct tty_struct *tty)
			ld->flush_buffer(tty);
		tty_ldisc_deref(ld);
	}
	tty_buffer_flush(tty);
}

EXPORT_SYMBOL_GPL(tty_ldisc_flush);
@@ -3350,6 +3374,15 @@ int tty_ioctl(struct inode * inode, struct file * file,
		case 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);