1 // SPDX-License-Identifier: BSD-3-Clause 2 /* 3 * Copyright (c) 1994-2009 Red Hat, Inc. 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions are met: 8 * 9 * 1. Redistributions of source code must retain the above copyright notice, 10 * this list of conditions and the following disclaimer. 11 * 12 * 2. Redistributions in binary form must reproduce the above copyright notice, 13 * this list of conditions and the following disclaimer in the documentation 14 * and/or other materials provided with the distribution. 15 * 16 * 3. Neither the name of the copyright holder nor the names of its 17 * contributors may be used to endorse or promote products derived from this 18 * software without specific prior written permission. 19 * 20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 21 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 23 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 24 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 25 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 26 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 27 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 30 * POSSIBILITY OF SUCH DAMAGE. 31 */ 32 33 /* 34 FUNCTION 35 <<strncpy>>---counted copy string 36 37 INDEX 38 strncpy 39 40 ANSI_SYNOPSIS 41 #include <string.h> 42 char *strncpy(char *restrict <[dst]>, const char *restrict <[src]>, 43 size_t <[length]>); 44 45 TRAD_SYNOPSIS 46 #include <string.h> 47 char *strncpy(<[dst]>, <[src]>, <[length]>) 48 char *<[dst]>; 49 char *<[src]>; 50 size_t <[length]>; 51 52 DESCRIPTION 53 <<strncpy>> copies not more than <[length]> characters from the 54 the string pointed to by <[src]> (including the terminating 55 null character) to the array pointed to by <[dst]>. If the 56 string pointed to by <[src]> is shorter than <[length]> 57 characters, null characters are appended to the destination 58 array until a total of <[length]> characters have been 59 written. 60 61 RETURNS 62 This function returns the initial value of <[dst]>. 63 64 PORTABILITY 65 <<strncpy>> is ANSI C. 66 67 <<strncpy>> requires no supporting OS subroutines. 68 69 QUICKREF 70 strncpy ansi pure 71 */ 72 73 #include "_ansi.h" 74 #include <string.h> 75 #include <limits.h> 76 77 /*SUPPRESS 560*/ 78 /*SUPPRESS 530*/ 79 80 /* Nonzero if either X or Y is not aligned on a "long" boundary. */ 81 #define UNALIGNED(X, Y) \ 82 (((long)X & (sizeof (long) - 1)) | ((long)Y & (sizeof (long) - 1))) 83 84 #if LONG_MAX == 2147483647L 85 #define DETECTNULL(X) (((X) - 0x01010101) & ~(X) & 0x80808080) 86 #else 87 #if LONG_MAX == 9223372036854775807L 88 /* Nonzero if X (a long int) contains a NULL byte. */ 89 #define DETECTNULL(X) (((X) - 0x0101010101010101) & ~(X) & 0x8080808080808080) 90 #else 91 #error long int is not a 32bit or 64bit type. 92 #endif 93 #endif 94 95 #ifndef DETECTNULL 96 #error long int is not a 32bit or 64bit byte 97 #endif 98 99 #define TOO_SMALL(LEN) ((LEN) < sizeof (long)) 100 101 char * 102 _DEFUN (strncpy, (dst0, src0), 103 char *__restrict dst0 _AND 104 _CONST char *__restrict src0 _AND 105 size_t count) 106 { 107 #if defined(PREFER_SIZE_OVER_SPEED) || defined(__OPTIMIZE_SIZE__) 108 char *dscan; 109 _CONST char *sscan; 110 111 dscan = dst0; 112 sscan = src0; 113 while (count > 0) 114 { 115 --count; 116 if ((*dscan++ = *sscan++) == '\0') 117 break; 118 } 119 while (count-- > 0) 120 *dscan++ = '\0'; 121 122 return dst0; 123 #else 124 char *dst = dst0; 125 _CONST char *src = src0; 126 long *aligned_dst; 127 _CONST long *aligned_src; 128 129 /* If SRC and DEST is aligned and count large enough, then copy words. */ 130 if (!UNALIGNED (src, dst) && !TOO_SMALL (count)) 131 { 132 aligned_dst = (long*)dst; 133 aligned_src = (long*)src; 134 135 /* SRC and DEST are both "long int" aligned, try to do "long int" 136 sized copies. */ 137 while (count >= sizeof (long int) && !DETECTNULL(*aligned_src)) 138 { 139 count -= sizeof (long int); 140 *aligned_dst++ = *aligned_src++; 141 } 142 143 dst = (char*)aligned_dst; 144 src = (char*)aligned_src; 145 } 146 147 while (count > 0) 148 { 149 --count; 150 if ((*dst++ = *src++) == '\0') 151 break; 152 } 153 154 while (count-- > 0) 155 *dst++ = '\0'; 156 157 return dst0; 158 #endif /* not PREFER_SIZE_OVER_SPEED */ 159 } 160