mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-28 02:32:09 -04:00
sysctl: add support for poll()
Adding support for poll() in sysctl fs allows userspace to receive notifications of changes in sysctl entries. This adds a infrastructure to allow files in sysctl fs to be pollable and implements it for hostname and domainname. [[email protected]: s/declare/define/ for definitions] Signed-off-by: Lucas De Marchi <[email protected]> Cc: Greg KH <[email protected]> Cc: Kay Sievers <[email protected]> Cc: Al Viro <[email protected]> Cc: "Eric W. Biederman" <[email protected]> Cc: Alexey Dobriyan <[email protected]> Signed-off-by: Andrew Morton <[email protected]> Signed-off-by: Linus Torvalds <[email protected]>
This commit is contained in:
parent
088024b1de
commit
f1ecf06854
5 changed files with 108 additions and 0 deletions
|
|
@ -3,6 +3,7 @@
|
|||
*/
|
||||
#include <linux/init.h>
|
||||
#include <linux/sysctl.h>
|
||||
#include <linux/poll.h>
|
||||
#include <linux/proc_fs.h>
|
||||
#include <linux/security.h>
|
||||
#include <linux/namei.h>
|
||||
|
|
@ -14,6 +15,15 @@ static const struct inode_operations proc_sys_inode_operations;
|
|||
static const struct file_operations proc_sys_dir_file_operations;
|
||||
static const struct inode_operations proc_sys_dir_operations;
|
||||
|
||||
void proc_sys_poll_notify(struct ctl_table_poll *poll)
|
||||
{
|
||||
if (!poll)
|
||||
return;
|
||||
|
||||
atomic_inc(&poll->event);
|
||||
wake_up_interruptible(&poll->wait);
|
||||
}
|
||||
|
||||
static struct inode *proc_sys_make_inode(struct super_block *sb,
|
||||
struct ctl_table_header *head, struct ctl_table *table)
|
||||
{
|
||||
|
|
@ -176,6 +186,39 @@ static ssize_t proc_sys_write(struct file *filp, const char __user *buf,
|
|||
return proc_sys_call_handler(filp, (void __user *)buf, count, ppos, 1);
|
||||
}
|
||||
|
||||
static int proc_sys_open(struct inode *inode, struct file *filp)
|
||||
{
|
||||
struct ctl_table *table = PROC_I(inode)->sysctl_entry;
|
||||
|
||||
if (table->poll)
|
||||
filp->private_data = proc_sys_poll_event(table->poll);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static unsigned int proc_sys_poll(struct file *filp, poll_table *wait)
|
||||
{
|
||||
struct inode *inode = filp->f_path.dentry->d_inode;
|
||||
struct ctl_table *table = PROC_I(inode)->sysctl_entry;
|
||||
unsigned long event = (unsigned long)filp->private_data;
|
||||
unsigned int ret = DEFAULT_POLLMASK;
|
||||
|
||||
if (!table->proc_handler)
|
||||
goto out;
|
||||
|
||||
if (!table->poll)
|
||||
goto out;
|
||||
|
||||
poll_wait(filp, &table->poll->wait, wait);
|
||||
|
||||
if (event != atomic_read(&table->poll->event)) {
|
||||
filp->private_data = proc_sys_poll_event(table->poll);
|
||||
ret = POLLIN | POLLRDNORM | POLLERR | POLLPRI;
|
||||
}
|
||||
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int proc_sys_fill_cache(struct file *filp, void *dirent,
|
||||
filldir_t filldir,
|
||||
|
|
@ -364,6 +407,8 @@ static int proc_sys_getattr(struct vfsmount *mnt, struct dentry *dentry, struct
|
|||
}
|
||||
|
||||
static const struct file_operations proc_sys_file_operations = {
|
||||
.open = proc_sys_open,
|
||||
.poll = proc_sys_poll,
|
||||
.read = proc_sys_read,
|
||||
.write = proc_sys_write,
|
||||
.llseek = default_llseek,
|
||||
|
|
|
|||
Loading…
Reference in a new issue