All of lore.kernel.org
 help / color / mirror / Atom feed
From: Oleg Nesterov <oleg@redhat.com>
To: Lucas De Marchi <lucas.de.marchi@gmail.com>
Cc: lkml <linux-kernel@vger.kernel.org>,
	Andrew Morton <akpm@linux-foundation.org>,
	Rusty Russell <rusty@rustcorp.com.au>,
	Andi Kleen <andi@firstfloor.org>,
	Neil Horman <nhorman@tuxdriver.com>,
	Lennart Poettering <mzxreary@0pointer.de>,
	Colin Walters <walters@verbum.org>,
	Denys Vlasenko <vda.linux@googlemail.com>
Subject: [RFC] teach argv_split() to ignore the spaces surrounded by \e
Date: Mon, 13 May 2013 16:35:37 +0200	[thread overview]
Message-ID: <20130513143537.GA3278@redhat.com> (raw)
In-Reply-To: <20130513141633.GB1613@redhat.com>

On 05/13, Oleg Nesterov wrote:
>
> Lucas. I will be happy to resend the argv_split/call_modprobe changes,

speaking of argv_split...

What do you all think about the hack below? Sure, this is user-visible
and incompatible change, but perhaps we can do this?

Let me quote Lennart:

	Currently, if the kernel generates one command line string from the core
	pattern (if it is one with a |) and then splits that up again where it
	finds spaces. This is really broken for %e if a process name contains
	spaces.

Yes, we can change format_corename() to construct "argv" by hand, and
this was my iniital plan. But perhaps it would be better to not uglify
this code even more?

With the patch below we can trivially fix the problem,

	+	char *fmt = ispipe ? "\e%s\e" : "%s";
	...
	-	err = cn_printf(cn, "%s", current->comm);
	+	err = cn_printf(cn, fmt, current->comm);

Or this ESC hack is too ugly or can break something?

Oleg.

------------------------------------------------------------------------------
[PATCH] teach argv_split() to ignore the spaces surrounded by \e

This patch assumes that nobody ever wants "\e" in the string
passed to argv_split().

With this change argv_split() treats '\e' as white-space and
ignores all other spaces till the next '\e'. For example,
argv("1\e2  3\e \e 4 \e") returns

	[0] = "1",
	[1] = "2 3",
	[2] = " 4 ",
	[3] = NULL,

This allows us to trivially fix format_corename(), we do not
want to split, say, current->comm if it has spaces.

Signed-off-by: Oleg Nesterov <oleg@redhat.com>
---
 lib/argv_split.c |   37 +++++++++++++++++++++++++------------
 1 files changed, 25 insertions(+), 12 deletions(-)

diff --git a/lib/argv_split.c b/lib/argv_split.c
index e927ed0..e74221c 100644
--- a/lib/argv_split.c
+++ b/lib/argv_split.c
@@ -8,13 +8,23 @@
 #include <linux/slab.h>
 #include <linux/export.h>
 
+static bool argv_isspace(char ch, bool *in_esc)
+{
+	if (unlikely(ch == '\e')) {
+		*in_esc = !*in_esc;
+		return true;
+	}
+
+	return !*in_esc && isspace(ch);
+}
+
 static int count_argc(const char *str)
 {
+	bool was_space, in_esc;
 	int count = 0;
-	bool was_space;
 
-	for (was_space = true; *str; str++) {
-		if (isspace(*str)) {
+	for (in_esc = false, was_space = true; *str; str++) {
+		if (argv_isspace(*str, &in_esc)) {
 			was_space = true;
 		} else if (was_space) {
 			was_space = false;
@@ -45,21 +55,24 @@ EXPORT_SYMBOL(argv_free);
  * @str: the string to be split
  * @argcp: returned argument count
  *
- * Returns an array of pointers to strings which are split out from
- * @str.  This is performed by strictly splitting on white-space; no
- * quote processing is performed.  Multiple whitespace characters are
- * considered to be a single argument separator.  The returned array
- * is always NULL-terminated.  Returns NULL on memory allocation
- * failure.
+ * Returns an array of pointers to strings which are split out from @str.
+ * The returned array is always NULL-terminated.  Returns NULL on memory
+ * allocation failure.
+ *
+ * This is performed by splitting on white-space, no quote processing is
+ * performed except: '\e' is counted as space, and all spaces till the
+ * next '\e' are ignored. Multiple whitespace characters are considered
+ * to be a single argument separator.
  *
  * The source string at `str' may be undergoing concurrent alteration via
  * userspace sysctl activity (at least).  The argv_split() implementation
  * attempts to handle this gracefully by taking a local copy to work on.
  */
+
 char **argv_split(gfp_t gfp, const char *str, int *argcp)
 {
 	char *argv_str;
-	bool was_space;
+	bool was_space, in_esc;
 	char **argv, **argv_ret;
 	int argc;
 
@@ -76,8 +89,8 @@ char **argv_split(gfp_t gfp, const char *str, int *argcp)
 
 	*argv = argv_str;
 	argv_ret = ++argv;
-	for (was_space = true; *argv_str; argv_str++) {
-		if (isspace(*argv_str)) {
+	for (in_esc = false, was_space = true; *argv_str; argv_str++) {
+		if (argv_isspace(*argv_str, &in_esc)) {
 			was_space = true;
 			*argv_str = 0;
 		} else if (was_space) {
-- 
1.5.5.1



  reply	other threads:[~2013-05-13 14:39 UTC|newest]

Thread overview: 17+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-05-10  4:15 [PATCH 1/3] argv_split(): Allow extra params Lucas De Marchi
2013-05-10  4:15 ` [PATCH 2/3] kmod: Use argv_split(), passing module as extra param Lucas De Marchi
2013-05-10  4:15 ` [PATCH 3/3] init/Kconfig: Add option to set modprobe command Lucas De Marchi
2013-05-10 12:58   ` Oleg Nesterov
2013-05-10 13:12     ` Oleg Nesterov
2013-05-10 13:15     ` Lucas De Marchi
2013-05-10 15:36       ` Oleg Nesterov
2013-05-10 16:03         ` Lucas De Marchi
2013-05-10 17:10           ` Oleg Nesterov
2013-05-10 17:35             ` Oleg Nesterov
2013-05-10 17:44               ` Lucas De Marchi
2013-05-13 13:59                 ` Oleg Nesterov
2013-05-11 20:10             ` Lucas De Marchi
2013-05-13 14:16               ` Oleg Nesterov
2013-05-13 14:35                 ` Oleg Nesterov [this message]
2013-05-13 16:06                   ` [RFC] teach argv_split() to ignore the spaces surrounded by \e Colin Walters
2013-05-13 17:13                     ` Oleg Nesterov

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20130513143537.GA3278@redhat.com \
    --to=oleg@redhat.com \
    --cc=akpm@linux-foundation.org \
    --cc=andi@firstfloor.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=lucas.de.marchi@gmail.com \
    --cc=mzxreary@0pointer.de \
    --cc=nhorman@tuxdriver.com \
    --cc=rusty@rustcorp.com.au \
    --cc=vda.linux@googlemail.com \
    --cc=walters@verbum.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.