MirBSD manpage: strlcat(3), strlcpy(3)

STRLCPY(3)                 BSD Programmer's Manual                  STRLCPY(3)


     strlcpy, strlcat - size-bounded string copying and concatenation


     #include <string.h>

     strlcpy(char *dst, const char *src, size_t dstsize);

     strlcat(char *dst, const char *src, size_t dstsize);


     The strlcpy() and strlcat() functions copy and concatenate strings with
     the same input parameters and output results as snprintf(3). They are
     designed to be safer, more consistent and less error-prone replacements
     for the easily misused functions strncpy(3) and strncat(3).

     strlcpy() and strlcat() take the full size of the destination buffer and
     guarantee NUL termination if there is room. Note that room for the NUL
     should be included in dstsize.

     strlcpy() copies up to dstsize - 1 characters from the string src to dst,
     NUL-terminating the result if dstsize is not 0.

     strlcat() appends the string src to the end of dst. It will append at
     most dstsize - strlen(dst) - 1 characters. It will then NUL-terminate,
     unless dstsize is 0 or the original dst string was longer than dstsize
     (in practice, this should not happen, as it means that either dstsize is
     incorrect or dst was not a proper string).

     If the src and dst strings overlap, the behaviour is undefined.


     Besides quibbles over the return type (size_t versus int) and signal
     handler safety (snprintf(3) is not entirely safe on some systems), the
     following two are equivalent:

           n = strlcpy(dst, src, len);
           n = snprintf(dst, len, "%s", src);

     Similarily, these are equivalent:

           n = strlcat(dst, src, len);
           n = snprintf(dst, len, "%s%s", dst, src);

     Like snprintf(3), the strlcpy() and strlcat() functions return the total
     length of the string they tried to create, not including the trailing
     NUL. For strlcpy() that means the length of src. For strlcat() that means
     the initial length of dst plus the length of src.

     If the return value is >= dstsize, the output string has been truncated.
     It is the caller's responsibility to handle this.


     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, fn[PATH_MAX];


           if (strlcpy(fn, dir, sizeof(fn)) >= sizeof(fn))
                   goto toolong;
           if (strlcat(fn, file, sizeof(fn)) >= sizeof(fn))
                   goto toolong;

     Since it is known how many characters were copied the first time, things
     can be sped up a bit by using a copy instead of an append:

           char *dir, *file, fn[PATH_MAX];
           size_t n;


           if ((n = strlcpy(fn, dir, sizeof(fn))) >= sizeof(fn))
                   goto toolong;
           if (strlcpy(fn + n, file, sizeof(fn) - n) >= sizeof(fn) - n)
                   goto toolong;

     However, one may question the validity of such optimizations, as their
     complexity defeats the whole purpose of strlcpy() and strlcat() - as a
     matter of fact, the first version within this manual page got it wrong.


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


     strlcpy() and strlcat() first appeared in OpenBSD 2.4.

     Overlapping strings were made into undefined behaviour in 2013; it was
     legitimate before. Mac OSX or standalone fortify-headers (usually with
     musl libc) terminate programs passing too large dstsize or overlapping
     dst and src arguments with SIGILL; unfortunately, neither of these has
     the decency to warn about this at compile time.


     Todd C. Miller <millert@openbsd.org> created strlcpy() and strlcat().

MirBSD #10-current              March 17, 2021                               1

Generated on 2022-12-24 01:00:14 by $MirOS: src/scripts/roff2htm,v 1.113 2022/12/21 23:14:31 tg Exp $ — This product includes material provided by mirabilos.

These manual pages and other documentation are copyrighted by their respective writers; their sources are available at the project’s CVSweb, AnonCVS and other mirrors. The rest is Copyright © 2002–2022 MirBSD.

This manual page’s HTML representation is supposed to be valid XHTML/1.1; if not, please send a bug report — diffs preferred.

Kontakt / Impressum & Datenschutzerklärung