string.c 23.5 KB
Newer Older
1
// SPDX-License-Identifier: GPL-2.0
Linus Torvalds's avatar
Linus Torvalds committed
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
/*
 *  linux/lib/string.c
 *
 *  Copyright (C) 1991, 1992  Linus Torvalds
 */

/*
 * stupid library routines.. The optimized versions should generally be found
 * as inline code in <asm-xx/string.h>
 *
 * These are buggy as well..
 *
 * * Fri Jun 25 1999, Ingo Oeser <ioe@informatik.tu-chemnitz.de>
 * -  Added strsep() which will replace strtok() soon (because strsep() is
 *    reentrant and should be faster). Use only strsep() in new code, please.
 *
 * * Sat Feb 09 2002, Jason Thomas <jason@topic.com.au>,
 *                    Matthew Hawkins <matt@mh.dropbear.id.au>
 * -  Kissed strtok() goodbye
 */

#include <linux/types.h>
#include <linux/string.h>
#include <linux/ctype.h>
26 27
#include <linux/kernel.h>
#include <linux/export.h>
28
#include <linux/bug.h>
29
#include <linux/errno.h>
30
#include <linux/slab.h>
Linus Torvalds's avatar
Linus Torvalds committed
31

Chris Metcalf's avatar
Chris Metcalf committed
32 33 34 35
#include <asm/byteorder.h>
#include <asm/word-at-a-time.h>
#include <asm/page.h>

36
#ifndef __HAVE_ARCH_STRNCASECMP
Linus Torvalds's avatar
Linus Torvalds committed
37
/**
38
 * strncasecmp - Case insensitive, length-limited string comparison
Linus Torvalds's avatar
Linus Torvalds committed
39 40 41 42
 * @s1: One string
 * @s2: The other string
 * @len: the maximum number of characters to compare
 */
43
int strncasecmp(const char *s1, const char *s2, size_t len)
Linus Torvalds's avatar
Linus Torvalds committed
44 45 46 47
{
	/* Yes, Virginia, it had better be unsigned */
	unsigned char c1, c2;

48 49 50 51 52 53 54 55 56 57 58 59 60 61 62
	if (!len)
		return 0;

	do {
		c1 = *s1++;
		c2 = *s2++;
		if (!c1 || !c2)
			break;
		if (c1 == c2)
			continue;
		c1 = tolower(c1);
		c2 = tolower(c2);
		if (c1 != c2)
			break;
	} while (--len);
Linus Torvalds's avatar
Linus Torvalds committed
63 64
	return (int)c1 - (int)c2;
}
65 66
EXPORT_SYMBOL(strncasecmp);
#endif
Linus Torvalds's avatar
Linus Torvalds committed
67

68 69 70 71 72 73 74 75 76 77 78 79 80 81
#ifndef __HAVE_ARCH_STRCASECMP
int strcasecmp(const char *s1, const char *s2)
{
	int c1, c2;

	do {
		c1 = tolower(*s1++);
		c2 = tolower(*s2++);
	} while (c1 == c2 && c1 != 0);
	return c1 - c2;
}
EXPORT_SYMBOL(strcasecmp);
#endif

Linus Torvalds's avatar
Linus Torvalds committed
82 83 84 85 86 87
#ifndef __HAVE_ARCH_STRCPY
/**
 * strcpy - Copy a %NUL terminated string
 * @dest: Where to copy the string to
 * @src: Where to copy the string from
 */
88
#undef strcpy
89
char *strcpy(char *dest, const char *src)
Linus Torvalds's avatar
Linus Torvalds committed
90 91 92 93 94 95 96 97 98 99 100 101
{
	char *tmp = dest;

	while ((*dest++ = *src++) != '\0')
		/* nothing */;
	return tmp;
}
EXPORT_SYMBOL(strcpy);
#endif

#ifndef __HAVE_ARCH_STRNCPY
/**
102
 * strncpy - Copy a length-limited, C-string
Linus Torvalds's avatar
Linus Torvalds committed
103 104 105 106 107 108
 * @dest: Where to copy the string to
 * @src: Where to copy the string from
 * @count: The maximum number of bytes to copy
 *
 * The result is not %NUL-terminated if the source exceeds
 * @count bytes.
109 110 111 112
 *
 * In the case where the length of @src is less than  that  of
 * count, the remainder of @dest will be padded with %NUL.
 *
Linus Torvalds's avatar
Linus Torvalds committed
113
 */
114
char *strncpy(char *dest, const char *src, size_t count)
Linus Torvalds's avatar
Linus Torvalds committed
115 116 117 118
{
	char *tmp = dest;

	while (count) {
119 120
		if ((*tmp = *src) != 0)
			src++;
Linus Torvalds's avatar
Linus Torvalds committed
121 122 123 124 125 126 127 128 129 130
		tmp++;
		count--;
	}
	return dest;
}
EXPORT_SYMBOL(strncpy);
#endif

#ifndef __HAVE_ARCH_STRLCPY
/**
131
 * strlcpy - Copy a C-string into a sized buffer
Linus Torvalds's avatar
Linus Torvalds committed
132 133 134 135
 * @dest: Where to copy the string to
 * @src: Where to copy the string from
 * @size: size of destination buffer
 *
136
 * Compatible with ``*BSD``: the result is always a valid
Linus Torvalds's avatar
Linus Torvalds committed
137 138 139 140 141 142 143 144 145
 * NUL-terminated string that fits in the buffer (unless,
 * of course, the buffer size is zero). It does not pad
 * out the result like strncpy() does.
 */
size_t strlcpy(char *dest, const char *src, size_t size)
{
	size_t ret = strlen(src);

	if (size) {
146
		size_t len = (ret >= size) ? size - 1 : ret;
Linus Torvalds's avatar
Linus Torvalds committed
147 148 149 150 151 152 153 154
		memcpy(dest, src, len);
		dest[len] = '\0';
	}
	return ret;
}
EXPORT_SYMBOL(strlcpy);
#endif

Chris Metcalf's avatar
Chris Metcalf committed
155 156 157 158 159 160 161
#ifndef __HAVE_ARCH_STRSCPY
/**
 * strscpy - Copy a C-string into a sized buffer
 * @dest: Where to copy the string to
 * @src: Where to copy the string from
 * @count: Size of destination buffer
 *
162 163 164
 * Copy the string, or as much of it as fits, into the dest buffer.  The
 * behavior is undefined if the string buffers overlap.  The destination
 * buffer is always NUL terminated, unless it's zero-sized.
Chris Metcalf's avatar
Chris Metcalf committed
165 166 167 168 169 170 171 172 173
 *
 * Preferred to strlcpy() since the API doesn't require reading memory
 * from the src string beyond the specified "count" bytes, and since
 * the return value is easier to error-check than strlcpy()'s.
 * In addition, the implementation is robust to the string changing out
 * from underneath it, unlike the current strlcpy() implementation.
 *
 * Preferred to strncpy() since it always returns a valid string, and
 * doesn't unnecessarily force the tail of the destination buffer to be
174 175
 * zeroed.  If zeroing is desired please use strscpy_pad().
 *
176 177 178
 * Returns:
 * * The number of characters copied (not including the trailing %NUL)
 * * -E2BIG if count is 0 or @src was truncated.
Chris Metcalf's avatar
Chris Metcalf committed
179 180 181 182 183 184 185
 */
ssize_t strscpy(char *dest, const char *src, size_t count)
{
	const struct word_at_a_time constants = WORD_AT_A_TIME_CONSTANTS;
	size_t max = count;
	long res = 0;

186
	if (count == 0 || WARN_ON_ONCE(count > INT_MAX))
Chris Metcalf's avatar
Chris Metcalf committed
187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207
		return -E2BIG;

#ifdef CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS
	/*
	 * If src is unaligned, don't cross a page boundary,
	 * since we don't know if the next page is mapped.
	 */
	if ((long)src & (sizeof(long) - 1)) {
		size_t limit = PAGE_SIZE - ((long)src & (PAGE_SIZE - 1));
		if (limit < max)
			max = limit;
	}
#else
	/* If src or dest is unaligned, don't do word-at-a-time. */
	if (((long) dest | (long) src) & (sizeof(long) - 1))
		max = 0;
#endif

	while (max >= sizeof(unsigned long)) {
		unsigned long c, data;

208
		c = read_word_at_a_time(src+res);
Chris Metcalf's avatar
Chris Metcalf committed
209 210 211
		if (has_zero(c, &data, &constants)) {
			data = prep_zero_mask(c, data, &constants);
			data = create_zero_mask(data);
212
			*(unsigned long *)(dest+res) = c & zero_bytemask(data);
Chris Metcalf's avatar
Chris Metcalf committed
213 214
			return res + find_zero(data);
		}
215
		*(unsigned long *)(dest+res) = c;
Chris Metcalf's avatar
Chris Metcalf committed
216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240
		res += sizeof(unsigned long);
		count -= sizeof(unsigned long);
		max -= sizeof(unsigned long);
	}

	while (count) {
		char c;

		c = src[res];
		dest[res] = c;
		if (!c)
			return res;
		res++;
		count--;
	}

	/* Hit buffer length without finding a NUL; force NUL-termination. */
	if (res)
		dest[res-1] = '\0';

	return -E2BIG;
}
EXPORT_SYMBOL(strscpy);
#endif

241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256
/**
 * strscpy_pad() - Copy a C-string into a sized buffer
 * @dest: Where to copy the string to
 * @src: Where to copy the string from
 * @count: Size of destination buffer
 *
 * Copy the string, or as much of it as fits, into the dest buffer.  The
 * behavior is undefined if the string buffers overlap.  The destination
 * buffer is always %NUL terminated, unless it's zero-sized.
 *
 * If the source string is shorter than the destination buffer, zeros
 * the tail of the destination buffer.
 *
 * For full explanation of why you may want to consider using the
 * 'strscpy' functions please see the function docstring for strscpy().
 *
257 258 259
 * Returns:
 * * The number of characters copied (not including the trailing %NUL)
 * * -E2BIG if count is 0 or @src was truncated.
260 261 262 263 264 265 266 267 268 269 270 271 272 273 274
 */
ssize_t strscpy_pad(char *dest, const char *src, size_t count)
{
	ssize_t written;

	written = strscpy(dest, src, count);
	if (written < 0 || written == count - 1)
		return written;

	memset(dest + written + 1, 0, count - written - 1);

	return written;
}
EXPORT_SYMBOL(strscpy_pad);

Linus Torvalds's avatar
Linus Torvalds committed
275 276 277 278 279 280
#ifndef __HAVE_ARCH_STRCAT
/**
 * strcat - Append one %NUL-terminated string to another
 * @dest: The string to be appended to
 * @src: The string to append to it
 */
281
#undef strcat
282
char *strcat(char *dest, const char *src)
Linus Torvalds's avatar
Linus Torvalds committed
283 284 285 286 287 288 289 290 291 292 293 294 295 296
{
	char *tmp = dest;

	while (*dest)
		dest++;
	while ((*dest++ = *src++) != '\0')
		;
	return tmp;
}
EXPORT_SYMBOL(strcat);
#endif

#ifndef __HAVE_ARCH_STRNCAT
/**
297
 * strncat - Append a length-limited, C-string to another
Linus Torvalds's avatar
Linus Torvalds committed
298 299 300 301
 * @dest: The string to be appended to
 * @src: The string to append to it
 * @count: The maximum numbers of bytes to copy
 *
302
 * Note that in contrast to strncpy(), strncat() ensures the result is
Linus Torvalds's avatar
Linus Torvalds committed
303 304
 * terminated.
 */
305
char *strncat(char *dest, const char *src, size_t count)
Linus Torvalds's avatar
Linus Torvalds committed
306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325
{
	char *tmp = dest;

	if (count) {
		while (*dest)
			dest++;
		while ((*dest++ = *src++) != 0) {
			if (--count == 0) {
				*dest = '\0';
				break;
			}
		}
	}
	return tmp;
}
EXPORT_SYMBOL(strncat);
#endif

#ifndef __HAVE_ARCH_STRLCAT
/**
326
 * strlcat - Append a length-limited, C-string to another
Linus Torvalds's avatar
Linus Torvalds committed
327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356
 * @dest: The string to be appended to
 * @src: The string to append to it
 * @count: The size of the destination buffer.
 */
size_t strlcat(char *dest, const char *src, size_t count)
{
	size_t dsize = strlen(dest);
	size_t len = strlen(src);
	size_t res = dsize + len;

	/* This would be a bug */
	BUG_ON(dsize >= count);

	dest += dsize;
	count -= dsize;
	if (len >= count)
		len = count-1;
	memcpy(dest, src, len);
	dest[len] = 0;
	return res;
}
EXPORT_SYMBOL(strlcat);
#endif

#ifndef __HAVE_ARCH_STRCMP
/**
 * strcmp - Compare two strings
 * @cs: One string
 * @ct: Another string
 */
357
#undef strcmp
358
int strcmp(const char *cs, const char *ct)
Linus Torvalds's avatar
Linus Torvalds committed
359
{
360
	unsigned char c1, c2;
Linus Torvalds's avatar
Linus Torvalds committed
361 362

	while (1) {
363 364 365 366 367
		c1 = *cs++;
		c2 = *ct++;
		if (c1 != c2)
			return c1 < c2 ? -1 : 1;
		if (!c1)
Linus Torvalds's avatar
Linus Torvalds committed
368 369
			break;
	}
370
	return 0;
Linus Torvalds's avatar
Linus Torvalds committed
371 372 373 374 375 376 377 378 379 380 381
}
EXPORT_SYMBOL(strcmp);
#endif

#ifndef __HAVE_ARCH_STRNCMP
/**
 * strncmp - Compare two length-limited strings
 * @cs: One string
 * @ct: Another string
 * @count: The maximum number of bytes to compare
 */
382
int strncmp(const char *cs, const char *ct, size_t count)
Linus Torvalds's avatar
Linus Torvalds committed
383
{
384
	unsigned char c1, c2;
Linus Torvalds's avatar
Linus Torvalds committed
385 386

	while (count) {
387 388 389 390 391
		c1 = *cs++;
		c2 = *ct++;
		if (c1 != c2)
			return c1 < c2 ? -1 : 1;
		if (!c1)
Linus Torvalds's avatar
Linus Torvalds committed
392 393 394
			break;
		count--;
	}
395
	return 0;
Linus Torvalds's avatar
Linus Torvalds committed
396 397 398 399 400 401 402 403 404
}
EXPORT_SYMBOL(strncmp);
#endif

#ifndef __HAVE_ARCH_STRCHR
/**
 * strchr - Find the first occurrence of a character in a string
 * @s: The string to be searched
 * @c: The character to search for
405 406 407
 *
 * Note that the %NUL-terminator is considered part of the string, and can
 * be searched for.
Linus Torvalds's avatar
Linus Torvalds committed
408
 */
409
char *strchr(const char *s, int c)
Linus Torvalds's avatar
Linus Torvalds committed
410
{
411
	for (; *s != (char)c; ++s)
Linus Torvalds's avatar
Linus Torvalds committed
412 413
		if (*s == '\0')
			return NULL;
414
	return (char *)s;
Linus Torvalds's avatar
Linus Torvalds committed
415 416 417 418
}
EXPORT_SYMBOL(strchr);
#endif

419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436
#ifndef __HAVE_ARCH_STRCHRNUL
/**
 * strchrnul - Find and return a character in a string, or end of string
 * @s: The string to be searched
 * @c: The character to search for
 *
 * Returns pointer to first occurrence of 'c' in s. If c is not found, then
 * return a pointer to the null byte at the end of s.
 */
char *strchrnul(const char *s, int c)
{
	while (*s && *s != (char)c)
		s++;
	return (char *)s;
}
EXPORT_SYMBOL(strchrnul);
#endif

Linus Torvalds's avatar
Linus Torvalds committed
437 438 439 440 441 442
#ifndef __HAVE_ARCH_STRRCHR
/**
 * strrchr - Find the last occurrence of a character in a string
 * @s: The string to be searched
 * @c: The character to search for
 */
443
char *strrchr(const char *s, int c)
Linus Torvalds's avatar
Linus Torvalds committed
444
{
445 446 447 448 449 450
	const char *last = NULL;
	do {
		if (*s == (char)c)
			last = s;
	} while (*s++);
	return (char *)last;
Linus Torvalds's avatar
Linus Torvalds committed
451 452 453 454 455 456 457 458 459 460
}
EXPORT_SYMBOL(strrchr);
#endif

#ifndef __HAVE_ARCH_STRNCHR
/**
 * strnchr - Find a character in a length limited string
 * @s: The string to be searched
 * @count: The number of characters to be searched
 * @c: The character to search for
461 462 463
 *
 * Note that the %NUL-terminator is considered part of the string, and can
 * be searched for.
Linus Torvalds's avatar
Linus Torvalds committed
464 465 466
 */
char *strnchr(const char *s, size_t count, int c)
{
467
	while (count--) {
468 469
		if (*s == (char)c)
			return (char *)s;
470 471 472
		if (*s++ == '\0')
			break;
	}
Linus Torvalds's avatar
Linus Torvalds committed
473 474 475 476 477
	return NULL;
}
EXPORT_SYMBOL(strnchr);
#endif

478
/**
479 480
 * skip_spaces - Removes leading whitespace from @str.
 * @str: The string to be stripped.
481
 *
482
 * Returns a pointer to the first non-whitespace character in @str.
483 484 485 486 487 488 489 490 491
 */
char *skip_spaces(const char *str)
{
	while (isspace(*str))
		++str;
	return (char *)str;
}
EXPORT_SYMBOL(skip_spaces);

Pekka Enberg's avatar
Pekka Enberg committed
492
/**
493
 * strim - Removes leading and trailing whitespace from @s.
Pekka Enberg's avatar
Pekka Enberg committed
494 495 496 497 498 499
 * @s: The string to be stripped.
 *
 * Note that the first trailing whitespace is replaced with a %NUL-terminator
 * in the given string @s. Returns a pointer to the first non-whitespace
 * character in @s.
 */
500
char *strim(char *s)
Pekka Enberg's avatar
Pekka Enberg committed
501 502 503 504 505 506 507 508 509
{
	size_t size;
	char *end;

	size = strlen(s);
	if (!size)
		return s;

	end = s + size - 1;
510
	while (end >= s && isspace(*end))
Pekka Enberg's avatar
Pekka Enberg committed
511 512 513
		end--;
	*(end + 1) = '\0';

514
	return skip_spaces(s);
Pekka Enberg's avatar
Pekka Enberg committed
515
}
516
EXPORT_SYMBOL(strim);
Pekka Enberg's avatar
Pekka Enberg committed
517

Linus Torvalds's avatar
Linus Torvalds committed
518 519 520 521 522
#ifndef __HAVE_ARCH_STRLEN
/**
 * strlen - Find the length of a string
 * @s: The string to be sized
 */
523
size_t strlen(const char *s)
Linus Torvalds's avatar
Linus Torvalds committed
524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539
{
	const char *sc;

	for (sc = s; *sc != '\0'; ++sc)
		/* nothing */;
	return sc - s;
}
EXPORT_SYMBOL(strlen);
#endif

#ifndef __HAVE_ARCH_STRNLEN
/**
 * strnlen - Find the length of a length-limited string
 * @s: The string to be sized
 * @count: The maximum number of bytes to search
 */
540
size_t strnlen(const char *s, size_t count)
Linus Torvalds's avatar
Linus Torvalds committed
541 542 543 544 545 546 547 548 549 550 551 552
{
	const char *sc;

	for (sc = s; count-- && *sc != '\0'; ++sc)
		/* nothing */;
	return sc - s;
}
EXPORT_SYMBOL(strnlen);
#endif

#ifndef __HAVE_ARCH_STRSPN
/**
553
 * strspn - Calculate the length of the initial substring of @s which only contain letters in @accept
Linus Torvalds's avatar
Linus Torvalds committed
554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577
 * @s: The string to be searched
 * @accept: The string to search for
 */
size_t strspn(const char *s, const char *accept)
{
	const char *p;
	const char *a;
	size_t count = 0;

	for (p = s; *p != '\0'; ++p) {
		for (a = accept; *a != '\0'; ++a) {
			if (*p == *a)
				break;
		}
		if (*a == '\0')
			return count;
		++count;
	}
	return count;
}

EXPORT_SYMBOL(strspn);
#endif

578
#ifndef __HAVE_ARCH_STRCSPN
Linus Torvalds's avatar
Linus Torvalds committed
579
/**
580
 * strcspn - Calculate the length of the initial substring of @s which does not contain letters in @reject
Linus Torvalds's avatar
Linus Torvalds committed
581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597
 * @s: The string to be searched
 * @reject: The string to avoid
 */
size_t strcspn(const char *s, const char *reject)
{
	const char *p;
	const char *r;
	size_t count = 0;

	for (p = s; *p != '\0'; ++p) {
		for (r = reject; *r != '\0'; ++r) {
			if (*p == *r)
				return count;
		}
		++count;
	}
	return count;
598
}
Linus Torvalds's avatar
Linus Torvalds committed
599
EXPORT_SYMBOL(strcspn);
600
#endif
Linus Torvalds's avatar
Linus Torvalds committed
601 602 603 604 605 606 607

#ifndef __HAVE_ARCH_STRPBRK
/**
 * strpbrk - Find the first occurrence of a set of characters
 * @cs: The string to be searched
 * @ct: The characters to search for
 */
608
char *strpbrk(const char *cs, const char *ct)
Linus Torvalds's avatar
Linus Torvalds committed
609
{
610
	const char *sc1, *sc2;
Linus Torvalds's avatar
Linus Torvalds committed
611

612 613
	for (sc1 = cs; *sc1 != '\0'; ++sc1) {
		for (sc2 = ct; *sc2 != '\0'; ++sc2) {
Linus Torvalds's avatar
Linus Torvalds committed
614
			if (*sc1 == *sc2)
615
				return (char *)sc1;
Linus Torvalds's avatar
Linus Torvalds committed
616 617 618 619
		}
	}
	return NULL;
}
620
EXPORT_SYMBOL(strpbrk);
Linus Torvalds's avatar
Linus Torvalds committed
621 622 623 624 625 626 627 628 629 630 631 632 633 634
#endif

#ifndef __HAVE_ARCH_STRSEP
/**
 * strsep - Split a string into tokens
 * @s: The string to be searched
 * @ct: The characters to search for
 *
 * strsep() updates @s to point after the token, ready for the next call.
 *
 * It returns empty tokens, too, behaving exactly like the libc function
 * of that name. In fact, it was stolen from glibc2 and de-fancy-fied.
 * Same semantics, slimmer shape. ;)
 */
635
char *strsep(char **s, const char *ct)
Linus Torvalds's avatar
Linus Torvalds committed
636
{
637 638
	char *sbegin = *s;
	char *end;
Linus Torvalds's avatar
Linus Torvalds committed
639 640 641 642 643 644 645 646 647 648 649 650 651

	if (sbegin == NULL)
		return NULL;

	end = strpbrk(sbegin, ct);
	if (end)
		*end++ = '\0';
	*s = end;
	return sbegin;
}
EXPORT_SYMBOL(strsep);
#endif

652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678
/**
 * sysfs_streq - return true if strings are equal, modulo trailing newline
 * @s1: one string
 * @s2: another string
 *
 * This routine returns true iff two strings are equal, treating both
 * NUL and newline-then-NUL as equivalent string terminations.  It's
 * geared for use with sysfs input strings, which generally terminate
 * with newlines but are compared against values without newlines.
 */
bool sysfs_streq(const char *s1, const char *s2)
{
	while (*s1 && *s1 == *s2) {
		s1++;
		s2++;
	}

	if (*s1 == *s2)
		return true;
	if (!*s1 && *s2 == '\n' && !s2[1])
		return true;
	if (*s1 == '\n' && !s1[1] && !*s2)
		return true;
	return false;
}
EXPORT_SYMBOL(sysfs_streq);

679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704
/**
 * match_string - matches given string in an array
 * @array:	array of strings
 * @n:		number of strings in the array or -1 for NULL terminated arrays
 * @string:	string to match with
 *
 * Return:
 * index of a @string in the @array if matches, or %-EINVAL otherwise.
 */
int match_string(const char * const *array, size_t n, const char *string)
{
	int index;
	const char *item;

	for (index = 0; index < n; index++) {
		item = array[index];
		if (!item)
			break;
		if (!strcmp(item, string))
			return index;
	}

	return -EINVAL;
}
EXPORT_SYMBOL(match_string);

705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730
/**
 * __sysfs_match_string - matches given string in an array
 * @array: array of strings
 * @n: number of strings in the array or -1 for NULL terminated arrays
 * @str: string to match with
 *
 * Returns index of @str in the @array or -EINVAL, just like match_string().
 * Uses sysfs_streq instead of strcmp for matching.
 */
int __sysfs_match_string(const char * const *array, size_t n, const char *str)
{
	const char *item;
	int index;

	for (index = 0; index < n; index++) {
		item = array[index];
		if (!item)
			break;
		if (sysfs_streq(item, str))
			return index;
	}

	return -EINVAL;
}
EXPORT_SYMBOL(__sysfs_match_string);

Linus Torvalds's avatar
Linus Torvalds committed
731 732 733 734 735 736 737 738 739
#ifndef __HAVE_ARCH_MEMSET
/**
 * memset - Fill a region of memory with the given value
 * @s: Pointer to the start of the area.
 * @c: The byte to fill the area with
 * @count: The size of the area.
 *
 * Do not use memset() to access IO space, use memset_io() instead.
 */
740
void *memset(void *s, int c, size_t count)
Linus Torvalds's avatar
Linus Torvalds committed
741
{
742
	char *xs = s;
Linus Torvalds's avatar
Linus Torvalds committed
743 744 745 746 747 748 749 750

	while (count--)
		*xs++ = c;
	return s;
}
EXPORT_SYMBOL(memset);
#endif

751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816
#ifndef __HAVE_ARCH_MEMSET16
/**
 * memset16() - Fill a memory area with a uint16_t
 * @s: Pointer to the start of the area.
 * @v: The value to fill the area with
 * @count: The number of values to store
 *
 * Differs from memset() in that it fills with a uint16_t instead
 * of a byte.  Remember that @count is the number of uint16_ts to
 * store, not the number of bytes.
 */
void *memset16(uint16_t *s, uint16_t v, size_t count)
{
	uint16_t *xs = s;

	while (count--)
		*xs++ = v;
	return s;
}
EXPORT_SYMBOL(memset16);
#endif

#ifndef __HAVE_ARCH_MEMSET32
/**
 * memset32() - Fill a memory area with a uint32_t
 * @s: Pointer to the start of the area.
 * @v: The value to fill the area with
 * @count: The number of values to store
 *
 * Differs from memset() in that it fills with a uint32_t instead
 * of a byte.  Remember that @count is the number of uint32_ts to
 * store, not the number of bytes.
 */
void *memset32(uint32_t *s, uint32_t v, size_t count)
{
	uint32_t *xs = s;

	while (count--)
		*xs++ = v;
	return s;
}
EXPORT_SYMBOL(memset32);
#endif

#ifndef __HAVE_ARCH_MEMSET64
/**
 * memset64() - Fill a memory area with a uint64_t
 * @s: Pointer to the start of the area.
 * @v: The value to fill the area with
 * @count: The number of values to store
 *
 * Differs from memset() in that it fills with a uint64_t instead
 * of a byte.  Remember that @count is the number of uint64_ts to
 * store, not the number of bytes.
 */
void *memset64(uint64_t *s, uint64_t v, size_t count)
{
	uint64_t *xs = s;

	while (count--)
		*xs++ = v;
	return s;
}
EXPORT_SYMBOL(memset64);
#endif

Linus Torvalds's avatar
Linus Torvalds committed
817 818 819 820 821 822 823 824 825 826
#ifndef __HAVE_ARCH_MEMCPY
/**
 * memcpy - Copy one area of memory to another
 * @dest: Where to copy to
 * @src: Where to copy from
 * @count: The size of the area.
 *
 * You should not use this function to access IO space, use memcpy_toio()
 * or memcpy_fromio() instead.
 */
827
void *memcpy(void *dest, const void *src, size_t count)
Linus Torvalds's avatar
Linus Torvalds committed
828
{
829
	char *tmp = dest;
830
	const char *s = src;
Linus Torvalds's avatar
Linus Torvalds committed
831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847

	while (count--)
		*tmp++ = *s++;
	return dest;
}
EXPORT_SYMBOL(memcpy);
#endif

#ifndef __HAVE_ARCH_MEMMOVE
/**
 * memmove - Copy one area of memory to another
 * @dest: Where to copy to
 * @src: Where to copy from
 * @count: The size of the area.
 *
 * Unlike memcpy(), memmove() copes with overlapping areas.
 */
848
void *memmove(void *dest, const void *src, size_t count)
Linus Torvalds's avatar
Linus Torvalds committed
849
{
850 851
	char *tmp;
	const char *s;
Linus Torvalds's avatar
Linus Torvalds committed
852 853

	if (dest <= src) {
854 855
		tmp = dest;
		s = src;
Linus Torvalds's avatar
Linus Torvalds committed
856 857
		while (count--)
			*tmp++ = *s++;
858
	} else {
859 860 861 862
		tmp = dest;
		tmp += count;
		s = src;
		s += count;
Linus Torvalds's avatar
Linus Torvalds committed
863 864
		while (count--)
			*--tmp = *--s;
865
	}
Linus Torvalds's avatar
Linus Torvalds committed
866 867 868 869 870 871 872 873 874 875 876 877
	return dest;
}
EXPORT_SYMBOL(memmove);
#endif

#ifndef __HAVE_ARCH_MEMCMP
/**
 * memcmp - Compare two areas of memory
 * @cs: One area of memory
 * @ct: Another area of memory
 * @count: The size of the area.
 */
878
#undef memcmp
879
__visible int memcmp(const void *cs, const void *ct, size_t count)
Linus Torvalds's avatar
Linus Torvalds committed
880 881 882 883
{
	const unsigned char *su1, *su2;
	int res = 0;

884
	for (su1 = cs, su2 = ct; 0 < count; ++su1, ++su2, count--)
Linus Torvalds's avatar
Linus Torvalds committed
885 886 887 888 889 890 891
		if ((res = *su1 - *su2) != 0)
			break;
	return res;
}
EXPORT_SYMBOL(memcmp);
#endif

892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911
#ifndef __HAVE_ARCH_BCMP
/**
 * bcmp - returns 0 if and only if the buffers have identical contents.
 * @a: pointer to first buffer.
 * @b: pointer to second buffer.
 * @len: size of buffers.
 *
 * The sign or magnitude of a non-zero return value has no particular
 * meaning, and architectures may implement their own more efficient bcmp(). So
 * while this particular implementation is a simple (tail) call to memcmp, do
 * not rely on anything but whether the return value is zero or non-zero.
 */
#undef bcmp
int bcmp(const void *a, const void *b, size_t len)
{
	return memcmp(a, b, len);
}
EXPORT_SYMBOL(bcmp);
#endif

Linus Torvalds's avatar
Linus Torvalds committed
912 913 914 915 916 917 918 919 920 921
#ifndef __HAVE_ARCH_MEMSCAN
/**
 * memscan - Find a character in an area of memory.
 * @addr: The memory area
 * @c: The byte to search for
 * @size: The size of the area.
 *
 * returns the address of the first occurrence of @c, or 1 byte past
 * the area if @c is not found
 */
922
void *memscan(void *addr, int c, size_t size)
Linus Torvalds's avatar
Linus Torvalds committed
923
{
924
	unsigned char *p = addr;
Linus Torvalds's avatar
Linus Torvalds committed
925 926 927

	while (size) {
		if (*p == c)
928
			return (void *)p;
Linus Torvalds's avatar
Linus Torvalds committed
929 930 931
		p++;
		size--;
	}
932
  	return (void *)p;
Linus Torvalds's avatar
Linus Torvalds committed
933 934 935 936 937 938 939 940 941 942
}
EXPORT_SYMBOL(memscan);
#endif

#ifndef __HAVE_ARCH_STRSTR
/**
 * strstr - Find the first substring in a %NUL terminated string
 * @s1: The string to be searched
 * @s2: The string to search for
 */
943
char *strstr(const char *s1, const char *s2)
Linus Torvalds's avatar
Linus Torvalds committed
944
{
Li Zefan's avatar
Li Zefan committed
945
	size_t l1, l2;
Linus Torvalds's avatar
Linus Torvalds committed
946 947 948

	l2 = strlen(s2);
	if (!l2)
949
		return (char *)s1;
Linus Torvalds's avatar
Linus Torvalds committed
950 951 952
	l1 = strlen(s1);
	while (l1 >= l2) {
		l1--;
953 954
		if (!memcmp(s1, s2, l2))
			return (char *)s1;
Linus Torvalds's avatar
Linus Torvalds committed
955 956 957 958 959 960 961
		s1++;
	}
	return NULL;
}
EXPORT_SYMBOL(strstr);
#endif

Li Zefan's avatar
Li Zefan committed
962 963 964 965 966 967 968 969 970
#ifndef __HAVE_ARCH_STRNSTR
/**
 * strnstr - Find the first substring in a length-limited string
 * @s1: The string to be searched
 * @s2: The string to search for
 * @len: the maximum number of characters to search
 */
char *strnstr(const char *s1, const char *s2, size_t len)
{
971
	size_t l2;
Li Zefan's avatar
Li Zefan committed
972 973 974 975

	l2 = strlen(s2);
	if (!l2)
		return (char *)s1;
976 977
	while (len >= l2) {
		len--;
Li Zefan's avatar
Li Zefan committed
978 979 980 981 982 983 984 985 986
		if (!memcmp(s1, s2, l2))
			return (char *)s1;
		s1++;
	}
	return NULL;
}
EXPORT_SYMBOL(strnstr);
#endif

Linus Torvalds's avatar
Linus Torvalds committed
987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001
#ifndef __HAVE_ARCH_MEMCHR
/**
 * memchr - Find a character in an area of memory.
 * @s: The memory area
 * @c: The byte to search for
 * @n: The size of the area.
 *
 * returns the address of the first occurrence of @c, or %NULL
 * if @c is not found
 */
void *memchr(const void *s, int c, size_t n)
{
	const unsigned char *p = s;
	while (n-- != 0) {
        	if ((unsigned char)c == *p++) {
1002
			return (void *)(p - 1);
Linus Torvalds's avatar
Linus Torvalds committed
1003 1004 1005 1006 1007 1008
		}
	}
	return NULL;
}
EXPORT_SYMBOL(memchr);
#endif
1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038

static void *check_bytes8(const u8 *start, u8 value, unsigned int bytes)
{
	while (bytes) {
		if (*start != value)
			return (void *)start;
		start++;
		bytes--;
	}
	return NULL;
}

/**
 * memchr_inv - Find an unmatching character in an area of memory.
 * @start: The memory area
 * @c: Find a character other than c
 * @bytes: The size of the area.
 *
 * returns the address of the first character other than @c, or %NULL
 * if the whole buffer contains just @c.
 */
void *memchr_inv(const void *start, int c, size_t bytes)
{
	u8 value = c;
	u64 value64;
	unsigned int words, prefix;

	if (bytes <= 16)
		return check_bytes8(start, value, bytes);

1039
	value64 = value;
1040
#if defined(CONFIG_ARCH_HAS_FAST_MULTIPLIER) && BITS_PER_LONG == 64
1041
	value64 *= 0x0101010101010101ULL;
1042
#elif defined(CONFIG_ARCH_HAS_FAST_MULTIPLIER)
1043 1044 1045 1046 1047 1048 1049
	value64 *= 0x01010101;
	value64 |= value64 << 32;
#else
	value64 |= value64 << 8;
	value64 |= value64 << 16;
	value64 |= value64 << 32;
#endif
1050

1051
	prefix = (unsigned long)start % 8;
1052
	if (prefix) {
1053 1054 1055 1056
		u8 *r;

		prefix = 8 - prefix;
		r = check_bytes8(start, value, prefix);
1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074
		if (r)
			return r;
		start += prefix;
		bytes -= prefix;
	}

	words = bytes / 8;

	while (words) {
		if (*(u64 *)start != value64)
			return check_bytes8(start, value, 8);
		start += 8;
		words--;
	}

	return check_bytes8(start, value, bytes % 8);
}
EXPORT_SYMBOL(memchr_inv);
1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091

/**
 * strreplace - Replace all occurrences of character in string.
 * @s: The string to operate on.
 * @old: The character being replaced.
 * @new: The character @old is replaced with.
 *
 * Returns pointer to the nul byte at the end of @s.
 */
char *strreplace(char *s, char old, char new)
{
	for (; *s; ++s)
		if (*s == old)
			*s = new;
	return s;
}
EXPORT_SYMBOL(strreplace);
1092 1093 1094 1095 1096 1097 1098

void fortify_panic(const char *name)
{
	pr_emerg("detected buffer overflow in %s\n", name);
	BUG();
}
EXPORT_SYMBOL(fortify_panic);