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