STRLCPY(3)

STRLCPY(3) | Library Functions Manual | STRLCPY(3)

# NAME

`strlcpy`, `strlcat` —
size-bounded string copying and concatenation

# LIBRARY

Standard C Library (libc, -lc)

# 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);

# DESCRIPTION

The `strlcpy`() and `strlcat`() functions copy and concatenate strings respectively. They are designed to be safer, more consistent, and less error prone replacements for strncpy(3) and strncat(3). 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 is at least one byte free in dst). Note that you should include a byte for the NUL in size. Also note that `strlcpy`() and `strlcat`() only operate on true “C” strings. This means that for `strlcpy`() src must be NUL-terminated and for `strlcat`() both src and dst must be NUL-terminated.

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.

# RETURN VALUES

The `strlcpy`() and `strlcat`() functions return the total length of the string they tried to create. 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.

Note however, that if `strlcat`() traverses size characters without finding a NUL, the length of the string is considered to be size and the destination string will not be NUL-terminated (since there was no space for the NUL). This keeps `strlcat`() from running off the end of a string. In practice this should not happen (as it means that either size is incorrect or that dst is not a proper “C” string). The check exists to prevent potential security problems in incorrect code.

# 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, something like the following might be used:

    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`().

# SEE ALSO

snprintf(3), strncat(3), strncpy(3)

Todd C. Miller and Theo de Raadt, strlcpy and strlcat -- Consistent, Safe, String Copy and Concatenation, Proceedings of the FREENIX Track: 1999 USENIX Annual Technical Conference, USENIX Association, http://www.usenix.org/publications/library/proceedings/usenix99/full_papers/millert/millert.pdf, June 6-11, 1999.

# HISTORY

The `strlcpy`() and `strlcat`() functions first appeared in OpenBSD 2.4, then in NetBSD 1.4.3 and FreeBSD 3.3.

March 1, 2001 | NetBSD 9.5