Eshell has long had difficult-to-diagnose issues with I/O handles closing when they shouldn't, or not closing when they should. This is because the handles are refcounted entirely manually, and the actual code is very easy to get wrong: the location in the source code that increments the refcount is often distant from where it's decremented. I've fixed many of these issues over the last couple years and added tests covering them, but it's time to solve this for once and for all. By using 'unwind-protect', we can always ensure that the handles are cleaned up at the right time without having to have a perfect understanding of every disparate part of Eshell's command evaluation. Luckily, thanks to the previous work here, we have a thorough suite of regression tests, which made developing this patch a lot easier. This also fixes some remaining issues with I/O handles (see the new regression test).