1 /* 2 FUNCTION 3 <<strncpy>>---counted copy string 4 5 INDEX 6 strncpy 7 8 ANSI_SYNOPSIS 9 #include <string.h> 10 char *strncpy(char *restrict <[dst]>, const char *restrict <[src]>, 11 size_t <[length]>); 12 13 TRAD_SYNOPSIS 14 #include <string.h> 15 char *strncpy(<[dst]>, <[src]>, <[length]>) 16 char *<[dst]>; 17 char *<[src]>; 18 size_t <[length]>; 19 20 DESCRIPTION 21 <<strncpy>> copies not more than <[length]> characters from the 22 the string pointed to by <[src]> (including the terminating 23 null character) to the array pointed to by <[dst]>. If the 24 string pointed to by <[src]> is shorter than <[length]> 25 characters, null characters are appended to the destination 26 array until a total of <[length]> characters have been 27 written. 28 29 RETURNS 30 This function returns the initial value of <[dst]>. 31 32 PORTABILITY 33 <<strncpy>> is ANSI C. 34 35 <<strncpy>> requires no supporting OS subroutines. 36 37 QUICKREF 38 strncpy ansi pure 39 */ 40 41 #include <string.h> 42 #include <limits.h> 43 44 /*SUPPRESS 560*/ 45 /*SUPPRESS 530*/ 46 47 #ifndef LONG_MAX 48 #ifdef _LP64 49 #define LONG_MAX 0x7fffffffffffffffL 50 #else 51 #define LONG_MAX 0x7fffffffUL 52 #endif 53 #endif 54 55 /* Nonzero if either X or Y is not aligned on a "long" boundary. */ 56 #define UNALIGNED(X, Y) \ 57 (((long)X & (sizeof (long) - 1)) | ((long)Y & (sizeof (long) - 1))) 58 59 #if LONG_MAX == 2147483647L 60 #define DETECTNULL(X) (((X) - 0x01010101) & ~(X) & 0x80808080) 61 #else 62 #if LONG_MAX == 9223372036854775807L 63 /* Nonzero if X (a long int) contains a NULL byte. */ 64 #define DETECTNULL(X) (((X) - 0x0101010101010101) & ~(X) & 0x8080808080808080) 65 #else 66 #error long int is not a 32bit or 64bit type. 67 #endif 68 #endif 69 70 #ifndef DETECTNULL 71 #error long int is not a 32bit or 64bit byte 72 #endif 73 74 #define TOO_SMALL(LEN) ((LEN) < sizeof (long)) 75 76 char * 77 _DEFUN (strncpy, (dst0, src0), 78 char *__restrict dst0 _AND 79 _CONST char *__restrict src0 _AND 80 size_t count) 81 { 82 #if defined(PREFER_SIZE_OVER_SPEED) || defined(__OPTIMIZE_SIZE__) 83 char *dscan; 84 _CONST char *sscan; 85 86 dscan = dst0; 87 sscan = src0; 88 while (count > 0) 89 { 90 --count; 91 if ((*dscan++ = *sscan++) == '\0') 92 break; 93 } 94 while (count-- > 0) 95 *dscan++ = '\0'; 96 97 return dst0; 98 #else 99 char *dst = dst0; 100 _CONST char *src = src0; 101 long *aligned_dst; 102 _CONST long *aligned_src; 103 104 /* If SRC and DEST is aligned and count large enough, then copy words. */ 105 if (!UNALIGNED (src, dst) && !TOO_SMALL (count)) 106 { 107 aligned_dst = (long*)dst; 108 aligned_src = (long*)src; 109 110 /* SRC and DEST are both "long int" aligned, try to do "long int" 111 sized copies. */ 112 while (count >= sizeof (long int) && !DETECTNULL(*aligned_src)) 113 { 114 count -= sizeof (long int); 115 *aligned_dst++ = *aligned_src++; 116 } 117 118 dst = (char*)aligned_dst; 119 src = (char*)aligned_src; 120 } 121 122 while (count > 0) 123 { 124 --count; 125 if ((*dst++ = *src++) == '\0') 126 break; 127 } 128 129 while (count-- > 0) 130 *dst++ = '\0'; 131 132 return dst0; 133 #endif /* not PREFER_SIZE_OVER_SPEED */ 134 } 135