xref: /netbsd-src/lib/libc/string/strlcpy.3 (revision 5aefcfdc06931dd97e76246d2fe0302f7b3fe094)
1.\"	$NetBSD: strlcpy.3,v 1.3 2000/11/24 16:19:05 itojun Exp $
2.\" from OpenBSD: strlcpy.3,v 1.11 2000/11/16 23:27:41 angelos Exp
3.\"
4.\" Copyright (c) 1998, 2000 Todd C. Miller <Todd.Miller@courtesan.com>
5.\" All rights reserved.
6.\"
7.\" Redistribution and use in source and binary forms, with or without
8.\" modification, are permitted provided that the following conditions
9.\" are met:
10.\" 1. Redistributions of source code must retain the above copyright
11.\"    notice, this list of conditions and the following disclaimer.
12.\" 2. Redistributions in binary form must reproduce the above copyright
13.\"    notice, this list of conditions and the following disclaimer in the
14.\"    documentation and/or other materials provided with the distribution.
15.\" 3. The name of the author may not be used to endorse or promote products
16.\"    derived from this software without specific prior written permission.
17.\"
18.\" THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
19.\" INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
20.\" AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
21.\" THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
22.\" EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
23.\" PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
24.\" OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
25.\" WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
26.\" OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
27.\" ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28.\"
29.Dd June 22, 1998
30.Dt STRLCPY 3
31.Os
32.Sh NAME
33.Nm strlcpy ,
34.Nm strlcat
35.Nd size-bounded string copying and concatenation
36.Sh SYNOPSIS
37.Fd #include <string.h>
38.Ft size_t
39.Fn strlcpy "char *dst" "const char *src" "size_t size"
40.Ft size_t
41.Fn strlcat "char *dst" "const char *src" "size_t size"
42.Sh DESCRIPTION
43The
44.Fn strlcpy
45and
46.Fn strlcat
47functions copy and concatenate strings respectively.
48They are designed
49to be safer, more consistent, and less error prone replacements for
50.Xr strncpy 3
51and
52.Xr strncat 3 .
53Unlike those functions,
54.Fn strlcpy
55and
56.Fn strlcat
57take the full size of the buffer (not just the length) and guarantee to
58NUL-terminate the result (as long as
59.Fa size
60is larger than 0 or, in the case of
61.Fn strlcat ,
62as long as there is at least one byte free in
63.Fa dst ) .
64Note that you should include a byte for the NUL in
65.Fa size .
66Also note that
67.Fn strlcpy
68and
69.Fn strlcat
70only operate on true
71.Dq C
72strings.
73This means that for
74.Fn strlcpy
75.Fa src
76must be NUL-terminated and for
77.Fn strlcat
78both
79.Fa src
80and
81.Fa dst
82must be NUL-terminated.
83.Pp
84The
85.Fn strlcpy
86function copies up to
87.Fa size
88- 1 characters from the NUL-terminated string
89.Fa src
90to
91.Fa dst ,
92NUL-terminating the result.
93.Pp
94The
95.Fn strlcat
96function appends the NUL-terminated string
97.Fa src
98to the end of
99.Fa dst .
100It will append at most
101.Fa size
102- strlen(dst) - 1 bytes, NUL-terminating the result.
103.Sh RETURN VALUES
104The
105.Fn strlcpy
106and
107.Fn strlcat
108functions return the total length of the string they tried to create.
109For
110.Fn strlcpy
111that means the length of
112.Fa src .
113For
114.Fn strlcat
115that means the initial length of
116.Fa dst
117plus
118the length of
119.Fa src .
120While this may seem somewhat confusing it was done to make
121truncation detection simple.
122.Sh EXAMPLES
123The following code fragment illustrates the simple case:
124.Bd -literal -offset indent
125char *s, *p, buf[BUFSIZ];
126
127\&...
128
129(void)strlcpy(buf, s, sizeof(buf));
130(void)strlcat(buf, p, sizeof(buf));
131.Ed
132.Pp
133To detect truncation, perhaps while building a pathname, something
134like the following might be used:
135.Bd -literal -offset indent
136char *dir, *file, pname[MAXPATHLEN];
137
138\&...
139
140if (strlcpy(pname, dir, sizeof(pname)) >= sizeof(pname))
141	goto toolong;
142if (strlcat(pname, file, sizeof(pname)) >= sizeof(pname))
143	goto toolong;
144.Ed
145.Pp
146Since we know how many characters we copied the first time, we can
147speed things up a bit by using a copy instead of an append:
148.Bd -literal -offset indent
149char *dir, *file, pname[MAXPATHLEN];
150size_t n;
151
152\&...
153
154n = strlcpy(pname, dir, sizeof(pname));
155if (n >= sizeof(pname))
156	goto toolong;
157if (strlcpy(pname + n, file, sizeof(pname) - n) >= sizeof(pname) - n)
158	goto toolong;
159.Ed
160.Pp
161However, one may question the validity of such optimizations, as they
162defeat the whole purpose of
163.Fn strlcpy
164and
165.Fn strlcat .
166As a matter of fact, the first version of this manual page got it wrong.
167.Sh SEE ALSO
168.Xr snprintf 3 ,
169.Xr strncat 3 ,
170.Xr strncpy 3
171