Hi Wilco, Here goes benchmark code for comparing performance of stpecpy(3) against strlcpy(3). I used my_strlcpy(3), with your definition, because I suspect libbsd's version won't be optimized. stpecpy(3) was also updated to be as optimized as I can write it. I won't be showing exact numbers, as that's probably very system- and version-dependent. Test yourself for exact numbers. However, I'll share the general results. At first I was a little bit surprised (and disappointed) because strlcpy(3) seemed faster under GCC. When forming the very short string "Hello, " "worlds" "!", in just 3 consecutive calls, my_strlcpy(3) outperforms (~10%) stpecpy() in GCC. In Clang they had both similar times. When I added a long string of 'x's, the results more or less were the same. When I added a few calls by repeating "worlds" "!", that changed the balance very significantly for stpecpy(3). When chaining more than just a couple calls, strlcpy(3) starts showing a performance decrease. With the code below, I saw stpecpy(3) consistently outperform strlcpy(3) by around 3%. I guess the advantage of strlcpy(3) over stpecpy(3) may be due to the overhead of setting 'end = buf + BUFSIZ;' for stpecpy(3), and to the fact that the first strlcpy(3) call doesn't have to do the usual '+=', ' + l', and ' - l', which can be significant given how negligible the internal difference between the two is. Cheers, Alex --- alx@debian:~/tmp$ cat foo.c #include #include #include void foo(char *buf, size_t *len) { char *p, *end; end = buf + BUFSIZ; p = buf; p = stpecpy(p, end, "Heylo, xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"); p = stpecpy(p, end, "worlds"); p = stpecpy(p, end, "!"); p = stpecpy(p, end, "worlds"); p = stpecpy(p, end, "!"); p = stpecpy(p, end, "worlds"); p = stpecpy(p, end, "!"); p = stpecpy(p, end, "worlds"); p = stpecpy(p, end, "!"); if (p == end) { p--; warnx("Truncated"); } *len = p - buf; } void bar(char *buf, size_t *len) { size_t l; l = my_strlcpy(buf, "Hello, xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", BUFSIZ); if (l >= BUFSIZ) goto toolong; l += my_strlcpy(buf + l, "worlds", BUFSIZ - l); if (l >= BUFSIZ) goto toolong; l += my_strlcpy(buf + l, "!", BUFSIZ - l); if (l >= BUFSIZ) goto toolong; l += my_strlcpy(buf + l, "worlds", BUFSIZ - l); if (l >= BUFSIZ) goto toolong; l += my_strlcpy(buf + l, "!", BUFSIZ - l); if (l >= BUFSIZ) goto toolong; l += my_strlcpy(buf + l, "worlds", BUFSIZ - l); if (l >= BUFSIZ) goto toolong; l += my_strlcpy(buf + l, "!", BUFSIZ - l); if (l >= BUFSIZ) goto toolong; l += my_strlcpy(buf + l, "worlds", BUFSIZ - l); if (l >= BUFSIZ) goto toolong; l += my_strlcpy(buf + l, "!", BUFSIZ - l); if (l >= BUFSIZ) { toolong: l = BUFSIZ - 1; warnx("Truncated"); } *len = l; } alx@debian:~/tmp$ cat bench.c #include int foo(char *buf, size_t *len); int bar(char *buf, size_t *len); int main(void) { char buf[BUFSIZ]; size_t len; for (size_t i = 0; i < 10000000; i++) #if 1 foo(buf, &len); #else bar(buf, &len); #endif printf("%zu: %s\n", len, buf); } --