[Vm-dev] Identify console executable and standard one

Alistair Grant akgrant0710 at gmail.com
Sun Apr 15 07:17:04 UTC 2018


Hi Vincent,

On 15 April 2018 at 00:23, Eliot Miranda <eliot.miranda at gmail.com> wrote:
>
> Hi Vincent,
>
> On Sat, Apr 14, 2018 at 2:05 PM, <Vincent.Blondeau at lamresearch.com> wrote:
>>
>>
>>
>> Hi,
>>
>>
>>
>> I would like to know from inside the image whether the ST image is a console executable, e.g. PharoConsole.exe vs Pharo.exe (Related to this pull request: https://github.com/pharo-project/pharo/pull/694).
>>
>> The solution is to add a primitive inside the VM but I have no idea where I should look for…
>>
>> Could someone give me some pointers?
>
>
> A quick hack would be to use system attribute 0, the name of the executable:
>
> Smalltalk getSystemAttribute: 0 '/Users/eliot/oscogvm/build.macos64x64/squeak.cog.spur/Squeak.app/Contents/MacOS/Squeak'
>
> and match for Console.exe.  A more thorough approach on unix is to test stdin to see if it is attached to a tty.  Try this at a unix/macos terminal:
>
> $ tty
> /dev/ttys006
> $ tty </dev/null
> not a tty
> $ man 3 ttyname
> $ man 2 ioctl
>
> I'm not sure how to do this on Windows.  I wrote this in platforms/win32/vm/sqWin32Main.c::WinMain
>
> #if 0 /* This way used to work.  Does no longer. */
>   DWORD mode;
>
>   fIsConsole = GetConsoleMode(GetStdHandle(STD_INPUT_HANDLE), &mode);
> #elif 0 /* This does /not/ work with STD_INPUT_HANDLE or STD_OUTPUT_HANDLE */
>   CONSOLE_SCREEN_BUFFER_INFO csbi;
>
>   if ((fIsConsole = GetConsoleScreenBufferInfo
>                         (GetStdHandle(STD_INPUT_HANDLE), &csbi)))
>         fIsConsole = csbi.dwCursorPosition.X || csbi.dwCursorPosition.Y;
> #else /* This /does/ work; see */
>     /* https://stackoverflow.com/questions/9009333/how-to-check-if-the-program-is-run-from-a-console */
>   HWND consoleWnd = GetConsoleWindow();
>   DWORD dwProcessId;
>   GetWindowThreadProcessId(consoleWnd, &dwProcessId);
>   fIsConsole = GetCurrentProcessId() != dwProcessId;
> #endif
>
> but it seems like a hack to me.  I'd love to know what the approved future proof way is.

If you want to test it, the results of similar code is currently
available from within the image:

SQFile.isStdioStream for stdin notionally provides the information.

On Unix it is set in sqFileStdioHandlesInto() in sqFilePluginBasicPrims.c:

files[0].sessionID = thisSession;
files[0].file = stdin;
files[0].writable = false;
files[0].lastOp = READ_OP;
files[0].isStdioStream = isatty(fileno(stdin));
files[0].lastChar = EOF;


On Windows in sqFileStdioHandlesInto() in sqWin32FilePrims.c:

files[0].sessionID = thisSession;
files[0].file = GetStdHandle(STD_INPUT_HANDLE);
files[0].writable = false;
files[0].lastOp = 0; /* unused on win32 */
files[0].isStdioStream = GetConsoleMode(files[0].file, &mode) != 0;
AddHandleToTable(win32Files, files[0].file);


And SQFile is the byte array handle used in the file streams.

I've been thinking that it would be nice to be able to access the
structure from within the image, but haven't yet come up with a way to
automatically map the fields (Monty did some work which might help,
but I haven't looked at it yet).

Cheers,
Alistair


More information about the Vm-dev mailing list