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

Commit f5dd3d6f authored by Sam Vilain's avatar Sam Vilain Committed by Linus Torvalds
Browse files

[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: default avatarSam 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: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent 12fd3520
Loading
Loading
Loading
Loading
+36 −29
Original line number Diff line number Diff line
@@ -1624,32 +1624,14 @@ static ssize_t proc_writesys(struct file * file, const char __user * buf,
	return do_rw_proc(1, file, (char __user *) buf, count, ppos);
}

/**
 * proc_dostring - read a string sysctl
 * @table: the sysctl table
 * @write: %TRUE if this is a write to the sysctl file
 * @filp: the file structure
 * @buffer: the user buffer
 * @lenp: the size of the user buffer
 * @ppos: file position
 *
 * Reads/writes a string from/to the user buffer. If the kernel
 * buffer provided is not large enough to hold the string, the
 * string is truncated. The copied string is %NULL-terminated.
 * If the string is being read by the user process, it is copied
 * and a newline '\n' is added. It is truncated if the buffer is
 * not large enough.
 *
 * Returns 0 on success.
 */
int proc_dostring(ctl_table *table, int write, struct file *filp,
int _proc_do_string(void* data, int maxlen, int write, struct file *filp,
		    void __user *buffer, size_t *lenp, loff_t *ppos)
{
	size_t len;
	char __user *p;
	char c;
	
	if (!table->data || !table->maxlen || !*lenp ||
	if (!data || !maxlen || !*lenp ||
	    (*ppos && !write)) {
		*lenp = 0;
		return 0;
@@ -1665,20 +1647,20 @@ int proc_dostring(ctl_table *table, int write, struct file *filp,
				break;
			len++;
		}
		if (len >= table->maxlen)
			len = table->maxlen-1;
		if(copy_from_user(table->data, buffer, len))
		if (len >= maxlen)
			len = maxlen-1;
		if(copy_from_user(data, buffer, len))
			return -EFAULT;
		((char *) table->data)[len] = 0;
		((char *) data)[len] = 0;
		*ppos += *lenp;
	} else {
		len = strlen(table->data);
		if (len > table->maxlen)
			len = table->maxlen;
		len = strlen(data);
		if (len > maxlen)
			len = maxlen;
		if (len > *lenp)
			len = *lenp;
		if (len)
			if(copy_to_user(buffer, table->data, len))
			if(copy_to_user(buffer, data, len))
				return -EFAULT;
		if (len < *lenp) {
			if(put_user('\n', ((char __user *) buffer) + len))
@@ -1691,6 +1673,31 @@ int proc_dostring(ctl_table *table, int write, struct file *filp,
	return 0;
}

/**
 * proc_dostring - read a string sysctl
 * @table: the sysctl table
 * @write: %TRUE if this is a write to the sysctl file
 * @filp: the file structure
 * @buffer: the user buffer
 * @lenp: the size of the user buffer
 * @ppos: file position
 *
 * Reads/writes a string from/to the user buffer. If the kernel
 * buffer provided is not large enough to hold the string, the
 * string is truncated. The copied string is %NULL-terminated.
 * If the string is being read by the user process, it is copied
 * and a newline '\n' is added. It is truncated if the buffer is
 * not large enough.
 *
 * Returns 0 on success.
 */
int proc_dostring(ctl_table *table, int write, struct file *filp,
		  void __user *buffer, size_t *lenp, loff_t *ppos)
{
	return _proc_do_string(table->data, table->maxlen, write, filp,
			       buffer, lenp, ppos);
}

/*
 *	Special case of dostring for the UTS structure. This has locks
 *	to observe. Should this be in kernel/sys.c ????