Initial revision
[kopensolaris-gnu/glibc.git] / sysdeps / generic / strncpy.c
1 /* Copyright (C) 1991 Free Software Foundation, Inc.
2 This file is part of the GNU C Library.
3
4 The GNU C Library is distributed in the hope that it will be useful, but
5 WITHOUT ANY WARRANTY.  No author or distributor accepts responsibility for
6 the consequences of using it or for whether it serves any particular
7 purpose or works at all, unless he says so in writing.  Refer to the GNU
8 C Library General Public License (in the file COPYING) for full details.
9
10 Everyone is granted permission to copy, modify and redistribute
11 the GNU C Library, but only under the conditions described in the
12 GNU C Library General Public License.  Among other things, this notice
13 must not be changed and a copy of the license must be included.  */
14
15 #include <ansidecl.h>
16 #include <string.h>
17 #include <memcopy.h>
18
19 char *
20 DEFUN(strncpy, (s1, s2, n), char *s1 AND CONST char *s2 AND size_t n)
21 {
22   reg_char c;
23   char *s = s1;
24
25   --s1;
26
27   if (n >= 4)
28     {
29       size_t n4 = n >> 2;
30
31       for (;;)
32         {
33           c = *s2++;
34           *++s1 = c;
35           if (c == '\0')
36             break;
37           c = *s2++;
38           *++s1 = c;
39           if (c == '\0')
40             break;
41           c = *s2++;
42           *++s1 = c;
43           if (c == '\0')
44             break;
45           c = *s2++;
46           *++s1 = c;
47           if (c == '\0')
48             break;
49           if (--n4 == 0)
50             goto last_chars;
51         }
52       n = n - (s1 - s) - 1;
53       if (n == 0)
54         return s;
55       goto zero_fill;
56     }
57
58  last_chars:
59   n &= 3;
60   if (n == 0)
61     return s;
62
63   do
64     {
65       c = *s2++;
66       *++s1 = c;
67       if (--n == 0)
68         return s;
69     }
70   while (c != '\0');
71
72  zero_fill:
73   do
74     *++s1 = '\0';
75   while (--n > 0);
76
77   return s;
78 }