strlcat(), strlcpy()
Size-bounded string copying and concatenation
Synopsis:
#include <string.h> size_t strlcpy( char *dst, const char *src, size_t size ); size_t strlcat( char *dst, const char *src, size_t size );
Arguments:
- dst
- A pointer to the destination string.
- src
- A pointer to the source string.
- size
- The size of the destination buffer.
Library:
libc
Use the -l c option to qcc to link against this library. This library is usually included automatically.
Description:
The strlcpy() and strlcat() functions copy and concatenate strings respectively. They're designed to be safer, more consistent, and less error-prone replacements for strncpy() and strncat() .
Unlike those functions, strlcpy() and strlcat() take the full size of the buffer (not just the length) and guarantee to NUL-terminate the result (as long as size is larger than 0 or, in the case of strlcat(), as long as there's at least one byte free in dst).
The strlcpy() function copies up to size − 1 characters from the NUL-terminated string src to dst, NUL-terminating the result.
The strlcat() function appends the NUL-terminated string src to the end of dst. It will append at most size − strlen(dst) − 1 bytes, NUL-terminating the result.
Returns:
The total length of the string:
- For strlcpy() that means the length of src.
- For strlcat() that means the initial length of dst plus the length of src. While this may seem somewhat confusing, it was done to make truncation detection simple.
Examples:
The following code fragment illustrates the simple case:
char *s, *p, buf[BUFSIZ]; ... (void)strlcpy(buf, s, sizeof(buf)); (void)strlcat(buf, p, sizeof(buf));
To detect truncation, perhaps while building a pathname, you could use something like this:
char *dir, *file, pname[MAXPATHLEN]; ... if (strlcpy(pname, dir, sizeof(pname)) >= sizeof(pname)) goto toolong; if (strlcat(pname, file, sizeof(pname)) >= sizeof(pname)) goto toolong;
Since we know how many characters we copied the first time, we can speed things up a bit by using a copy instead of an append:
char *dir, *file, pname[MAXPATHLEN]; size_t n; ... 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;
However, one may question the validity of such optimizations, as they defeat the whole purpose of strlcpy() and strlcat().
Classification:
Safety: | |
---|---|
Cancellation point | No |
Interrupt handler | Yes |
Signal handler | Yes |
Thread | Yes |
Contributing author:
OpenBSD