Comment 6 for bug 1256034

Revision history for this message
Wilfredo Velázquez-Rodríguez (zulu-inuoe) wrote :

After more testing it appears that this patch was incomplete.. arguably.

There's an error in the case where the calling process (the one invoking CreateProcess), (in this case cmd) has std handles. If the callee (in this case SBCL) calls GetStdHandle they will receive whatever was supplied through CreateProcess, which in a grand majority of cases is the stdio handles of the parent process.
These handles however, are not valid cross-process when the callee process (SBCL) is a GUI application (set by Subsystem) unless they're set up specifically for that purpose, such as a pipe.
Right now SBCL takes these bogus handles and attempts to operate on them. WinApi will fail in these cases.
Attached is a patch that verifies the validity of the std handles via GetFileType..

I believe this is the best approach for SBCL to take for usability purposes. Other environments fail on write 'silently' (WriteFile simply returns 0, printf returns 0, etc). But when we fail to write on SBCL we must signal an error (ANSI), which is typically a sledge-hammer in the cases where this is relevant.
For example, I ran into this issue because my program does many diagnostic (format t ...) calls which I can use by doing proper i/o redirection. I then invoked my program from the shell without i/o redirection and just crashed as soon as writes attempted to happen.

To compensate for this possibility I have three options:

  1)Handle the error at every format
  2)Delegate the format calls to a central function that has error handling (and update all my existing format calls)
  3)Rely on my output to always be properly redirected.. which in the Windows environment is not particularly reliable, seeing as even the standard provided cmd.exe fails to do this

Options 1 and 2 solve the issue for -my- code, but if I load some other library (quicklisp, etc) that does output, I'm more or less screwed unless I wrap all calls to code that -might- call other libraries with error handling.
Option 3 to me is barely even an option. It's what I'm doing right now just to get around this issue but to me seems to restrictive.

So, I make the argument that if SBCL is unable to meaningfully perform I/O due to circumstances outside of its control (OS handing it bogus io handles), it should be redirected to NUL and considered to 'always succeed'.

I apologize very much for my lack of proper testing of the previous fixes.