C has unions. C has sum types. People have been doing tagged unions in C for longer than rust has been a language
I don't think I've ever seen a C function that uses unions for this purpose though?
I can think of two common patterns that I've seen frequently:
* Return NULL for errors (sometimes with a global errorno() function).
* Return an integer error with any return values as out parameters.
So if it is possible to improve, why doesn't anyone do it?
Yet the authors of crypt did not use them. The C language is not designed in a way to encourage people to write code that correctly uses tagged unions (or nullable pointers for that matter).
It is extremely unidiomatic to use tagged unions in C for error handling. It's definitely possible, but awkward, and the compiler doesn't check that you checked the tag.