strscpy always null terminates, unless the destination buffer has size zero. -E2BIG is returned when the entire string could not be copied. The return value is essentially strlen of the resulting string. It’s good all around.
Even with that, I still don't have enough information to safely invoke it. (What is count?)
These APIs are too complicated/subtle. Honestly, at this point, I just use (ptr, len) pairs that point to non-null terminated strings whenever possible.
I don’t usually call people out for moving the goalposts, but when it comes to string copying routines I get real cranky about it. Stop moving the goalposts. You want a string copying routine. Most suck. This is the good one. Or at least, it’s one in the family of good ones. You have a C-style string, you want it copied elsewhere, you want it to be mindful of the bounds you give it, you want it to not do something you didn’t ask it for, this does that. It’s not trivial to write one, I wrote a whole thing about how it’s not and how this is good. People did it right. Now, shut up.
No, seriously, shut up. After all that work you don’t get to go “uh, this is actually unsafe because what if the original string is not null terminated and the buffer is not actually the size you said it is”. That’s not how strings in C work. Strings in C work in exactly one way and you don’t get to change that, because that’s just how they work, and there’s 50 years of code that uses string copying routines that work with this that would very much like to have the holy grail of string copies and doesn’t need you muddying the waters and saying that this cannot be invoked safely. It can. The invariants are challenging to uphold but this implementation provides every accommodation that the C standard can provide to this API.
Every single time string copying comes up on Hacker News some enlightened commenter is like “yeah why even bother with this I’m just going to use pointer+length pairs and solve everything”. No. You don’t get to drag this discussion about a very real problem into your half-baked “solution” for C. You especially do not get to reply to me explaining exactly why this API improves upon the state of the art with a lazy dismissal where you retreat to something completely different and go “yeah this is way safer lol”. This would be like if I just responded “yeah I’d just use Rust here I don’t get what the deal is” to you. It doesn’t help.
Look, I’d love to have a conversation about fat pointers and alternative strings in C. I’d love to talk about how we can migrate all this code to safer languages. But this isn’t the time or place for that, and I’m sick of this discussion repeating every single time we talk about, for the love of god, projects that are using normal C strings and safer ways to work with them. It’s not just you but you responding to my comment with something I perceive as fundamentally uninspired set me off.