Windows CogVM stdOut?

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
3 messages Options
Reply | Threaded
Open this post in threaded view
|

Windows CogVM stdOut?

douglas mcpherson
I'm using FFI to call an external C function which performs a printf. On the Mac such output conveniently displays in Console.app. Anyone know how I can see these printfs on Windows ? I tried starting the image with Cog's CroquetConsole.exe but nothing gets displayed in the console. Ideas?

Thanks,
Doug
Reply | Threaded
Open this post in threaded view
|

Re: Windows CogVM stdOut?

Eliot Miranda-2
Hi DOug,

On Fri, Aug 17, 2012 at 1:57 PM, Douglas McPherson <[hidden email]> wrote:
I'm using FFI to call an external C function which performs a printf. On the Mac such output conveniently displays in Console.app. Anyone know how I can see these printfs on Windows ? I tried starting the image with Cog's CroquetConsole.exe but nothing gets displayed in the console. Ideas?

Thanks,
Doug

phhh... mingw :(.  The VM can write to stdout, but does so not using printf.  here's how it works, all code in platforms/win32/plugins/FilePlugin/sqWin32FilePrims.c.

When the CVM is asked for the stdin/out/err handles it does this for each handle:

    DWORD mode;
...
    files[0].sessionID = thisSession;
    files[0].file = GetStdHandle(STD_INPUT_HANDLE); // & STD_OUTPUT_HANDLE & 1 & STD_ERROR_HANDLE & 2
    files[0].fileSize = 0;
    files[0].writable = false;
    files[0].lastOp = 0; /* unused on win32 */
    files[0].isStdioStream = GetConsoleMode(files[0].file, &mode) != 0;

i.e. isStdioStream == GetConsoleMode(GetStdHandle(STD_INPUT_HANDLE), &mode) != 0;

Then when it wants to write it does

  if (f->isStdioStream)
    WriteConsole(FILE_HANDLE(f), (LPVOID) (byteArrayIndex + startIndex), count, &dwReallyWritten, NULL);
  else
    WriteFile(FILE_HANDLE(f), (LPVOID) (byteArrayIndex + startIndex), count, &dwReallyWritten, NULL);

and to read it does

  if (f->isStdioStream)
    ReadConsole(FILE_HANDLE(f), (LPVOID) (byteArrayIndex+startIndex), count,
                &dwReallyRead, NULL);
  else
    ReadFile(FILE_HANDLE(f), (LPVOID) (byteArrayIndex+startIndex), count,
             &dwReallyRead, NULL);

Now this doesn't really help you with printf, but if you can link your external C code you can redefine printf to invoke the above writing code.  Hence adapted from platforms/win32/vm/sqWin32Intel.c, do something like:

int __cdecl
printf(const char *fmt, ...)
{ va_list al;
  int result;

  va_start(al, fmt);
  wvsprintf(consoleBuffer, fmt, al);

// and then adapt the above to write to the console:
  if (f->isStdioStream)
    WriteConsole(FILE_HANDLE(f), consoleBuffer, strlen(consoleBuffer), &dwReallyWritten, NULL);
  else
    WriteFile(FILE_HANDLE(f), consoleBuffer, strlen(consoleBuffer), &dwReallyWritten, NULL);

  result = vfprintf(stdout, fmt, al);
  va_end(al);
  return result;
}

--
HTH,
Eliot



Reply | Threaded
Open this post in threaded view
|

Re: Windows CogVM stdOut?

douglas mcpherson
Thanks, Eliot!

On Aug 17, 2012, at 15:21 , Eliot Miranda wrote:

Hi DOug,

On Fri, Aug 17, 2012 at 1:57 PM, Douglas McPherson <[hidden email]> wrote:
I'm using FFI to call an external C function which performs a printf. On the Mac such output conveniently displays in Console.app. Anyone know how I can see these printfs on Windows ? I tried starting the image with Cog's CroquetConsole.exe but nothing gets displayed in the console. Ideas?

Thanks,
Doug

phhh... mingw :(.  The VM can write to stdout, but does so not using printf.  here's how it works, all code in platforms/win32/plugins/FilePlugin/sqWin32FilePrims.c.

When the CVM is asked for the stdin/out/err handles it does this for each handle:

    DWORD mode;
...
    files[0].sessionID = thisSession;
    files[0].file = GetStdHandle(STD_INPUT_HANDLE); // & STD_OUTPUT_HANDLE & 1 & STD_ERROR_HANDLE & 2
    files[0].fileSize = 0;
    files[0].writable = false;
    files[0].lastOp = 0; /* unused on win32 */
    files[0].isStdioStream = GetConsoleMode(files[0].file, &mode) != 0;

i.e. isStdioStream == GetConsoleMode(GetStdHandle(STD_INPUT_HANDLE), &mode) != 0;

Then when it wants to write it does

  if (f->isStdioStream)
    WriteConsole(FILE_HANDLE(f), (LPVOID) (byteArrayIndex + startIndex), count, &dwReallyWritten, NULL);
  else
    WriteFile(FILE_HANDLE(f), (LPVOID) (byteArrayIndex + startIndex), count, &dwReallyWritten, NULL);

and to read it does

  if (f->isStdioStream)
    ReadConsole(FILE_HANDLE(f), (LPVOID) (byteArrayIndex+startIndex), count,
                &dwReallyRead, NULL);
  else
    ReadFile(FILE_HANDLE(f), (LPVOID) (byteArrayIndex+startIndex), count,
             &dwReallyRead, NULL);

Now this doesn't really help you with printf, but if you can link your external C code you can redefine printf to invoke the above writing code.  Hence adapted from platforms/win32/vm/sqWin32Intel.c, do something like:

int __cdecl
printf(const char *fmt, ...)
{ va_list al;
  int result;

  va_start(al, fmt);
  wvsprintf(consoleBuffer, fmt, al);

// and then adapt the above to write to the console:
  if (f->isStdioStream)
    WriteConsole(FILE_HANDLE(f), consoleBuffer, strlen(consoleBuffer), &dwReallyWritten, NULL);
  else
    WriteFile(FILE_HANDLE(f), consoleBuffer, strlen(consoleBuffer), &dwReallyWritten, NULL);

  result = vfprintf(stdout, fmt, al);
  va_end(al);
  return result;
}

--
HTH,
Eliot