Fwd: [MLton-user] Linking (?) 'print' means I can only run from the
mingw command line
Wesley W. Terpstra
wesley at terpstra.ca
Mon Sep 15 12:18:12 PDT 2008
Foiled again by the google default of reply-only-to-one-person!
---------- Forwarded message ----------
From: Wesley W. Terpstra <wesley at terpstra.ca>
Date: Mon, Sep 15, 2008 at 4:04 PM
Subject: Re: [MLton-user] Linking (?) 'print' means I can only run from the
mingw command line
To: Vesa Karvonen <vesa.a.j.k at gmail.com>
On Mon, Sep 15, 2008 at 3:36 PM, Vesa Karvonen <vesa.a.j.k at gmail.com> wrote:
> On Mon, Sep 15, 2008 at 2:30 PM, Wesley W. Terpstra <wesley at terpstra.ca>
> wrote:
> [...]
> > I tend towards option #2. stdin&out can come from openIn/Out "NUL".
> However,
> > if stderr is missing one loses exception information. Perhaps it could
> > create a popup window. A TextPrimIO.writer that creates a window and adds
> > text on write* calls shouldn't be that hard to implement.
>
> BTW, this issue was also underlying the thread starting here:
>
> http://mlton.org/pipermail/mlton/2007-June/029811.html
>
> Basically, some code was failing and (IIRC) then the program went into
> an infinite memory hogging loop, because the default handler couldn't
> write to stderr.
>
It seems a pretty easy failure mode affecting people compiling with
'-mwindows'. 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.
#define _WIN32_WINNT 0x0500
> #include <io.h>
> #include <fcntl.h>
> #include <stdint.h>
> #include <windows.h>
> #include <stdio.h>
>
> int main() {
> HWND console;
> BOOL existed;
> int in, out, err;
>
> existed = fileno(stdout) == 1;
>
> if (!existed) {
> AllocConsole();
>
> console = GetConsoleWindow();
> // ShowWindow(console, SW_HIDE);
>
> in = _open_osfhandle((intptr_t)GetStdHandle(STD_INPUT_HANDLE),
> _O_TEXT);
> out = _open_osfhandle((intptr_t)GetStdHandle(STD_OUTPUT_HANDLE),
> _O_TEXT);
> err = _open_osfhandle((intptr_t)GetStdHandle(STD_ERROR_HANDLE),
> _O_TEXT);
> dup2(in, 0); if (in > 0) close(in); stdin ->_file = 0;
> dup2(out, 1); if (out > 1) close(out); stdout->_file = 1;
> dup2(err, 2); if (err > 2) close(err); stderr->_file = 2;
> setvbuf(stdin, NULL, _IONBF, 0);
> setvbuf(stdout, NULL, _IOLBF, 4096);
> setvbuf(stderr, NULL, _IONBF, 0);
> }
>
> printf("mooo!\n");
> fflush(stdout);
> write(1, "baaa!\n", 6);
>
> MessageBoxA(0, "Click.", "title", 0);
>
> return 0;
> }
>
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.
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's only run if you actual might be
using stdio. Somehow it also needs to be shown once a write occurs. I'm not
sure how to do this since linked C code might also printf.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://mlton.org/pipermail/mlton-user/attachments/20080915/bb14d42c/attachment.htm
More information about the MLton-user
mailing list