1/* Copyright (C) 1993, 1995-1997, 2002-2003, 2005-2007, 2009-2010 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 <http://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.  */
33char *
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
91weak_alias (__stpncpy, stpncpy)
92#endif
93