1.\" $OpenBSD: strlcpy.3,v 1.19 2007/05/31 19:19:32 jmc Exp $ 2.\" 3.\" Copyright (c) 1998, 2000 Todd C. Miller <Todd.Miller@courtesan.com> 4.\" 5.\" Permission to use, copy, modify, and distribute this software for any 6.\" purpose with or without fee is hereby granted, provided that the above 7.\" copyright notice and this permission notice appear in all copies. 8.\" 9.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 10.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 11.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 12.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 13.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 14.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 15.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 16.\" 17.Dd $Mdocdate: May 31 2007 $ 18.Dt STRLCPY 3 19.Os 20.Sh NAME 21.Nm strlcpy , 22.Nm strlcat 23.Nd size-bounded string copying and concatenation 24.Sh SYNOPSIS 25.Fd #include <string.h> 26.Ft size_t 27.Fn strlcpy "char *dst" "const char *src" "size_t size" 28.Ft size_t 29.Fn strlcat "char *dst" "const char *src" "size_t size" 30.Sh DESCRIPTION 31The 32.Fn strlcpy 33and 34.Fn strlcat 35functions copy and concatenate strings respectively. 36They are designed 37to be safer, more consistent, and less error prone replacements for 38.Xr strncpy 3 39and 40.Xr strncat 3 . 41Unlike those functions, 42.Fn strlcpy 43and 44.Fn strlcat 45take the full size of the buffer (not just the length) and guarantee to 46NUL-terminate the result (as long as 47.Fa size 48is larger than 0 or, in the case of 49.Fn strlcat , 50as long as there is at least one byte free in 51.Fa dst ) . 52Note that a byte for the NUL should be included in 53.Fa size . 54Also note that 55.Fn strlcpy 56and 57.Fn strlcat 58only operate on true 59.Dq C 60strings. 61This means that for 62.Fn strlcpy 63.Fa src 64must be NUL-terminated and for 65.Fn strlcat 66both 67.Fa src 68and 69.Fa dst 70must be NUL-terminated. 71.Pp 72The 73.Fn strlcpy 74function copies up to 75.Fa size 76- 1 characters from the NUL-terminated string 77.Fa src 78to 79.Fa dst , 80NUL-terminating the result. 81.Pp 82The 83.Fn strlcat 84function appends the NUL-terminated string 85.Fa src 86to the end of 87.Fa dst . 88It will append at most 89.Fa size 90- strlen(dst) - 1 bytes, NUL-terminating the result. 91.Sh RETURN VALUES 92The 93.Fn strlcpy 94and 95.Fn strlcat 96functions return the total length of the string they tried to create. 97For 98.Fn strlcpy 99that means the length of 100.Fa src . 101For 102.Fn strlcat 103that means the initial length of 104.Fa dst 105plus 106the length of 107.Fa src . 108While this may seem somewhat confusing, it was done to make 109truncation detection simple. 110.Pp 111Note, however, that if 112.Fn strlcat 113traverses 114.Fa size 115characters without finding a NUL, the length of the string is considered 116to be 117.Fa size 118and the destination string will not be NUL-terminated (since there was 119no space for the NUL). 120This keeps 121.Fn strlcat 122from running off the end of a string. 123In practice this should not happen (as it means that either 124.Fa size 125is incorrect or that 126.Fa dst 127is not a proper 128.Dq C 129string). 130The check exists to prevent potential security problems in incorrect code. 131.Sh EXAMPLES 132The following code fragment illustrates the simple case: 133.Bd -literal -offset indent 134char *s, *p, buf[BUFSIZ]; 135 136\&... 137 138(void)strlcpy(buf, s, sizeof(buf)); 139(void)strlcat(buf, p, sizeof(buf)); 140.Ed 141.Pp 142To detect truncation, perhaps while building a pathname, something 143like the following might be used: 144.Bd -literal -offset indent 145char *dir, *file, pname[MAXPATHLEN]; 146 147\&... 148 149if (strlcpy(pname, dir, sizeof(pname)) >= sizeof(pname)) 150 goto toolong; 151if (strlcat(pname, file, sizeof(pname)) >= sizeof(pname)) 152 goto toolong; 153.Ed 154.Pp 155Since it is known how many characters were copied the first time, things 156can be sped up a bit by using a copy instead of an append: 157.Bd -literal -offset indent 158char *dir, *file, pname[MAXPATHLEN]; 159size_t n; 160 161\&... 162 163n = strlcpy(pname, dir, sizeof(pname)); 164if (n >= sizeof(pname)) 165 goto toolong; 166if (strlcpy(pname + n, file, sizeof(pname) - n) >= sizeof(pname) - n) 167 goto toolong; 168.Ed 169.Pp 170However, one may question the validity of such optimizations, as they 171defeat the whole purpose of 172.Fn strlcpy 173and 174.Fn strlcat . 175As a matter of fact, the first version of this manual page got it wrong. 176.Sh SEE ALSO 177.Xr snprintf 3 , 178.Xr strncat 3 , 179.Xr strncpy 3 180.Sh HISTORY 181The 182.Fn strlcpy 183and 184.Fn strlcat 185functions first appeared in 186.Ox 2.4 . 187