| 
									
										
										
										
											2005-04-16 15: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 17:21:46 +01:00
										 |  |  | #include <stdarg.h>
 | 
					
						
							| 
									
										
										
										
											2012-10-13 10:46:48 +01:00
										 |  |  | #include <uapi/linux/string.h>
 | 
					
						
							| 
									
										
										
										
											2005-04-16 15:20:36 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-03-24 03:18:42 -08:00
										 |  |  | extern char *strndup_user(const char __user *, long); | 
					
						
							| 
									
										
										
										
											2009-03-31 15:23:16 -07:00
										 |  |  | extern void *memdup_user(const void __user *, size_t); | 
					
						
							| 
									
										
										
										
											2006-03-24 03:18:42 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-04-16 15: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
 | 
					
						
							|  |  |  | extern int strnicmp(const char *, const char *, __kernel_size_t); | 
					
						
							|  |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2007-03-29 01: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-16 15:20:36 -07:00
										 |  |  | #ifndef __HAVE_ARCH_STRCHR
 | 
					
						
							|  |  |  | extern char * strchr(const char *,int); | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | #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-14 18:01:04 -08:00
										 |  |  | extern char * __must_check skip_spaces(const char *); | 
					
						
							| 
									
										
										
										
											2009-12-14 18:01:15 -08:00
										 |  |  | 
 | 
					
						
							|  |  |  | extern char *strim(char *); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static inline __must_check char *strstrip(char *str) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	return strim(str); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-04-16 15:20:36 -07:00
										 |  |  | #ifndef __HAVE_ARCH_STRSTR
 | 
					
						
							| 
									
										
										
										
											2010-01-14 10:53:55 +08:00
										 |  |  | extern char * strstr(const char *, const char *); | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | #ifndef __HAVE_ARCH_STRNSTR
 | 
					
						
							|  |  |  | extern char * strnstr(const char *, const char *, size_t); | 
					
						
							| 
									
										
										
										
											2005-04-16 15: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-10 22: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-16 15: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-10-31 17:08:07 -07:00
										 |  |  | void *memchr_inv(const void *s, int c, size_t n); | 
					
						
							| 
									
										
										
										
											2005-04-16 15:20:36 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-10-07 07:46:04 +01:00
										 |  |  | extern char *kstrdup(const char *s, gfp_t gfp); | 
					
						
							| 
									
										
										
										
											2007-07-17 18: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-09-30 23:27:20 -07:00
										 |  |  | extern void *kmemdup(const void *src, size_t len, gfp_t gfp); | 
					
						
							| 
									
										
										
										
											2005-06-23 00:09:02 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-07-17 18: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 04:34:42 -07:00
										 |  |  | extern bool sysfs_streq(const char *s1, const char *s2); | 
					
						
							| 
									
										
										
										
											2011-04-19 12:43:45 +01:00
										 |  |  | extern int strtobool(const char *s, bool *res); | 
					
						
							| 
									
										
										
										
											2008-05-01 04:34:42 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-03-06 17:21:46 +01: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-23 21:26:44 -07:00
										 |  |  | extern ssize_t memory_read_from_buffer(void *to, size_t count, loff_t *ppos, | 
					
						
							|  |  |  | 			const void *from, size_t available); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-03-31 13:05:36 -06: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-30 14:40:55 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | extern size_t memweight(const void *ptr, size_t bytes); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-12-17 16:01:18 -08: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-16 15:20:36 -07:00
										 |  |  | #endif /* _LINUX_STRING_H_ */
 |