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