Ensuring errno survives over leave_blocking_section until uerror is called

Summary

I was looking at how errno, leave_blocking_section and uerror interact, and although it all seems to work on Linux, I couldn’t find any guarantees that errno would indeed be preserved over leave_blocking_section (and you cannot call uerror without holding the runtime lock).

In fact POSIX says:

The value of errno should only be examined when it is indicated to be valid by a function’s return value
The setting of errno after a successful call to a function is unspecified unless the description of that function specifies that errno shall not be modified.

[This has similarities with how you must really get the backtrace of an exception immediately in the exception handler, before any other call had a chance to overwrite it. errno should be handled in a similar way]

I looked at the manpages of pthread_mutex_lock, and they don’t mention errno at all (these functions return error codes instead of setting errno, but the manpage is silent about whether they leave errno unchanged or not).

But leave_blocking_section does much more than that, it may end up calling functions in skiplist.c, including malloc. Although a failed malloc would set errno, the manpage again doesn’t specify that a succesful call doesn’t alter it.

In fact the way the OCaml runtime and C stubs typically use errno seems to fall into the “common mistake” pattern as documented by the Linux manpage.

I wonder whether leave_blocking_section should explicitly save/restore errno?

(In fact in OCaml 4.14 there used to be some code there that did something similar for Windows.)

P.S. the reason I looked into this is that I thought I observed a situation where errno was set incorrectly. But I was fooled by a Unix_error(11, ... error message being printed, where 11 was in fact EINTR, and not errno 11 (EAGAIN), so errno is correct in my application

[Edit] caml_leave_blocking_section in runtime/signals.c already does what I was suggesting since OCaml 4.01
I was mistakenly reading caml_thread_leave_blocking_section