Here [uerror] uses the global variable [errno]. The problem is that [leave_blocking_section] can run arbitrary code and so modify [errno]. It can run signal handlers for instance. Attached is an example of program where the call to select is expected to fail with EINTR but instead fails with EROFS.

But since this is very common I propose that [leave_blocking_section] saves and restores [errno].

Additional Information

let () =
(* Force initialization of the thread library. This modify
[caml_try_leave_blocking_section_hook] so that all
signals are executed by [caml_leave_blocking_section]
and never asynchronously. *)
ignore (Thread.self ());

errno should also be saved in handle_signal since it can be executed while the runtime system lock is released and this could break the C code. It seems to be common practice to save errno in signal handlers that can modify it.