errno is a macro on OS X and expands to this:
#define errno (*__error())
The reason for this is for thread safety. That means that in the debugger, if you want to see what the current value of errno is, you can type:
p *(int *)__error()
It’s important to remember that if you’re using errno, any system call can reset it. The following code is broken:
NSLog (@"errno: %d", errno); if (errno == EIO) ...
The call to NSLog can, and probably will, reset errno. On 10.6 calls to the free library function (which NSLog can call) will usually reset errno to 2 (ENOENT), so bear this in mind if you’re seeing an errno value of 2 when you wouldn’t expect it.
As a consequence of this, you cannot single step through code in Xcode when you have “Use Data Formatters” checked, and expect errno to be preserved. You will find in many cases errno is reset to 2. In fact, I would recommend turning off “Use Data Formatters”—they cause many problems. Hopefully lldb will bring a non-invasive method of inspecting variables.
Was this post born from bitter experience? Yes it was.