2005-04-17 05:20:36 +07:00
|
|
|
#ifndef _LINUX_STRING_H_
|
|
|
|
#define _LINUX_STRING_H_
|
|
|
|
|
|
|
|
|
|
|
|
#include <linux/compiler.h> /* for inline */
|
|
|
|
#include <linux/types.h> /* for size_t */
|
|
|
|
#include <linux/stddef.h> /* for NULL */
|
2009-03-06 23:21:46 +07:00
|
|
|
#include <stdarg.h>
|
2012-10-13 16:46:48 +07:00
|
|
|
#include <uapi/linux/string.h>
|
2005-04-17 05:20:36 +07:00
|
|
|
|
2006-03-24 18:18:42 +07:00
|
|
|
extern char *strndup_user(const char __user *, long);
|
2009-04-01 05:23:16 +07:00
|
|
|
extern void *memdup_user(const void __user *, size_t);
|
2006-03-24 18:18:42 +07:00
|
|
|
|
2005-04-17 05:20:36 +07:00
|
|
|
/*
|
|
|
|
* Include machine specific inline routines
|
|
|
|
*/
|
|
|
|
#include <asm/string.h>
|
|
|
|
|
|
|
|
#ifndef __HAVE_ARCH_STRCPY
|
|
|
|
extern char * strcpy(char *,const char *);
|
|
|
|
#endif
|
|
|
|
#ifndef __HAVE_ARCH_STRNCPY
|
|
|
|
extern char * strncpy(char *,const char *, __kernel_size_t);
|
|
|
|
#endif
|
|
|
|
#ifndef __HAVE_ARCH_STRLCPY
|
|
|
|
size_t strlcpy(char *, const char *, size_t);
|
|
|
|
#endif
|
|
|
|
#ifndef __HAVE_ARCH_STRCAT
|
|
|
|
extern char * strcat(char *, const char *);
|
|
|
|
#endif
|
|
|
|
#ifndef __HAVE_ARCH_STRNCAT
|
|
|
|
extern char * strncat(char *, const char *, __kernel_size_t);
|
|
|
|
#endif
|
|
|
|
#ifndef __HAVE_ARCH_STRLCAT
|
|
|
|
extern size_t strlcat(char *, const char *, __kernel_size_t);
|
|
|
|
#endif
|
|
|
|
#ifndef __HAVE_ARCH_STRCMP
|
|
|
|
extern int strcmp(const char *,const char *);
|
|
|
|
#endif
|
|
|
|
#ifndef __HAVE_ARCH_STRNCMP
|
|
|
|
extern int strncmp(const char *,const char *,__kernel_size_t);
|
|
|
|
#endif
|
|
|
|
#ifndef __HAVE_ARCH_STRNICMP
|
2014-10-14 05:54:27 +07:00
|
|
|
#define strnicmp strncasecmp
|
2005-04-17 05:20:36 +07:00
|
|
|
#endif
|
2007-03-29 15:18:42 +07:00
|
|
|
#ifndef __HAVE_ARCH_STRCASECMP
|
|
|
|
extern int strcasecmp(const char *s1, const char *s2);
|
|
|
|
#endif
|
|
|
|
#ifndef __HAVE_ARCH_STRNCASECMP
|
|
|
|
extern int strncasecmp(const char *s1, const char *s2, size_t n);
|
|
|
|
#endif
|
2005-04-17 05:20:36 +07:00
|
|
|
#ifndef __HAVE_ARCH_STRCHR
|
|
|
|
extern char * strchr(const char *,int);
|
|
|
|
#endif
|
2014-03-15 00:00:14 +07:00
|
|
|
#ifndef __HAVE_ARCH_STRCHRNUL
|
|
|
|
extern char * strchrnul(const char *,int);
|
|
|
|
#endif
|
2005-04-17 05:20:36 +07:00
|
|
|
#ifndef __HAVE_ARCH_STRNCHR
|
|
|
|
extern char * strnchr(const char *, size_t, int);
|
|
|
|
#endif
|
|
|
|
#ifndef __HAVE_ARCH_STRRCHR
|
|
|
|
extern char * strrchr(const char *,int);
|
|
|
|
#endif
|
2009-12-15 09:01:04 +07:00
|
|
|
extern char * __must_check skip_spaces(const char *);
|
2009-12-15 09:01:15 +07:00
|
|
|
|
|
|
|
extern char *strim(char *);
|
|
|
|
|
|
|
|
static inline __must_check char *strstrip(char *str)
|
|
|
|
{
|
|
|
|
return strim(str);
|
|
|
|
}
|
|
|
|
|
2005-04-17 05:20:36 +07:00
|
|
|
#ifndef __HAVE_ARCH_STRSTR
|
2010-01-14 09:53:55 +07:00
|
|
|
extern char * strstr(const char *, const char *);
|
|
|
|
#endif
|
|
|
|
#ifndef __HAVE_ARCH_STRNSTR
|
|
|
|
extern char * strnstr(const char *, const char *, size_t);
|
2005-04-17 05:20:36 +07:00
|
|
|
#endif
|
|
|
|
#ifndef __HAVE_ARCH_STRLEN
|
|
|
|
extern __kernel_size_t strlen(const char *);
|
|
|
|
#endif
|
|
|
|
#ifndef __HAVE_ARCH_STRNLEN
|
|
|
|
extern __kernel_size_t strnlen(const char *,__kernel_size_t);
|
|
|
|
#endif
|
2006-04-11 12:53:57 +07:00
|
|
|
#ifndef __HAVE_ARCH_STRPBRK
|
|
|
|
extern char * strpbrk(const char *,const char *);
|
|
|
|
#endif
|
|
|
|
#ifndef __HAVE_ARCH_STRSEP
|
|
|
|
extern char * strsep(char **,const char *);
|
|
|
|
#endif
|
|
|
|
#ifndef __HAVE_ARCH_STRSPN
|
|
|
|
extern __kernel_size_t strspn(const char *,const char *);
|
|
|
|
#endif
|
|
|
|
#ifndef __HAVE_ARCH_STRCSPN
|
|
|
|
extern __kernel_size_t strcspn(const char *,const char *);
|
|
|
|
#endif
|
2005-04-17 05:20:36 +07:00
|
|
|
|
|
|
|
#ifndef __HAVE_ARCH_MEMSET
|
|
|
|
extern void * memset(void *,int,__kernel_size_t);
|
|
|
|
#endif
|
|
|
|
#ifndef __HAVE_ARCH_MEMCPY
|
|
|
|
extern void * memcpy(void *,const void *,__kernel_size_t);
|
|
|
|
#endif
|
|
|
|
#ifndef __HAVE_ARCH_MEMMOVE
|
|
|
|
extern void * memmove(void *,const void *,__kernel_size_t);
|
|
|
|
#endif
|
|
|
|
#ifndef __HAVE_ARCH_MEMSCAN
|
|
|
|
extern void * memscan(void *,int,__kernel_size_t);
|
|
|
|
#endif
|
|
|
|
#ifndef __HAVE_ARCH_MEMCMP
|
|
|
|
extern int memcmp(const void *,const void *,__kernel_size_t);
|
|
|
|
#endif
|
|
|
|
#ifndef __HAVE_ARCH_MEMCHR
|
|
|
|
extern void * memchr(const void *,int,__kernel_size_t);
|
|
|
|
#endif
|
2011-11-01 07:08:07 +07:00
|
|
|
void *memchr_inv(const void *s, int c, size_t n);
|
2005-04-17 05:20:36 +07:00
|
|
|
|
2005-10-07 13:46:04 +07:00
|
|
|
extern char *kstrdup(const char *s, gfp_t gfp);
|
2007-07-18 08:37:02 +07:00
|
|
|
extern char *kstrndup(const char *s, size_t len, gfp_t gfp);
|
[PATCH] kmemdup: introduce
One of idiomatic ways to duplicate a region of memory is
dst = kmalloc(len, GFP_KERNEL);
if (!dst)
return -ENOMEM;
memcpy(dst, src, len);
which is neat code except a programmer needs to write size twice. Which
sometimes leads to mistakes. If len passed to kmalloc is smaller that len
passed to memcpy, it's straight overwrite-beyond-end. If len passed to
memcpy is smaller than len passed to kmalloc, it's either a) legit
behaviour ;-), or b) cloned buffer will contain garbage in second half.
Slight trolling of commit lists shows several duplications bugs
done exactly because of diverged lenghts:
Linux:
[CRYPTO]: Fix memcpy/memset args.
[PATCH] memcpy/memset fixes
OpenBSD:
kerberosV/src/lib/asn1: der_copy.c:1.4
If programmer is given only one place to play with lengths, I believe, such
mistakes could be avoided.
With kmemdup, the snippet above will be rewritten as:
dst = kmemdup(src, len, GFP_KERNEL);
if (!dst)
return -ENOMEM;
This also leads to smaller code (kzalloc effect). Quick grep shows
200+ places where kmemdup() can be used.
Signed-off-by: Alexey Dobriyan <adobriyan@gmail.com>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-10-01 13:27:20 +07:00
|
|
|
extern void *kmemdup(const void *src, size_t len, gfp_t gfp);
|
2005-06-23 14:09:02 +07:00
|
|
|
|
2007-07-18 08:37:02 +07:00
|
|
|
extern char **argv_split(gfp_t gfp, const char *str, int *argcp);
|
|
|
|
extern void argv_free(char **argv);
|
|
|
|
|
2008-05-01 18:34:42 +07:00
|
|
|
extern bool sysfs_streq(const char *s1, const char *s2);
|
2011-04-19 18:43:45 +07:00
|
|
|
extern int strtobool(const char *s, bool *res);
|
2008-05-01 18:34:42 +07:00
|
|
|
|
2009-03-06 23:21:46 +07:00
|
|
|
#ifdef CONFIG_BINARY_PRINTF
|
|
|
|
int vbin_printf(u32 *bin_buf, size_t size, const char *fmt, va_list args);
|
|
|
|
int bstr_printf(char *buf, size_t size, const char *fmt, const u32 *bin_buf);
|
|
|
|
int bprintf(u32 *bin_buf, size_t size, const char *fmt, ...) __printf(3, 4);
|
|
|
|
#endif
|
|
|
|
|
2008-07-24 11:26:44 +07:00
|
|
|
extern ssize_t memory_read_from_buffer(void *to, size_t count, loff_t *ppos,
|
2014-08-27 10:16:35 +07:00
|
|
|
const void *from, size_t available);
|
2008-07-24 11:26:44 +07:00
|
|
|
|
2009-04-01 02:05:36 +07:00
|
|
|
/**
|
|
|
|
* strstarts - does @str start with @prefix?
|
|
|
|
* @str: string to examine
|
|
|
|
* @prefix: prefix to look for.
|
|
|
|
*/
|
|
|
|
static inline bool strstarts(const char *str, const char *prefix)
|
|
|
|
{
|
|
|
|
return strncmp(str, prefix, strlen(prefix)) == 0;
|
|
|
|
}
|
2012-07-31 04:40:55 +07:00
|
|
|
|
2014-08-27 10:16:35 +07:00
|
|
|
size_t memweight(const void *ptr, size_t bytes);
|
|
|
|
void memzero_explicit(void *s, size_t count);
|
2012-07-31 04:40:55 +07:00
|
|
|
|
2012-12-18 07:01:18 +07:00
|
|
|
/**
|
|
|
|
* kbasename - return the last part of a pathname.
|
|
|
|
*
|
|
|
|
* @path: path to extract the filename from.
|
|
|
|
*/
|
|
|
|
static inline const char *kbasename(const char *path)
|
|
|
|
{
|
|
|
|
const char *tail = strrchr(path, '/');
|
|
|
|
return tail ? tail + 1 : path;
|
|
|
|
}
|
|
|
|
|
2005-04-17 05:20:36 +07:00
|
|
|
#endif /* _LINUX_STRING_H_ */
|