In my last post, I introduced a basic error handling mechanism for C API. The code I showed had a small memory leak in it. I love that fact about it, because it is hidden away and probably won’t show up very easily for production code until very late in the game. Here is the fix:
The problem was that I was freeing the error struct, but wasn’t freeing the actual error message. That is something that is very easy to miss, unfortunately. Especially as we assume that errors are rare. With that minor issue out of the way, let’s look at how we actually write the code. Here is the updated version of creating a connection, with proper error handling:
The calling code will check if it got NULL and then can decide whatever it should add it’s own error (for context) and return a failure to its own caller or handle it. The cleanup stuff is still annoying with goto, but I don’t believe that there is much that can be done about it.
I’m going to refactored things a bit, so I have proper separation and an explicit API. Here is what the API looks like now:
This is basically a wrapper around all the things we need to around SSL. It handles one time initialization and any other necessary work that is required. Note that I don’t actually expose any state outside, instead just forward declaring the state struct and leaving it at that. In addition to the overall server state, there is also a single connection state, whose API looks like this:
Now, let’s bring it all together and see how it works.
This is a pretty trivial echo server, I’ll admit, but it actually handles things like SSL setup, good error handling and give us a good baseline to start from.
More posts in "Refactoring C Code" series:
- (12 Dec 2018) Going to async I/O
- (10 Dec 2018) Do we need a security review?
- (07 Dec 2018) Implementing parsing
- (04 Dec 2018) Multi platform and Valgrind
- (03 Dec 2018) Choosing the next direction
- (30 Nov 2018) Giving good SSL errors to your client…
- (29 Nov 2018) Starting with an API
- (27 Nov 2018) Error handling is HARD, error REPORTING is much harder