summaryrefslogtreecommitdiffstats
path: root/kernel/0001-tty-notifier.patch
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/0001-tty-notifier.patch')
-rw-r--r--kernel/0001-tty-notifier.patch224
1 files changed, 224 insertions, 0 deletions
diff --git a/kernel/0001-tty-notifier.patch b/kernel/0001-tty-notifier.patch
new file mode 100644
index 0000000..519cd55
--- /dev/null
+++ b/kernel/0001-tty-notifier.patch
@@ -0,0 +1,224 @@
+From 6579fc26064c146dd886ddc1d63c8469e9d8fc65 Mon Sep 17 00:00:00 2001
+From: jolsa@redhat.com <jolsa@redhat.com>
+Date: Mon, 8 Mar 2010 17:52:48 +0100
+Subject: [PATCH 1/3] tty notifier
+
+---
+ drivers/char/Kconfig | 6 +++
+ drivers/char/tty_io.c | 106 +++++++++++++++++++++++++++++++++++++++++++++++++
+ include/linux/tty.h | 22 ++++++++++
+ 3 files changed, 134 insertions(+), 0 deletions(-)
+
+diff --git a/drivers/char/Kconfig b/drivers/char/Kconfig
+index 3141dd3..9be342e 100644
+--- a/drivers/char/Kconfig
++++ b/drivers/char/Kconfig
+@@ -1113,5 +1113,11 @@ config DEVPORT
+
+ source "drivers/s390/char/Kconfig"
+
++config TTY_NOTIFIER
++ bool "Terminal notifier"
++ depends on EXPERIMENTAL
++ default n
++ help
++ Interface to norify about terminals' data and state changes.
+ endmenu
+
+diff --git a/drivers/char/tty_io.c b/drivers/char/tty_io.c
+index a42c466..38f2d7b 100644
+--- a/drivers/char/tty_io.c
++++ b/drivers/char/tty_io.c
+@@ -154,6 +154,90 @@ static void release_tty(struct tty_struct *tty, int idx);
+ static void __proc_set_tty(struct task_struct *tsk, struct tty_struct *tty);
+ static void proc_set_tty(struct task_struct *tsk, struct tty_struct *tty);
+
++#ifdef CONFIG_TTY_NOTIFIER
++static LIST_HEAD(tty_structs); /* linked list of tty structs */
++static ATOMIC_NOTIFIER_HEAD(tty_notifier_list);
++
++/**
++ * register_tty_notifier - register tty notifier
++ *
++ * Locking: none
++ */
++
++int register_tty_notifier(struct notifier_block *nb)
++{
++ return atomic_notifier_chain_register(&tty_notifier_list, nb);
++}
++EXPORT_SYMBOL_GPL(register_tty_notifier);
++
++/**
++ * unregister_tty_notifier - unregister tty notifier
++ *
++ * Locking: none
++ */
++
++int unregister_tty_notifier(struct notifier_block *nb)
++{
++ return atomic_notifier_chain_unregister(&tty_notifier_list, nb);
++}
++EXPORT_SYMBOL_GPL(unregister_tty_notifier);
++
++
++/**
++ * notify_tty_open - notify about tty open
++ *
++ * Calls the tty notifier chain.
++ *
++ * Locking: none
++ */
++
++static void notify_tty_create(struct tty_struct *tty)
++{
++ struct tty_notifier_param param = {
++ .tty = tty,
++ };
++
++ atomic_notifier_call_chain(&tty_notifier_list, TTY_NOTIFY_CREATE, &param);
++}
++
++/**
++ * notify_tty_close - notify about tty close
++ *
++ * Calls the tty notifier chain.
++ *
++ * Locking: none
++ */
++
++static void notify_tty_release(struct tty_struct *tty)
++{
++ struct tty_notifier_param param = {
++ .tty = tty,
++ };
++
++ atomic_notifier_call_chain(&tty_notifier_list, TTY_NOTIFY_RELEASE, &param);
++}
++
++/**
++ * notify_tty_data - notify about tty data
++ *
++ * Calls the tty notifier chain.
++ *
++ * Locking: none
++ */
++
++static void notify_tty_data(struct tty_struct *tty, unsigned char *buf, size_t size)
++{
++ struct tty_notifier_param param = {
++ .tty = tty,
++ .buf = buf,
++ .size = size
++ };
++
++ atomic_notifier_call_chain(&tty_notifier_list, TTY_NOTIFY_DATA, &param);
++}
++
++#endif
++
+ /**
+ * alloc_tty_struct - allocate a tty object
+ *
+@@ -981,6 +1065,11 @@ static inline ssize_t do_tty_write(
+ ret = -EFAULT;
+ if (copy_from_user(tty->write_buf, buf, size))
+ break;
++
++#ifdef CONFIG_TTY_NOTIFIER
++ notify_tty_data(tty, tty->write_buf, size);
++#endif
++
+ ret = write(tty, file, tty->write_buf, size);
+ if (ret <= 0)
+ break;
+@@ -1352,6 +1441,11 @@ struct tty_struct *tty_init_dev(struct tty_driver *driver, int idx,
+ retval = tty_ldisc_setup(tty, tty->link);
+ if (retval)
+ goto release_mem_out;
++
++#ifdef CONFIG_TTY_NOTIFIER
++ list_add(&tty->list, &tty_structs);
++ notify_tty_create(tty);
++#endif
+ return tty;
+
+ fail_no_mem:
+@@ -1474,6 +1568,10 @@ static void release_tty(struct tty_struct *tty, int idx)
+ /* This should always be true but check for the moment */
+ WARN_ON(tty->index != idx);
+
++#ifdef CONFIG_TTY_NOTIFIER
++ list_del(&tty->list);
++#endif
++
+ if (tty->link)
+ tty_kref_put(tty->link);
+ tty_kref_put(tty);
+@@ -1703,6 +1801,11 @@ int tty_release(struct inode *inode, struct file *filp)
+ #ifdef TTY_DEBUG_HANGUP
+ printk(KERN_DEBUG "freeing tty structure...");
+ #endif
++
++#ifdef CONFIG_TTY_NOTIFIER
++ notify_tty_release(tty);
++#endif
++
+ /*
+ * Ask the line discipline code to release its structures
+ */
+@@ -2768,6 +2871,9 @@ void initialize_tty_struct(struct tty_struct *tty,
+ spin_lock_init(&tty->read_lock);
+ spin_lock_init(&tty->ctrl_lock);
+ INIT_LIST_HEAD(&tty->tty_files);
++#ifdef CONFIG_TTY_NOTIFIER
++ INIT_LIST_HEAD(&tty->list);
++#endif
+ INIT_WORK(&tty->SAK_work, do_SAK_work);
+
+ tty->driver = driver;
+diff --git a/include/linux/tty.h b/include/linux/tty.h
+index 4409967..7d57719 100644
+--- a/include/linux/tty.h
++++ b/include/linux/tty.h
+@@ -13,6 +13,7 @@
+ #include <linux/tty_driver.h>
+ #include <linux/tty_ldisc.h>
+ #include <linux/mutex.h>
++#include <linux/notifier.h>
+
+ #include <asm/system.h>
+
+@@ -324,8 +325,29 @@ struct tty_struct {
+ /* If the tty has a pending do_SAK, queue it here - akpm */
+ struct work_struct SAK_work;
+ struct tty_port *port;
++#ifdef CONFIG_TTY_NOTIFIER
++ struct list_head list;
++#endif
++};
++
++
++#ifdef CONFIG_TTY_NOTIFIER
++
++#define TTY_NOTIFY_DATA 1
++#define TTY_NOTIFY_CREATE 2
++#define TTY_NOTIFY_RELEASE 3
++
++struct tty_notifier_param {
++ struct tty_struct *tty;
++ unsigned char *buf;
++ size_t size;
+ };
+
++extern int register_tty_notifier(struct notifier_block *nb);
++extern int unregister_tty_notifier(struct notifier_block *nb);
++
++#endif /* CONFIG_TTY_NOTIFIER */
++
+ /* tty magic number */
+ #define TTY_MAGIC 0x5401
+
+--
+1.6.6.1
+