Hi Paul, On Fri, Nov 10, 2023 at 09:58:42AM -0800, Paul Eggert wrote: > On 2023-11-10 03:05, Alejandro Colomar wrote: > > Hopefully, it won't be so bad in terms of performance. > > It's significantly slower than strncpy for typical use (smallish fixed-size > destination buffers). So just use strncpy for that. It may be bad, but it's > better than the alternatives you've mentioned. You can package strncpy > inside a [[nodiscard]] inline wrapper if you like. > > More importantly, the manual should not push strlcpy as being superior or > being in any way a "fix" for strncpy's problems. strlcpy is worse than > strncpy in important ways and besides - as mentioned in the glibc manual - > neither function is a good choice for string processing. Hmmmm, that sounds convincing. How about this as a starting point? diff --git a/man3/stpncpy.3 b/man3/stpncpy.3 index 3cf4eb371..3aff18106 100644 --- a/man3/stpncpy.3 +++ b/man3/stpncpy.3 @@ -67,6 +67,38 @@ .SH DESCRIPTION } .EE .in +.\" +.SS Copying a string with truncation +Although this function wasn't designed to copy a string with truncation, +it can be used with appropriate care for that purpose. +Such use is prone to off-by-one bugs, +so it is recommended that you write a wrapper function +that encloses all the danger. +.P +.in +4n +.EX +[[nodiscard]] +inline ssize_t +strxcpy(char *restrict dst, const char *restrict src, char dsize) +{ + char *p; + + p = stpncpy(dst, src, dsize); + if (dst[dsize - 1] != '\0') + return -1; + + return p - dst - 1; +} +.EE +.in +You could implement a similar function in terms of +.BR strlen (3) +and +.BR memcpy (3), +or in terms of +.BR strlcpy (3), +and it would be simpler, +but this implementation is faster. .SH RETURN VALUE .TP .BR strncpy () I used stpncpy(3), assuming it will have the same performance of strncpy(3), because it can be used to return the length. Cheers, Alex -- <https://www.alejandro-colomar.es/>
Attachment:
signature.asc
Description: PGP signature