diff options
author | Sam Vilain <sam.vilain@catalyst.net.nz> | 2006-10-02 05:18:04 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-10-02 10:57:20 -0400 |
commit | f5dd3d6fadf98a53b35d20427ca198fda42f1251 (patch) | |
tree | 2e1deb1d0fb69002f459ae8dc90b2d26c24ca480 | |
parent | 12fd352038c037ba3a7071a2ca8597c55114abc3 (diff) |
[PATCH] proc: sysctl: add _proc_do_string helper
The logic in proc_do_string is worth re-using without passing in a
ctl_table structure (say, we want to calculate a pointer and pass that in
instead); pass in the two fields it uses from that structure as explicit
arguments.
Signed-off-by: Sam Vilain <sam.vilain@catalyst.net.nz>
Cc: Serge E. Hallyn <serue@us.ibm.com>
Cc: Kirill Korotaev <dev@openvz.org>
Cc: "Eric W. Biederman" <ebiederm@xmission.com>
Cc: Herbert Poetzl <herbert@13thfloor.at>
Cc: Andrey Savochkin <saw@sw.ru>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
-rw-r--r-- | kernel/sysctl.c | 65 |
1 files changed, 36 insertions, 29 deletions
diff --git a/kernel/sysctl.c b/kernel/sysctl.c index ba42694f0453..8b5f4bb8ad2f 100644 --- a/kernel/sysctl.c +++ b/kernel/sysctl.c | |||
@@ -1624,32 +1624,14 @@ static ssize_t proc_writesys(struct file * file, const char __user * buf, | |||
1624 | return do_rw_proc(1, file, (char __user *) buf, count, ppos); | 1624 | return do_rw_proc(1, file, (char __user *) buf, count, ppos); |
1625 | } | 1625 | } |
1626 | 1626 | ||
1627 | /** | 1627 | int _proc_do_string(void* data, int maxlen, int write, struct file *filp, |
1628 | * proc_dostring - read a string sysctl | 1628 | void __user *buffer, size_t *lenp, loff_t *ppos) |
1629 | * @table: the sysctl table | ||
1630 | * @write: %TRUE if this is a write to the sysctl file | ||
1631 | * @filp: the file structure | ||
1632 | * @buffer: the user buffer | ||
1633 | * @lenp: the size of the user buffer | ||
1634 | * @ppos: file position | ||
1635 | * | ||
1636 | * Reads/writes a string from/to the user buffer. If the kernel | ||
1637 | * buffer provided is not large enough to hold the string, the | ||
1638 | * string is truncated. The copied string is %NULL-terminated. | ||
1639 | * If the string is being read by the user process, it is copied | ||
1640 | * and a newline '\n' is added. It is truncated if the buffer is | ||
1641 | * not large enough. | ||
1642 | * | ||
1643 | * Returns 0 on success. | ||
1644 | */ | ||
1645 | int proc_dostring(ctl_table *table, int write, struct file *filp, | ||
1646 | void __user *buffer, size_t *lenp, loff_t *ppos) | ||
1647 | { | 1629 | { |
1648 | size_t len; | 1630 | size_t len; |
1649 | char __user *p; | 1631 | char __user *p; |
1650 | char c; | 1632 | char c; |
1651 | 1633 | ||
1652 | if (!table->data || !table->maxlen || !*lenp || | 1634 | if (!data || !maxlen || !*lenp || |
1653 | (*ppos && !write)) { | 1635 | (*ppos && !write)) { |
1654 | *lenp = 0; | 1636 | *lenp = 0; |
1655 | return 0; | 1637 | return 0; |
@@ -1665,20 +1647,20 @@ int proc_dostring(ctl_table *table, int write, struct file *filp, | |||
1665 | break; | 1647 | break; |
1666 | len++; | 1648 | len++; |
1667 | } | 1649 | } |
1668 | if (len >= table->maxlen) | 1650 | if (len >= maxlen) |
1669 | len = table->maxlen-1; | 1651 | len = maxlen-1; |
1670 | if(copy_from_user(table->data, buffer, len)) | 1652 | if(copy_from_user(data, buffer, len)) |
1671 | return -EFAULT; | 1653 | return -EFAULT; |
1672 | ((char *) table->data)[len] = 0; | 1654 | ((char *) data)[len] = 0; |
1673 | *ppos += *lenp; | 1655 | *ppos += *lenp; |
1674 | } else { | 1656 | } else { |
1675 | len = strlen(table->data); | 1657 | len = strlen(data); |
1676 | if (len > table->maxlen) | 1658 | if (len > maxlen) |
1677 | len = table->maxlen; | 1659 | len = maxlen; |
1678 | if (len > *lenp) | 1660 | if (len > *lenp) |
1679 | len = *lenp; | 1661 | len = *lenp; |
1680 | if (len) | 1662 | if (len) |
1681 | if(copy_to_user(buffer, table->data, len)) | 1663 | if(copy_to_user(buffer, data, len)) |
1682 | return -EFAULT; | 1664 | return -EFAULT; |
1683 | if (len < *lenp) { | 1665 | if (len < *lenp) { |
1684 | if(put_user('\n', ((char __user *) buffer) + len)) | 1666 | if(put_user('\n', ((char __user *) buffer) + len)) |
@@ -1691,6 +1673,31 @@ int proc_dostring(ctl_table *table, int write, struct file *filp, | |||
1691 | return 0; | 1673 | return 0; |
1692 | } | 1674 | } |
1693 | 1675 | ||
1676 | /** | ||
1677 | * proc_dostring - read a string sysctl | ||
1678 | * @table: the sysctl table | ||
1679 | * @write: %TRUE if this is a write to the sysctl file | ||
1680 | * @filp: the file structure | ||
1681 | * @buffer: the user buffer | ||
1682 | * @lenp: the size of the user buffer | ||
1683 | * @ppos: file position | ||
1684 | * | ||
1685 | * Reads/writes a string from/to the user buffer. If the kernel | ||
1686 | * buffer provided is not large enough to hold the string, the | ||
1687 | * string is truncated. The copied string is %NULL-terminated. | ||
1688 | * If the string is being read by the user process, it is copied | ||
1689 | * and a newline '\n' is added. It is truncated if the buffer is | ||
1690 | * not large enough. | ||
1691 | * | ||
1692 | * Returns 0 on success. | ||
1693 | */ | ||
1694 | int proc_dostring(ctl_table *table, int write, struct file *filp, | ||
1695 | void __user *buffer, size_t *lenp, loff_t *ppos) | ||
1696 | { | ||
1697 | return _proc_do_string(table->data, table->maxlen, write, filp, | ||
1698 | buffer, lenp, ppos); | ||
1699 | } | ||
1700 | |||
1694 | /* | 1701 | /* |
1695 | * Special case of dostring for the UTS structure. This has locks | 1702 | * Special case of dostring for the UTS structure. This has locks |
1696 | * to observe. Should this be in kernel/sys.c ???? | 1703 | * to observe. Should this be in kernel/sys.c ???? |