Your implementations is very fast, but with two quirks:
- One quirk is that your function writes two NUL-characters instead of one when there is enough space.
- Another quirk is the return value which doesn't indicate issues.
Apart from these quircks, your version is functionally equivalent to strxcpy()
by attractivechaos. However, your code is 30-100% faster depending on which machine I use. Good job in that respect!
Regarding the return value, here are the differences I observe:
the original strlcpy
returns length of src
:
- cons: unsafe, unnecessarily slow
- pros:
strlcpy(d,s,n)
is equivalent to snprintf(d,n,"%s",s)
strxcpy by attractivechaos returns number of bytes written:
- pros: return value doesn't clearly indicate an issue when src is too long
- cons: deviates from strlcpy in return value
your function returns length of the string length written:
- cons:
- return value doesn't clearly indicate an issue when src is too long
- return value doesn't indicate whether NUL-character was written or not
- pros: more in line with the original strlcpy.
In my preferred implementation all the mentioned functional disadvantages are fixed:
ssize_t safe_strlcpy(char *dst, const char *src, size_t size)
{
if (size == 0)
return -1;
size_t ret = strnlen(src, size);
size_t len = (ret >= size) ? size - 1 : ret;
memcpy(dst, src, len);
dst[len] = '\0';
return ret;
}
It returns size
when src
was too long and didn't fit entirely; -1 if size
is zero; otherwise - string length written. So, when everything is OK, the return value is still in line with strlcpy. And it's based on Git's implementation of the original strlcpy.