<div dir="ltr">Foiled again by the google default of reply-only-to-one-person!<br><br><div class="gmail_quote">---------- Forwarded message ----------<br>From: <b class="gmail_sendername">Wesley W. Terpstra</b> <span dir="ltr">&lt;<a href="mailto:wesley@terpstra.ca">wesley@terpstra.ca</a>&gt;</span><br>
Date: Mon, Sep 15, 2008 at 4:04 PM<br>Subject: Re: [MLton-user] Linking (?) &#39;print&#39; means I can only run from the mingw command line<br>To: Vesa Karvonen &lt;<a href="mailto:vesa.a.j.k@gmail.com">vesa.a.j.k@gmail.com</a>&gt;<br>
<br><br><div dir="ltr"><div><div class="Ih2E3d">On Mon, Sep 15, 2008 at 3:36 PM, Vesa Karvonen <span dir="ltr">&lt;<a href="mailto:vesa.a.j.k@gmail.com" target="_blank">vesa.a.j.k@gmail.com</a>&gt;</span> wrote:<br><div class="gmail_quote">
<blockquote class="gmail_quote" style="border-left:1px solid rgb(204, 204, 204);margin:0pt 0pt 0pt 0.8ex;padding-left:1ex">
On Mon, Sep 15, 2008 at 2:30 PM, Wesley W. Terpstra &lt;<a href="mailto:wesley@terpstra.ca" target="_blank">wesley@terpstra.ca</a>&gt; wrote:<br>
[...]<br>
<div>&gt; I tend towards option #2. stdin&amp;out can come from openIn/Out &quot;NUL&quot;. However,<br>
&gt; if stderr is missing one loses exception information. Perhaps it could<br>
&gt; create a popup window. A TextPrimIO.writer that creates a window and adds<br>
&gt; text on write* calls shouldn&#39;t be that hard to implement.<br>
<br>
</div>BTW, this issue was also underlying the thread starting here:<br>
<br>
 &nbsp;<a href="http://mlton.org/pipermail/mlton/2007-June/029811.html" target="_blank">http://mlton.org/pipermail/mlton/2007-June/029811.html</a><br>
<br>
Basically, some code was failing and (IIRC) then the program went into<br>
an infinite memory hogging loop, because the default handler couldn&#39;t<br>
write to stderr.<br>
</blockquote></div><br></div>It seems a pretty easy failure mode affecting people compiling with &#39;-mwindows&#39;. I did a bit of hacking in C to see how it could work to create a console on demand and link stdin/out/err to it. I figure you could just ShowWindow when a write happens.<br>

<br></div><blockquote style="border-left:1px solid rgb(204, 204, 204);margin:0pt 0pt 0pt 0.8ex;padding-left:1ex" class="gmail_quote">#define _WIN32_WINNT 0x0500
<br>#include &lt;io.h&gt;
<br>#include &lt;fcntl.h&gt;
<br>#include &lt;stdint.h&gt;
<br>#include &lt;windows.h&gt;
<br>#include &lt;stdio.h&gt;
<br>&nbsp;<br>int main() {
<br>&nbsp; HWND console;
<br>&nbsp; BOOL existed;
<br>&nbsp; int in, out, err;
<br>&nbsp;&nbsp;
<br>&nbsp; existed = fileno(stdout) == 1;
<br>&nbsp;<br>&nbsp; if (!existed) {
<br>&nbsp;&nbsp;&nbsp; AllocConsole();
<br>&nbsp;&nbsp;&nbsp;&nbsp;
<br>&nbsp;&nbsp;&nbsp; console = GetConsoleWindow();
<br>&nbsp;&nbsp;&nbsp; // ShowWindow(console, SW_HIDE);
<br>&nbsp;<br>&nbsp;&nbsp;&nbsp; in&nbsp; = _open_osfhandle((intptr_t)GetStdHandle(STD_INPUT_HANDLE),&nbsp; _O_TEXT);
<br>&nbsp;&nbsp;&nbsp; out = _open_osfhandle((intptr_t)GetStdHandle(STD_OUTPUT_HANDLE), _O_TEXT);
<br>&nbsp;&nbsp;&nbsp; err = _open_osfhandle((intptr_t)GetStdHandle(STD_ERROR_HANDLE),&nbsp; _O_TEXT);
<br>&nbsp;&nbsp;&nbsp; dup2(in,&nbsp; 0); if (in&nbsp; &gt; 0) close(in);&nbsp; stdin -&gt;_file = 0;
<br>&nbsp;&nbsp;&nbsp; dup2(out, 1); if (out &gt; 1) close(out); stdout-&gt;_file = 1;
<br>&nbsp;&nbsp;&nbsp; dup2(err, 2); if (err &gt; 2) close(err); stderr-&gt;_file = 2;
<br>&nbsp;&nbsp;&nbsp; setvbuf(stdin,&nbsp; NULL, _IONBF, 0);
<br>&nbsp;&nbsp;&nbsp; setvbuf(stdout, NULL, _IOLBF, 4096);
<br>&nbsp;&nbsp;&nbsp; setvbuf(stderr, NULL, _IONBF, 0);
<br>&nbsp; }
<br>&nbsp;<br>&nbsp; printf(&quot;mooo!\n&quot;);
<br>&nbsp; fflush(stdout);
<br>&nbsp; write(1, &quot;baaa!\n&quot;, 6);
<br>&nbsp;<br>&nbsp; MessageBoxA(0, &quot;Click.&quot;, &quot;title&quot;, 0);
<br>&nbsp;<br>&nbsp;return 0;
<br>}
<br></blockquote><div><br>This code will only create a new console if needed. That means it will use the existing console of msys even if -mwindows. However, if -mwindows and run from explorer or command-line, it creates a console.<br>

<br>So if someone wants this to work in MLton, that code should probably be glued into some MLton_initStdio() method that gets called in the SML-side construction of stdOut/Err/In. That way it&#39;s only run if you actual might be using stdio. Somehow it also needs to be shown once a write occurs. I&#39;m not sure how to do this since linked C code might also printf.<br>

</div></div>
</div><br></div>