# define strndup sandbox_strndup
#endif
- #ifndef __HAVE_ARCH_STRDUP
extern char * strdup(const char *);
extern char * strndup(const char *, size_t);
- #endif
+
+extern const char *strdup_const(const char *s);
+extern void kfree_const(const void *x);
++
#ifndef __HAVE_ARCH_STRSWAB
extern char * strswab(const char *);
#endif
}
#endif
- #ifndef __HAVE_ARCH_STRDUP
- char * strdup(const char *s)
+ void *memdup_nul(const void *src, size_t len)
{
- char *new;
+ char *dst;
- if ((s == NULL) ||
- ((new = malloc (strlen(s) + 1)) == NULL) ) {
+ if (len + 1 < len)
return NULL;
- }
- strcpy (new, s);
- return new;
- }
-
- char * strndup(const char *s, size_t n)
- {
- size_t len;
- char *new;
-
- if (s == NULL)
+ dst = malloc(len + 1);
+ if (!dst)
return NULL;
- len = strlen(s);
-
- if (n < len)
- len = n;
-
- new = malloc(len + 1);
- if (new == NULL)
- return NULL;
+ dst[len] = '\0';
+ return memcpy(dst, src, len);
+ }
- strncpy(new, s, len);
- new[len] = '\0';
+ char * strdup(const char *s)
+ {
+ return s ? memdup_nul(s, strlen(s)) : NULL;
+ }
- return new;
+ char * strndup(const char *s, size_t n)
+ {
+ return s ? memdup_nul(s, strnlen(s, n)) : NULL;
}
- #endif
+/**
+ * strdup_const - conditionally duplicate an existing const string
+ * @s: the string to duplicate
+ *
+ * Note: Strings allocated by kstrdup_const should be freed by kfree_const and
+ * must not be passed to krealloc().
+ *
+ * Return: source string if it is in .rodata section otherwise
+ * fallback to kstrdup.
+ */
+const char *strdup_const(const char *s)
+{
+ if (is_kernel_rodata((unsigned long)s))
+ return s;
+
+ return strdup(s);
+}
+
+/**
+ * kfree_const - conditionally free memory
+ * @x: pointer to the memory
+ *
+ * Function calls kfree only if @x is not in .rodata section.
+ */
+void kfree_const(const void *x)
+{
+ if (!is_kernel_rodata((unsigned long)x))
+ free((void *)x);
+}
+
+
#ifndef __HAVE_ARCH_STRSPN
/**
* strspn - Calculate the length of the initial substring of @s which only