1999-08-10 05:58:58 +00:00
|
|
|
.\" $OpenBSD: strlcpy.3,v 1.5 1999/06/06 15:17:32 aaron Exp $
|
1999-08-10 05:21:31 +00:00
|
|
|
.\"
|
|
|
|
.\" Copyright (c) 1998 Todd C. Miller <Todd.Miller@courtesan.com>
|
|
|
|
.\" All rights reserved.
|
|
|
|
.\"
|
|
|
|
.\" Redistribution and use in source and binary forms, with or without
|
|
|
|
.\" modification, are permitted provided that the following conditions
|
|
|
|
.\" are met:
|
|
|
|
.\" 1. Redistributions of source code must retain the above copyright
|
|
|
|
.\" notice, this list of conditions and the following disclaimer.
|
|
|
|
.\" 2. Redistributions in binary form must reproduce the above copyright
|
|
|
|
.\" notice, this list of conditions and the following disclaimer in the
|
|
|
|
.\" documentation and/or other materials provided with the distribution.
|
|
|
|
.\" 3. The name of the author may not be used to endorse or promote products
|
|
|
|
.\" derived from this software without specific prior written permission.
|
|
|
|
.\"
|
|
|
|
.\" THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
|
|
|
.\" INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
|
|
|
|
.\" AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
|
|
|
|
.\" THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
|
|
|
.\" EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
|
|
|
.\" PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
|
|
|
.\" OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
|
|
|
.\" WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
|
|
|
.\" OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
|
|
|
.\" ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
|
|
.\"
|
1999-08-28 23:04:49 +00:00
|
|
|
.\" $FreeBSD$
|
|
|
|
.\"
|
1999-08-10 05:21:31 +00:00
|
|
|
.Dd June 22, 1998
|
|
|
|
.Dt STRLCPY 3
|
|
|
|
.Os
|
|
|
|
.Sh NAME
|
1999-08-10 05:58:58 +00:00
|
|
|
.Nm strlcpy ,
|
1999-08-10 05:21:31 +00:00
|
|
|
.Nm strlcat
|
|
|
|
.Nd size-bounded string copying and concatenation
|
2000-04-21 09:42:15 +00:00
|
|
|
.Sh LIBRARY
|
|
|
|
.Lb libc
|
1999-08-10 05:21:31 +00:00
|
|
|
.Sh SYNOPSIS
|
2001-10-01 16:09:29 +00:00
|
|
|
.In string.h
|
1999-08-10 05:21:31 +00:00
|
|
|
.Ft size_t
|
|
|
|
.Fn strlcpy "char *dst" "const char *src" "size_t size"
|
|
|
|
.Ft size_t
|
|
|
|
.Fn strlcat "char *dst" "const char *src" "size_t size"
|
|
|
|
.Sh DESCRIPTION
|
|
|
|
The
|
|
|
|
.Fn strlcpy
|
|
|
|
and
|
|
|
|
.Fn strlcat
|
2004-07-02 23:52:20 +00:00
|
|
|
functions copy and concatenate strings respectively.
|
|
|
|
They are designed
|
1999-08-10 05:21:31 +00:00
|
|
|
to be safer, more consistent, and less error prone replacements for
|
|
|
|
.Xr strncpy 3
|
|
|
|
and
|
|
|
|
.Xr strncat 3 .
|
|
|
|
Unlike those functions,
|
|
|
|
.Fn strlcpy
|
|
|
|
and
|
|
|
|
.Fn strlcat
|
|
|
|
take the full size of the buffer (not just the length) and guarantee to
|
|
|
|
NUL-terminate the result (as long as
|
|
|
|
.Fa size
|
2001-01-17 20:51:20 +00:00
|
|
|
is larger than 0 or, in the case of
|
|
|
|
.Fn strlcat ,
|
|
|
|
as long as there is at least one byte free in
|
|
|
|
.Fa dst ) .
|
|
|
|
Note that you should include a byte for the NUL in
|
1999-08-10 05:21:31 +00:00
|
|
|
.Fa size .
|
2001-01-17 20:51:20 +00:00
|
|
|
Also note that
|
2001-07-15 07:53:42 +00:00
|
|
|
.Fn strlcpy
|
2001-01-17 20:51:20 +00:00
|
|
|
and
|
|
|
|
.Fn strlcat
|
|
|
|
only operate on true
|
|
|
|
.Dq C
|
|
|
|
strings.
|
|
|
|
This means that for
|
|
|
|
.Fn strlcpy
|
|
|
|
.Fa src
|
|
|
|
must be NUL-terminated and for
|
|
|
|
.Fn strlcat
|
|
|
|
both
|
|
|
|
.Fa src
|
|
|
|
and
|
|
|
|
.Fa dst
|
|
|
|
must be NUL-terminated.
|
1999-08-10 05:21:31 +00:00
|
|
|
.Pp
|
|
|
|
The
|
|
|
|
.Fn strlcpy
|
|
|
|
function copies up to
|
|
|
|
.Fa size
|
|
|
|
- 1 characters from the NUL-terminated string
|
|
|
|
.Fa src
|
|
|
|
to
|
|
|
|
.Fa dst ,
|
|
|
|
NUL-terminating the result.
|
|
|
|
.Pp
|
|
|
|
The
|
|
|
|
.Fn strlcat
|
|
|
|
function appends the NUL-terminated string
|
|
|
|
.Fa src
|
|
|
|
to the end of
|
|
|
|
.Fa dst .
|
|
|
|
It will append at most
|
|
|
|
.Fa size
|
|
|
|
- strlen(dst) - 1 bytes, NUL-terminating the result.
|
|
|
|
.Sh RETURN VALUES
|
|
|
|
The
|
|
|
|
.Fn strlcpy
|
|
|
|
and
|
|
|
|
.Fn strlcat
|
|
|
|
functions return the total length of the string they tried to
|
2004-07-02 23:52:20 +00:00
|
|
|
create.
|
|
|
|
For
|
1999-08-10 05:21:31 +00:00
|
|
|
.Fn strlcpy
|
|
|
|
that means the length of
|
|
|
|
.Fa src .
|
|
|
|
For
|
|
|
|
.Fn strlcat
|
|
|
|
that means the initial length of
|
|
|
|
.Fa dst
|
|
|
|
plus
|
|
|
|
the length of
|
|
|
|
.Fa src .
|
|
|
|
While this may seem somewhat confusing it was done to make
|
|
|
|
truncation detection simple.
|
2001-07-24 11:32:29 +00:00
|
|
|
.Pp
|
|
|
|
Note however, that if
|
|
|
|
.Fn strlcat
|
|
|
|
traverses
|
|
|
|
.Fa size
|
|
|
|
characters without finding a NUL, the length of the string is considered
|
|
|
|
to be
|
|
|
|
.Fa size
|
|
|
|
and the destination string will not be NUL-terminated (since there was
|
|
|
|
no space for the NUL).
|
|
|
|
This keeps
|
|
|
|
.Fn strlcat
|
|
|
|
from running off the end of a string.
|
|
|
|
In practice this should not happen (as it means that either
|
|
|
|
.Fa size
|
|
|
|
is incorrect or that
|
|
|
|
.Fa dst
|
|
|
|
is not a proper
|
|
|
|
.Dq C
|
|
|
|
string).
|
|
|
|
The check exists to prevent potential security problems in incorrect code.
|
1999-08-10 05:21:31 +00:00
|
|
|
.Sh EXAMPLES
|
|
|
|
The following code fragment illustrates the simple case:
|
|
|
|
.Bd -literal -offset indent
|
|
|
|
char *s, *p, buf[BUFSIZ];
|
|
|
|
|
2000-12-29 14:08:20 +00:00
|
|
|
\&...
|
1999-08-10 05:21:31 +00:00
|
|
|
|
|
|
|
(void)strlcpy(buf, s, sizeof(buf));
|
|
|
|
(void)strlcat(buf, p, sizeof(buf));
|
|
|
|
.Ed
|
|
|
|
.Pp
|
|
|
|
To detect truncation, perhaps while building a pathname, something
|
|
|
|
like the following might be used:
|
|
|
|
.Bd -literal -offset indent
|
2000-11-19 11:29:58 +00:00
|
|
|
char *dir, *file, pname[MAXPATHLEN];
|
1999-08-10 05:21:31 +00:00
|
|
|
|
2000-12-29 14:08:20 +00:00
|
|
|
\&...
|
1999-08-10 05:21:31 +00:00
|
|
|
|
|
|
|
if (strlcpy(pname, dir, sizeof(pname)) >= sizeof(pname))
|
|
|
|
goto toolong;
|
|
|
|
if (strlcat(pname, file, sizeof(pname)) >= sizeof(pname))
|
|
|
|
goto toolong;
|
|
|
|
.Ed
|
|
|
|
.Pp
|
|
|
|
Since we know how many characters we copied the first time, we can
|
2001-07-24 11:32:29 +00:00
|
|
|
speed things up a bit by using a copy instead of an append:
|
1999-08-10 05:21:31 +00:00
|
|
|
.Bd -literal -offset indent
|
2001-07-24 11:32:29 +00:00
|
|
|
char *dir, *file, pname[MAXPATHLEN];
|
1999-08-10 05:21:31 +00:00
|
|
|
size_t n;
|
|
|
|
|
2000-12-29 14:08:20 +00:00
|
|
|
\&...
|
1999-08-10 05:21:31 +00:00
|
|
|
|
|
|
|
n = strlcpy(pname, dir, sizeof(pname));
|
|
|
|
if (n >= sizeof(pname))
|
|
|
|
goto toolong;
|
|
|
|
if (strlcpy(pname + n, file, sizeof(pname) - n) >= sizeof(pname) - n)
|
|
|
|
goto toolong;
|
|
|
|
.Ed
|
|
|
|
.Pp
|
|
|
|
However, one may question the validity of such optimizations, as they
|
|
|
|
defeat the whole purpose of
|
|
|
|
.Fn strlcpy
|
|
|
|
and
|
|
|
|
.Fn strlcat .
|
|
|
|
As a matter of fact, the first version of this manual page got it wrong.
|
|
|
|
.Sh SEE ALSO
|
|
|
|
.Xr snprintf 3 ,
|
1999-08-10 05:58:58 +00:00
|
|
|
.Xr strncat 3 ,
|
|
|
|
.Xr strncpy 3
|
1999-10-29 16:50:22 +00:00
|
|
|
.Sh HISTORY
|
2002-12-18 12:45:11 +00:00
|
|
|
The
|
1999-10-29 16:50:22 +00:00
|
|
|
.Fn strlcpy
|
|
|
|
and
|
|
|
|
.Fn strlcat
|
|
|
|
functions first appeared in
|
|
|
|
.Ox 2.4 ,
|
|
|
|
and made their appearance in
|
|
|
|
.Fx 3.3 .
|