Message ID | 1391039304-3172-2-git-send-email-sebastian.capella@linaro.org (mailing list archive) |
---|---|
State | Superseded, archived |
Headers | show |
On Wed, 29 Jan 2014, Sebastian Capella wrote: > kstrimdup will duplicate and trim spaces from the passed in > null terminated string. This is useful for strings coming from > sysfs that often include trailing whitespace due to user input. > > Signed-off-by: Sebastian Capella <sebastian.capella@linaro.org> > Cc: Andrew Morton <akpm@linux-foundation.org> > Cc: Rik van Riel <riel@redhat.com> (commit_signer:5/10=50%) > Cc: Michel Lespinasse <walken@google.com> > Cc: Shaohua Li <shli@kernel.org> > Cc: Jerome Marchand <jmarchan@redhat.com> > Cc: Mikulas Patocka <mpatocka@redhat.com> > Cc: Joonsoo Kim <iamjoonsoo.kim@lge.com> > --- > include/linux/string.h | 1 + > mm/util.c | 19 +++++++++++++++++++ > 2 files changed, 20 insertions(+) > > diff --git a/include/linux/string.h b/include/linux/string.h > index ac889c5..f29f9a0 100644 > --- a/include/linux/string.h > +++ b/include/linux/string.h > @@ -114,6 +114,7 @@ void *memchr_inv(const void *s, int c, size_t n); > > extern char *kstrdup(const char *s, gfp_t gfp); > extern char *kstrndup(const char *s, size_t len, gfp_t gfp); > +extern char *kstrimdup(const char *s, gfp_t gfp); > extern void *kmemdup(const void *src, size_t len, gfp_t gfp); > > extern char **argv_split(gfp_t gfp, const char *str, int *argcp); > diff --git a/mm/util.c b/mm/util.c > index a24aa22..da17de5 100644 > --- a/mm/util.c > +++ b/mm/util.c > @@ -63,6 +63,25 @@ char *kstrndup(const char *s, size_t max, gfp_t gfp) > EXPORT_SYMBOL(kstrndup); > > /** > + * kstrimdup - Trim and copy a %NUL terminated string. > + * @s: the string to trim and duplicate > + * @gfp: the GFP mask used in the kmalloc() call when allocating memory > + * > + * Returns an address, which the caller must kfree, containing > + * a duplicate of the passed string with leading and/or trailing > + * whitespace (as defined by isspace) removed. It doesn't remove leading whitespace. To remove them, you need to do char *p = strim(ret); memmove(ret, p, strlen(p) + 1); Mikulas > + */ > +char *kstrimdup(const char *s, gfp_t gfp) > +{ > + char *ret = kstrdup(skip_spaces(s), gfp); > + > + if (ret) > + strim(ret); > + return ret; > +} > +EXPORT_SYMBOL(kstrimdup); > + > +/** > * kmemdup - duplicate region of memory > * > * @src: memory region to duplicate > -- > 1.7.9.5 > -- To unsubscribe from this list: send the line "unsubscribe linux-pm" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
On Wed, 29 Jan 2014, Mikulas Patocka wrote: > > > On Wed, 29 Jan 2014, Sebastian Capella wrote: > > > kstrimdup will duplicate and trim spaces from the passed in > > null terminated string. This is useful for strings coming from > > sysfs that often include trailing whitespace due to user input. > > > > Signed-off-by: Sebastian Capella <sebastian.capella@linaro.org> > > Cc: Andrew Morton <akpm@linux-foundation.org> > > Cc: Rik van Riel <riel@redhat.com> (commit_signer:5/10=50%) > > Cc: Michel Lespinasse <walken@google.com> > > Cc: Shaohua Li <shli@kernel.org> > > Cc: Jerome Marchand <jmarchan@redhat.com> > > Cc: Mikulas Patocka <mpatocka@redhat.com> > > Cc: Joonsoo Kim <iamjoonsoo.kim@lge.com> > > --- > > include/linux/string.h | 1 + > > mm/util.c | 19 +++++++++++++++++++ > > 2 files changed, 20 insertions(+) > > > > diff --git a/include/linux/string.h b/include/linux/string.h > > index ac889c5..f29f9a0 100644 > > --- a/include/linux/string.h > > +++ b/include/linux/string.h > > @@ -114,6 +114,7 @@ void *memchr_inv(const void *s, int c, size_t n); > > > > extern char *kstrdup(const char *s, gfp_t gfp); > > extern char *kstrndup(const char *s, size_t len, gfp_t gfp); > > +extern char *kstrimdup(const char *s, gfp_t gfp); > > extern void *kmemdup(const void *src, size_t len, gfp_t gfp); > > > > extern char **argv_split(gfp_t gfp, const char *str, int *argcp); > > diff --git a/mm/util.c b/mm/util.c > > index a24aa22..da17de5 100644 > > --- a/mm/util.c > > +++ b/mm/util.c > > @@ -63,6 +63,25 @@ char *kstrndup(const char *s, size_t max, gfp_t gfp) > > EXPORT_SYMBOL(kstrndup); > > > > /** > > + * kstrimdup - Trim and copy a %NUL terminated string. > > + * @s: the string to trim and duplicate > > + * @gfp: the GFP mask used in the kmalloc() call when allocating memory > > + * > > + * Returns an address, which the caller must kfree, containing > > + * a duplicate of the passed string with leading and/or trailing > > + * whitespace (as defined by isspace) removed. > > It doesn't remove leading whitespace. To remove them, you need to do I was wrong - I forgot about that skip_spaces in kstrdup. Mikulas > > + */ > > +char *kstrimdup(const char *s, gfp_t gfp) > > +{ > > + char *ret = kstrdup(skip_spaces(s), gfp); > > + > > + if (ret) > > + strim(ret); > > + return ret; > > +} > > +EXPORT_SYMBOL(kstrimdup); > > + > > +/** > > * kmemdup - duplicate region of memory > > * > > * @src: memory region to duplicate > > -- > > 1.7.9.5 > > > -- To unsubscribe from this list: send the line "unsubscribe linux-pm" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
On Wed, 2014-01-29 at 19:58 -0500, Mikulas Patocka wrote: > On Wed, 29 Jan 2014, Sebastian Capella wrote: > > kstrimdup will duplicate and trim spaces from the passed in > > null terminated string. This is useful for strings coming from > > sysfs that often include trailing whitespace due to user input. [] > > diff --git a/mm/util.c b/mm/util.c [] > > /** > > + * kstrimdup - Trim and copy a %NUL terminated string. > > + * @s: the string to trim and duplicate > > + * @gfp: the GFP mask used in the kmalloc() call when allocating memory > > + * > > + * Returns an address, which the caller must kfree, containing > > + * a duplicate of the passed string with leading and/or trailing > > + * whitespace (as defined by isspace) removed. > > It doesn't remove leading whitespace. To remove them, you need to do > > char *p = strim(ret); > memmove(ret, p, strlen(p) + 1); [] > > + */ > > +char *kstrimdup(const char *s, gfp_t gfp) > > +{ > > + char *ret = kstrdup(skip_spaces(s), gfp); > > + > > + if (ret) > > + strim(ret); > > + return ret; > > +} > > +EXPORT_SYMBOL(kstrimdup); Why not minimize the malloc length too? maybe something like: char *kstrimdup(const char *s, gfp_t gfp) { char *buf; const char *begin = skip_spaces(s); size_t len = strlen(begin); while (len && isspace(begin[len - 1])) len--; buf = kmalloc_track_caller(len + 1, gfp); if (!buf) return NULL; memcpy(buf, begin, len); buf[len] = 0; return buf; } -- To unsubscribe from this list: send the line "unsubscribe linux-pm" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Quoting Joe Perches (2014-01-29 17:24:28) > Why not minimize the malloc length too? > > maybe something like: > > char *kstrimdup(const char *s, gfp_t gfp) > { > char *buf; > const char *begin = skip_spaces(s); > size_t len = strlen(begin); > > while (len && isspace(begin[len - 1])) > len--; > > buf = kmalloc_track_caller(len + 1, gfp); > if (!buf) > return NULL; > > memcpy(buf, begin, len); > buf[len] = 0; > > return buf; > } I figured it would be mostly for small trimming, but it seems like it could be and advantage and used more generally this way. I have a couple of small changes to return NULL in empty string/all ws cases and fix a buffer underrun. How does this look? Thanks, Sebastian char *kstrimdup(const char *s, gfp_t gfp) { char *buf; const char *begin = skip_spaces(s); size_t len = strlen(begin); if (len == 0) return NULL; while (len > 1 && isspace(begin[len - 1])) len--; buf = kmalloc_track_caller(len + 1, gfp); if (!buf) return NULL; memcpy(buf, begin, len); buf[len] = '\0'; return buf; } -- To unsubscribe from this list: send the line "unsubscribe linux-pm" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
On Wed, 2014-01-29 at 19:41 -0800, Sebastian Capella wrote: > Quoting Joe Perches (2014-01-29 17:24:28) > > Why not minimize the malloc length too? > > > I figured it would be mostly for small trimming, but it seems like > it could be and advantage and used more generally this way. > > I have a couple of small changes to return NULL in empty string/all ws > cases and fix a buffer underrun. > > How does this look? [] > char *kstrimdup(const char *s, gfp_t gfp) > { > char *buf; > const char *begin = skip_spaces(s); > size_t len = strlen(begin); removing begin and just using s would work > if (len == 0) > return NULL; > > while (len > 1 && isspace(begin[len - 1])) > len--; > > buf = kmalloc_track_caller(len + 1, gfp); > if (!buf) > return NULL; > > memcpy(buf, begin, len); > buf[len] = '\0'; > > return buf; > } What should the return be to this string? " " Should it be "" or " " or NULL? I don't think it should be NULL. I don't think it should be " ". cheers, Joe -- To unsubscribe from this list: send the line "unsubscribe linux-pm" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
On Wed 2014-01-29 15:48:23, Sebastian Capella wrote: > kstrimdup will duplicate and trim spaces from the passed in > null terminated string. This is useful for strings coming from > sysfs that often include trailing whitespace due to user input. Is it good idea? I mean "\n\n/foo bar baz" is valid filename in unix. This is kernel interface, it is not meant to be too user friendly... Pavel > +char *kstrimdup(const char *s, gfp_t gfp) > +{ > + char *ret = kstrdup(skip_spaces(s), gfp); > + > + if (ret) > + strim(ret); > + return ret; > +} > +EXPORT_SYMBOL(kstrimdup); > + > +/** > * kmemdup - duplicate region of memory > * > * @src: memory region to duplicate
On Fri, 31 Jan 2014, Pavel Machek wrote: > > kstrimdup will duplicate and trim spaces from the passed in > > null terminated string. This is useful for strings coming from > > sysfs that often include trailing whitespace due to user input. > > Is it good idea? I mean "\n\n/foo bar baz" is valid filename in > unix. This is kernel interface, it is not meant to be too user > friendly... v6 of this patchset carries your ack of the patch that uses this for /sys/debug/resume, so are you disagreeing we need this support at all or that it shouldn't be the generic sysfs write behavior? If the latter, I agree, and the changelog could be improved to specify what writes we actually care about. -- To unsubscribe from this list: send the line "unsubscribe linux-pm" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Hi! On Fri 2014-01-31 02:46:08, David Rientjes wrote: > On Fri, 31 Jan 2014, Pavel Machek wrote: > > > > kstrimdup will duplicate and trim spaces from the passed in > > > null terminated string. This is useful for strings coming from > > > sysfs that often include trailing whitespace due to user input. > > > > Is it good idea? I mean "\n\n/foo bar baz" is valid filename in > > unix. This is kernel interface, it is not meant to be too user > > friendly... > > v6 of this patchset carries your ack of the patch that uses this for > /sys/debug/resume, so are you disagreeing we need this support at > all or /sys/power/resume, no? > that it shouldn't be the generic sysfs write behavior? If the latter, I > agree, and the changelog could be improved to specify what writes we > actually care about. Well, your /sys/power/resume patch would be nice cleanup, but it changs behaviour, too... which is unnice. Stripping trailing "\n" is probably neccessary, because we did it before. (It probably was a mistake). But kernel is not right place to second-guess what the user meant. Just return -EINVAL. This is kernel ABI, after all, not user facing shell. Pavel
Quoting Pavel Machek (2014-01-31 04:24:21) > Well, your /sys/power/resume patch would be nice cleanup, but it > changs behaviour, too... which is unnice. Stripping trailing "\n" is > probably neccessary, because we did it before. (It probably was a > mistake). But kernel is not right place to second-guess what the user > meant. Just return -EINVAL. This is kernel ABI, after all, not user > facing shell. Thanks guys! I hadn't thought of these cases. It sounds like we're really back to stripping one trailing \n to match the sysfs behavior to which people have become accustomed, and leave the rest of the string untouched in case the whitespace is intentional. Should a user intentionally have input ending in a newline, then they should add an additional newline, expecting it to be stripped, but otherwise, their string is taken as entered. Does this sound right? Meanwhile, I'll try a test to see how name_to_dev_t handles files with spaces in them. Thanks, Sebastian -- To unsubscribe from this list: send the line "unsubscribe linux-pm" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
diff --git a/include/linux/string.h b/include/linux/string.h index ac889c5..f29f9a0 100644 --- a/include/linux/string.h +++ b/include/linux/string.h @@ -114,6 +114,7 @@ void *memchr_inv(const void *s, int c, size_t n); extern char *kstrdup(const char *s, gfp_t gfp); extern char *kstrndup(const char *s, size_t len, gfp_t gfp); +extern char *kstrimdup(const char *s, gfp_t gfp); extern void *kmemdup(const void *src, size_t len, gfp_t gfp); extern char **argv_split(gfp_t gfp, const char *str, int *argcp); diff --git a/mm/util.c b/mm/util.c index a24aa22..da17de5 100644 --- a/mm/util.c +++ b/mm/util.c @@ -63,6 +63,25 @@ char *kstrndup(const char *s, size_t max, gfp_t gfp) EXPORT_SYMBOL(kstrndup); /** + * kstrimdup - Trim and copy a %NUL terminated string. + * @s: the string to trim and duplicate + * @gfp: the GFP mask used in the kmalloc() call when allocating memory + * + * Returns an address, which the caller must kfree, containing + * a duplicate of the passed string with leading and/or trailing + * whitespace (as defined by isspace) removed. + */ +char *kstrimdup(const char *s, gfp_t gfp) +{ + char *ret = kstrdup(skip_spaces(s), gfp); + + if (ret) + strim(ret); + return ret; +} +EXPORT_SYMBOL(kstrimdup); + +/** * kmemdup - duplicate region of memory * * @src: memory region to duplicate
kstrimdup will duplicate and trim spaces from the passed in null terminated string. This is useful for strings coming from sysfs that often include trailing whitespace due to user input. Signed-off-by: Sebastian Capella <sebastian.capella@linaro.org> Cc: Andrew Morton <akpm@linux-foundation.org> Cc: Rik van Riel <riel@redhat.com> (commit_signer:5/10=50%) Cc: Michel Lespinasse <walken@google.com> Cc: Shaohua Li <shli@kernel.org> Cc: Jerome Marchand <jmarchan@redhat.com> Cc: Mikulas Patocka <mpatocka@redhat.com> Cc: Joonsoo Kim <iamjoonsoo.kim@lge.com> --- include/linux/string.h | 1 + mm/util.c | 19 +++++++++++++++++++ 2 files changed, 20 insertions(+)