| 1 | /* | 
|---|
| 2 | *  linux/lib/string.c | 
|---|
| 3 | * | 
|---|
| 4 | *  Copyright (C) 1991, 1992  Linus Torvalds | 
|---|
| 5 | */ | 
|---|
| 6 |  | 
|---|
| 7 | #include <string.h> | 
|---|
| 8 | #include <types.h> | 
|---|
| 9 | #include <asm/errno.h> | 
|---|
| 10 |  | 
|---|
| 11 | #define REPEAT_BYTE(x)  ((~0ul / 0xff) * (x)) | 
|---|
| 12 |  | 
|---|
| 13 | /* | 
|---|
| 14 | * This is largely generic for little-endian machines, but the | 
|---|
| 15 | * optimal byte mask counting is probably going to be something | 
|---|
| 16 | * that is architecture-specific. If you have a reliably fast | 
|---|
| 17 | * bit count instruction, that might be better than the multiply | 
|---|
| 18 | * and shift, for example. | 
|---|
| 19 | */ | 
|---|
| 20 | struct word_at_a_time { | 
|---|
| 21 | const unsigned long one_bits, high_bits; | 
|---|
| 22 | }; | 
|---|
| 23 |  | 
|---|
| 24 | /* Carl Chatfield / Jan Achrenius G+ version for 32-bit */ | 
|---|
| 25 | static inline long count_masked_bytes(long mask) | 
|---|
| 26 | { | 
|---|
| 27 | /* (000000 0000ff 00ffff ffffff) -> ( 1 1 2 3 ) */ | 
|---|
| 28 | long a = (0x0ff0001+mask) >> 23; | 
|---|
| 29 | /* Fix the 1 for 00 case */ | 
|---|
| 30 | return a & mask; | 
|---|
| 31 | } | 
|---|
| 32 |  | 
|---|
| 33 | #define WORD_AT_A_TIME_CONSTANTS { REPEAT_BYTE(0x01), REPEAT_BYTE(0x80) } | 
|---|
| 34 |  | 
|---|
| 35 | /* Return nonzero if it has a zero */ | 
|---|
| 36 | static inline unsigned long has_zero(unsigned long a, unsigned long *bits, const struct word_at_a_time *c) | 
|---|
| 37 | { | 
|---|
| 38 | unsigned long mask = ((a - c->one_bits) & ~a) & c->high_bits; | 
|---|
| 39 | *bits = mask; | 
|---|
| 40 | return mask; | 
|---|
| 41 | } | 
|---|
| 42 |  | 
|---|
| 43 | static inline unsigned long prep_zero_mask(unsigned long a, unsigned long bits, const struct word_at_a_time *c) | 
|---|
| 44 | { | 
|---|
| 45 | return bits; | 
|---|
| 46 | } | 
|---|
| 47 |  | 
|---|
| 48 | static inline unsigned long create_zero_mask(unsigned long bits) | 
|---|
| 49 | { | 
|---|
| 50 | bits = (bits - 1) & ~bits; | 
|---|
| 51 | return bits >> 7; | 
|---|
| 52 | } | 
|---|
| 53 |  | 
|---|
| 54 | /* The mask we created is directly usable as a bytemask */ | 
|---|
| 55 | #define zero_bytemask(mask) (mask) | 
|---|
| 56 |  | 
|---|
| 57 | static inline unsigned long find_zero(unsigned long mask) | 
|---|
| 58 | { | 
|---|
| 59 | return count_masked_bytes(mask); | 
|---|
| 60 | } | 
|---|
| 61 |  | 
|---|
| 62 | /** | 
|---|
| 63 | * strscpy - Copy a C-string into a sized buffer | 
|---|
| 64 | * @dest: Where to copy the string to | 
|---|
| 65 | * @src: Where to copy the string from | 
|---|
| 66 | * @count: Size of destination buffer | 
|---|
| 67 | * | 
|---|
| 68 | * Copy the string, or as much of it as fits, into the dest buffer. | 
|---|
| 69 | * The routine returns the number of characters copied (not including | 
|---|
| 70 | * the trailing NUL) or -E2BIG if the destination buffer wasn't big enough. | 
|---|
| 71 | * The behavior is undefined if the string buffers overlap. | 
|---|
| 72 | * The destination buffer is always NUL terminated, unless it's zero-sized. | 
|---|
| 73 | * | 
|---|
| 74 | * Preferred to strlcpy() since the API doesn't require reading memory | 
|---|
| 75 | * from the src string beyond the specified "count" bytes, and since | 
|---|
| 76 | * the return value is easier to error-check than strlcpy()'s. | 
|---|
| 77 | * In addition, the implementation is robust to the string changing out | 
|---|
| 78 | * from underneath it, unlike the current strlcpy() implementation. | 
|---|
| 79 | * | 
|---|
| 80 | * Preferred to strncpy() since it always returns a valid string, and | 
|---|
| 81 | * doesn't unnecessarily force the tail of the destination buffer to be | 
|---|
| 82 | * zeroed.  If the zeroing is desired, it's likely cleaner to use strscpy() | 
|---|
| 83 | * with an overflow test, then just memset() the tail of the dest buffer. | 
|---|
| 84 | */ | 
|---|
| 85 | ssize_t strscpy(char *dest, const char *src, size_t count) | 
|---|
| 86 | { | 
|---|
| 87 | const struct word_at_a_time constants = WORD_AT_A_TIME_CONSTANTS; | 
|---|
| 88 | size_t max = count; | 
|---|
| 89 | long res = 0; | 
|---|
| 90 |  | 
|---|
| 91 | if (count == 0) | 
|---|
| 92 | return -E2BIG; | 
|---|
| 93 |  | 
|---|
| 94 | /* If src or dest is unaligned, don't do word-at-a-time. */ | 
|---|
| 95 | if (((long) dest | (long) src) & (sizeof(long) - 1)) | 
|---|
| 96 | max = 0; | 
|---|
| 97 |  | 
|---|
| 98 | while (max >= sizeof(unsigned long)) { | 
|---|
| 99 | unsigned long c, data; | 
|---|
| 100 |  | 
|---|
| 101 | c = *(unsigned long *)(src+res); | 
|---|
| 102 | if (has_zero(c, &data, &constants)) { | 
|---|
| 103 | data = prep_zero_mask(c, data, &constants); | 
|---|
| 104 | data = create_zero_mask(data); | 
|---|
| 105 | *(unsigned long *)(dest+res) = c & zero_bytemask(data); | 
|---|
| 106 | return res + find_zero(data); | 
|---|
| 107 | } | 
|---|
| 108 | *(unsigned long *)(dest+res) = c; | 
|---|
| 109 | res += sizeof(unsigned long); | 
|---|
| 110 | count -= sizeof(unsigned long); | 
|---|
| 111 | max -= sizeof(unsigned long); | 
|---|
| 112 | } | 
|---|
| 113 |  | 
|---|
| 114 | while (count) { | 
|---|
| 115 | char c; | 
|---|
| 116 |  | 
|---|
| 117 | c = src[res]; | 
|---|
| 118 | dest[res] = c; | 
|---|
| 119 | if (!c) | 
|---|
| 120 | return res; | 
|---|
| 121 | res++; | 
|---|
| 122 | count--; | 
|---|
| 123 | } | 
|---|
| 124 |  | 
|---|
| 125 | /* Hit buffer length without finding a NUL; force NUL-termination. */ | 
|---|
| 126 | if (res) | 
|---|
| 127 | dest[res-1] = '\0'; | 
|---|
| 128 |  | 
|---|
| 129 | return -E2BIG; | 
|---|
| 130 | } | 
|---|