1 /* Copyright (C) 1993, 1995-1997, 2002-2003, 2005-2007, 2009-2018 Free Software 2 * Foundation, Inc. 3 4 NOTE: The canonical source of this file is maintained with the GNU C Library. 5 Bugs can be reported to bug-glibc@gnu.org. 6 7 This program is free software: you can redistribute it and/or modify it 8 under the terms of the GNU General Public License as published by the 9 Free Software Foundation; either version 3 of the License, or any 10 later version. 11 12 This program is distributed in the hope that it will be useful, 13 but WITHOUT ANY WARRANTY; without even the implied warranty of 14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 GNU General Public License for more details. 16 17 You should have received a copy of the GNU General Public License 18 along with this program. If not, see <https://www.gnu.org/licenses/>. */ 19 20 /* This is almost copied from strncpy.c, written by Torbjorn Granlund. */ 21 22 #include <config.h> 23 24 /* Specification. */ 25 #include <string.h> 26 27 #ifndef weak_alias 28 # define __stpncpy stpncpy 29 #endif 30 31 /* Copy no more than N bytes of SRC to DST, returning a pointer past the 32 last non-NUL byte written into DST. */ 33 char * 34 (__stpncpy) (char *dest, const char *src, size_t n) 35 { 36 char c; 37 char *s = dest; 38 39 if (n >= 4) 40 { 41 size_t n4 = n >> 2; 42 43 for (;;) 44 { 45 c = *src++; 46 *dest++ = c; 47 if (c == '\0') 48 break; 49 c = *src++; 50 *dest++ = c; 51 if (c == '\0') 52 break; 53 c = *src++; 54 *dest++ = c; 55 if (c == '\0') 56 break; 57 c = *src++; 58 *dest++ = c; 59 if (c == '\0') 60 break; 61 if (--n4 == 0) 62 goto last_chars; 63 } 64 n -= dest - s; 65 goto zero_fill; 66 } 67 68 last_chars: 69 n &= 3; 70 if (n == 0) 71 return dest; 72 73 for (;;) 74 { 75 c = *src++; 76 --n; 77 *dest++ = c; 78 if (c == '\0') 79 break; 80 if (n == 0) 81 return dest; 82 } 83 84 zero_fill: 85 while (n-- > 0) 86 dest[n] = '\0'; 87 88 return dest - 1; 89 } 90 #ifdef weak_alias 91 weak_alias (__stpncpy, stpncpy) 92 #endif 93