@ -0,0 +1,71 @@ | |||
/* $OpenBSD: strlcat.c,v 1.1 1998/07/01 01:29:45 millert Exp $ */ | |||
/* | |||
* 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. | |||
*/ | |||
#if defined(LIBC_SCCS) && !defined(lint) | |||
static char *rcsid = "$OpenBSD: strlcat.c,v 1.1 1998/07/01 01:29:45 millert Exp $"; | |||
#endif /* LIBC_SCCS and not lint */ | |||
#include <sys/types.h> | |||
#include <string.h> | |||
/* | |||
* Appends src to string dst of size siz (unlike strncat, siz is the | |||
* full size of dst, not space left). At most siz-1 characters | |||
* will be copied. Always NUL terminates (unless siz == 0). | |||
* Returns strlen(src); if retval >= siz, truncation occurred. | |||
*/ | |||
size_t strlcat(dst, src, siz) | |||
char *dst; | |||
const char *src; | |||
size_t siz; | |||
{ | |||
register char *d = dst; | |||
register const char *s = src; | |||
register size_t n = siz; | |||
size_t dlen; | |||
/* Find the end of dst and adjust bytes left */ | |||
while (*d != '\0' && n != 0) | |||
d++; | |||
dlen = d - dst; | |||
n -= dlen; | |||
if (n == 0) | |||
return(dlen + strlen(s)); | |||
while (*s != '\0') { | |||
if (n != 1) { | |||
*d++ = *s; | |||
n--; | |||
} | |||
s++; | |||
} | |||
*d = '\0'; | |||
return(dlen + (s - src)); /* count does not include NUL */ | |||
} |
@ -0,0 +1,140 @@ | |||
.\" $OpenBSD: strlcpy.3,v 1.1 1998/07/01 01:29:45 millert Exp $ | |||
.\" | |||
.\" 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. | |||
.\" | |||
.Dd June 22, 1998 | |||
.Dt STRLCPY 3 | |||
.Os | |||
.Sh NAME | |||
.Nm strlcpy, | |||
.Nm strlcat | |||
.Nd size-bounded string copying and concatenation | |||
.Sh SYNOPSIS | |||
.Fd #include <string.h> | |||
.Ft char * | |||
.Fn strlcpy "char *dst" "const char *src" "size_t size" | |||
.Ft char * | |||
.Fn strlcat "char *dst" "const char *src" "size_t size" | |||
.Sh DESCRIPTION | |||
The | |||
.Fn strlcpy | |||
and | |||
.Fn strlcat | |||
functions copy and concatenate strings respectively. They are designed | |||
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 | |||
is larger than 0). Note that you should include a byte for the NUL in | |||
.Fa size . | |||
.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 | |||
create. For | |||
.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. | |||
.Sh EXAMPLES | |||
The following code fragment illustrates the simple case: | |||
.Bd -literal -offset indent | |||
char *s, *p, buf[BUFSIZ]; | |||
.Li ... | |||
(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 | |||
char *dir, *file, pname[MAXPATHNAMELEN]; | |||
.Li ... | |||
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 | |||
speed things up a bit by using a copy instead on an append: | |||
.Bd -literal -offset indent | |||
char *dir, *file, pname[MAXPATHNAMELEN]; | |||
size_t n; | |||
.Li ... | |||
n = strlcpy(pname, dir, sizeof(pname)); | |||
if (n >= sizeof(pname)) | |||
goto toolong; | |||
if (strlcpy(pname + n, file, sizeof(pname)) >= sizeof(pname) - n) | |||
goto toolong; | |||
.Ed | |||
.Sh SEE ALSO | |||
.Xr snprintf 3 , | |||
.Xr strncpy 3 , | |||
.Xr strncat 3 |
@ -0,0 +1,63 @@ | |||
/* $OpenBSD: strlcpy.c,v 1.1 1998/07/01 01:29:45 millert Exp $ */ | |||
/* | |||
* 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. | |||
*/ | |||
#if defined(LIBC_SCCS) && !defined(lint) | |||
static char *rcsid = "$OpenBSD: strlcpy.c,v 1.1 1998/07/01 01:29:45 millert Exp $"; | |||
#endif /* LIBC_SCCS and not lint */ | |||
#include <sys/types.h> | |||
#include <string.h> | |||
/* | |||
* Copy src to string dst of size siz. At most siz-1 characters | |||
* will be copied. Always NUL terminates (unless siz == 0). | |||
* Returns strlen(src); if retval >= siz, truncation occurred. | |||
*/ | |||
size_t strlcpy(dst, src, siz) | |||
char *dst; | |||
char *src; | |||
size_t siz; | |||
{ | |||
register char *d = dst; | |||
register const char *s = src; | |||
register size_t n = siz; | |||
if (n == 0) | |||
return(strlen(s)); | |||
while (*s != '\0') { | |||
if (n != 1) { | |||
*d++ = *s; | |||
n--; | |||
} | |||
s++; | |||
} | |||
*d = '\0'; | |||
return(s - src); /* count does not include NUL */ | |||
} |