Here's a lightly tested implementation of strlprecat()
which more or less follows OpenBSD's 'strlxxx()' function style of:
- passing a length for the destination buffer,
- always terminating the resulting string (if the buffer size is greater than 0) and
- returning the length of the buffer required (not including the terminator character)
So this function will never result in a buffer overrun, but may result in a truncated string (destroying the original string in the buffer as a consequence).
Anyway, I've found a similar function to be occasionally useful:
size_t
strlprecat( char* dst, const char * src, size_t size)
{
size_t dstlen = strnlen( dst, size);
size_t srclen = strlen( src);
size_t srcChars = srclen;
size_t dstChars = dstlen;
if (0 == size) {
/* we can't write anything into the dst buffer */
/* -- bail out */
return( srclen + dstlen);
}
/* determine how much space we need to add to front of dst */
if (srcChars >= size) {
/* we can't even fit all of src into dst */
srcChars = size - 1;
}
/* now figure out how many of dst's characters will fit in the remaining buffer */
if ((srcChars + dstChars) >= size) {
dstChars = size - srcChars - 1;
}
/* move dst to new location, truncating if necessary */
memmove( dst+srcChars, dst, dstChars);
/* copy src into the spot we just made for it */
memcpy( dst, src, srcChars);
/* make sure the whole thing is terminated properly */
dst[srcChars + dstChars] = '\0';
return( srclen + dstlen);
}
Feel free to muck with this so it doesn't deal with a buffer length (blindly moves stuff to the desired place) or simply returns an error without doing anything if the buffer's not large enough.
Oh, and of course post a comment if you fix any bugs.