aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Howells <dhowells@redhat.com>2017-07-04 12:25:02 -0400
committerAl Viro <viro@zeniv.linux.org.uk>2017-07-06 03:27:09 -0400
commitf35157417215ec138c920320c746fdb3e04ef1d5 (patch)
tree5d8e536fc716419fe3b9474dcacb92c6f055930f
parentc0bc126f97fb929b3ae02c1c62322645d70eb408 (diff)
Provide a function to create a NUL-terminated string from unterminated data
Provide a function, kmemdup_nul(), that will create a NUL-terminated string from an unterminated character array where the length is known in advance. This is better than kstrndup() in situations where we already know the string length as the strnlen() in kstrndup() is superfluous. Signed-off-by: David Howells <dhowells@redhat.com> Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
-rw-r--r--include/linux/string.h1
-rw-r--r--mm/util.c24
2 files changed, 25 insertions, 0 deletions
diff --git a/include/linux/string.h b/include/linux/string.h
index 537918f8a98e..3dd944cfe171 100644
--- a/include/linux/string.h
+++ b/include/linux/string.h
@@ -131,6 +131,7 @@ extern char *kstrdup(const char *s, gfp_t gfp) __malloc;
131extern const char *kstrdup_const(const char *s, gfp_t gfp); 131extern const char *kstrdup_const(const char *s, gfp_t gfp);
132extern char *kstrndup(const char *s, size_t len, gfp_t gfp); 132extern char *kstrndup(const char *s, size_t len, gfp_t gfp);
133extern void *kmemdup(const void *src, size_t len, gfp_t gfp); 133extern void *kmemdup(const void *src, size_t len, gfp_t gfp);
134extern char *kmemdup_nul(const char *s, size_t len, gfp_t gfp);
134 135
135extern char **argv_split(gfp_t gfp, const char *str, int *argcp); 136extern char **argv_split(gfp_t gfp, const char *str, int *argcp);
136extern void argv_free(char **argv); 137extern void argv_free(char **argv);
diff --git a/mm/util.c b/mm/util.c
index 26be6407abd7..21ddf90f883d 100644
--- a/mm/util.c
+++ b/mm/util.c
@@ -83,6 +83,8 @@ EXPORT_SYMBOL(kstrdup_const);
83 * @s: the string to duplicate 83 * @s: the string to duplicate
84 * @max: read at most @max chars from @s 84 * @max: read at most @max chars from @s
85 * @gfp: the GFP mask used in the kmalloc() call when allocating memory 85 * @gfp: the GFP mask used in the kmalloc() call when allocating memory
86 *
87 * Note: Use kmemdup_nul() instead if the size is known exactly.
86 */ 88 */
87char *kstrndup(const char *s, size_t max, gfp_t gfp) 89char *kstrndup(const char *s, size_t max, gfp_t gfp)
88{ 90{
@@ -121,6 +123,28 @@ void *kmemdup(const void *src, size_t len, gfp_t gfp)
121EXPORT_SYMBOL(kmemdup); 123EXPORT_SYMBOL(kmemdup);
122 124
123/** 125/**
126 * kmemdup_nul - Create a NUL-terminated string from unterminated data
127 * @s: The data to stringify
128 * @len: The size of the data
129 * @gfp: the GFP mask used in the kmalloc() call when allocating memory
130 */
131char *kmemdup_nul(const char *s, size_t len, gfp_t gfp)
132{
133 char *buf;
134
135 if (!s)
136 return NULL;
137
138 buf = kmalloc_track_caller(len + 1, gfp);
139 if (buf) {
140 memcpy(buf, s, len);
141 buf[len] = '\0';
142 }
143 return buf;
144}
145EXPORT_SYMBOL(kmemdup_nul);
146
147/**
124 * memdup_user - duplicate memory region from user space 148 * memdup_user - duplicate memory region from user space
125 * 149 *
126 * @src: source address in user space 150 * @src: source address in user space