strlcpy(3bsd)
π strlcpy, strlcat β size-bounded string copying and concatenation π
okay bestie, welcome to strlcpy(3bsd), a LOCAL manual page, and honestly? it's giving safety era. π these two are the glow-up versions of the string functions your CS professor warned you about.
π LIBRARY
Utility functions from BSD systems β that's libbsd, and you link it with -lbsd. β¨
β¨ SYNOPSIS β¨
#include <string.h>
(See libbsd(7) for include usage.)
size_t
strlcpy(char *dst, const char *src, size_t size);
size_t
strlcat(char *dst, const char *src, size_t size);
π«Ά tiny note from me to you: peep libbsd(7) for the whole include-usage situation, it's the plug.
π¦ DESCRIPTION π¦
okay so. strlcpy() and strlcat() copy and concatenate strings respectively. that's the whole job. but the way they do it is so much better than the old guard β they're designed to be safer, more consistent, and less error-prone replacements for strncpy(3) and strncat(3). no cap. π₯
here's the difference and it's a big one: unlike those other functions, strlcpy() and strlcat() take the full size of the buffer (not just the length, bestie, the whole size) and they guarantee to NUL-terminate the result. π
- that guarantee holds as long as
sizeis larger than0 - or, in the case of
strlcat(), as long as there's at least one byte free indst
π and pleaseeee remember: a byte for the NUL should be included in size. that's not optional, that's the vibe.
also note (this part matters): strlcpy() and strlcat() only operate on true βCβ strings. which means:
- for
strlcpy(),srcmust be NUL-terminated - for
strlcat(), bothsrcanddstmust be NUL-terminated
strlcpy() β copies up to size - 1 characters from the NUL-terminated string src to dst, NUL-terminating the result. π
strlcat() β 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 β
both functions return the total length of the string they tried to create. yes, tried. here's the breakdown:
- for
strlcpy()that means the length ofsrc - for
strlcat()that means the initial length ofdstplus the length ofsrc
and yeah, it may seem somewhat confusing at first, but it was done to make truncation detection simple. iykyk. π§
π however! heads up. ifstrlcat()traversessizecharacters without finding a NUL, the length of the string is considered to besize, and the destination string will not be NUL-terminated (since there was no space for the NUL). this keepsstrlcat()from running off the end of a string. in practice this should not happen (as it means that eithersizeis incorrect or thatdstis 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 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, 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 ofstrlcpy()andstrlcat(). as a matter of fact, the first version of this manual page got it wrong. iconic behaviour honestly. π
π SEE ALSO π
π HISTORY π
the strlcpy() and strlcat() functions first appeared in OpenBSD 2.4, and made their appearance in NetBSD 1.4.3, FreeBSD 3.3 and glibc 2.38. absolute main character energy, they've been everywhere. π
and that's the whole page, bestie π this one comes to you from <strong>Debian</strong>, dated <strong>January 7, 2024</strong>, under the <strong>strlcpy(3bsd)</strong> name β go forth and never overflow a buffer again. periodt. π β¨
π¦ where this page comes from
- alpine 3.22: libbsd-doc 0.12.2-r0 Β· BSD-3-Clause
- alpine 3.23: libbsd-doc 0.12.2-r0 Β· BSD-3-Clause
- alpine 3.24: libbsd-doc 0.12.2-r0 Β· BSD-3-Clause
- arch rolling: libbsd 0.12.2-2 Β· custom
- debian trixie: libbsd-dev 0.12.2-2
- epel 10: libbsd-devel 0.12.2-4.el10_0 Β· Beerware AND BSD-2-Clause AND BSD-3-Clause AND ISC AND libutil-David-Nugent AND MIT AND LicenseRef-Fedora-Public-Domain
- epel 9: libbsd-devel 0.12.2-1.el9 Β· Beerware AND BSD-2-Clause AND BSD-3-Clause AND ISC AND libutil-David-Nugent AND MIT AND LicenseRef-Fedora-Public-Domain
- fedora 43: libbsd-devel 0.12.2-6.fc43 Β· Beerware AND BSD-2-Clause AND BSD-3-Clause AND ISC AND libutil-David-Nugent AND MIT AND LicenseRef-Fedora-Public-Domain
- fedora 43: libbsd-devel 0.12.2-6.fc43 Β· Beerware AND BSD-2-Clause AND BSD-3-Clause AND ISC AND libutil-David-Nugent AND MIT AND LicenseRef-Fedora-Public-Domain
- fedora 44: libbsd-devel 0.12.2-7.fc44 Β· Beerware AND BSD-2-Clause AND BSD-3-Clause AND ISC AND libutil-David-Nugent AND MIT AND LicenseRef-Fedora-Public-Domain
- fedora 44: libbsd-devel 0.12.2-7.fc44 Β· Beerware AND BSD-2-Clause AND BSD-3-Clause AND ISC AND libutil-David-Nugent AND MIT AND LicenseRef-Fedora-Public-Domain
- nixos 26.05: libbsd 0.12.2
- ubuntu noble: libbsd-dev 0.12.1-1build1
- ubuntu noble: libbsd-dev 0.12.1-1build1.1
- ubuntu questing: libbsd-dev 0.12.2-2build1
- ubuntu resolute: libbsd-dev 0.12.2-2build2
- ubuntu stonking: libbsd-dev 0.12.2-3
- Copyright (c) 1998, 2000 Todd C. Miller <Todd.Miller@courtesan.com>
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms