diff options
Diffstat (limited to 'kernel/0001-tty-notifier.patch')
-rw-r--r-- | kernel/0001-tty-notifier.patch | 224 |
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, ¶m); ++} ++ ++/** ++ * 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, ¶m); ++} ++ ++/** ++ * 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, ¶m); ++} ++ ++#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 + |