static void test2()

in misc/ScreenBufferTest.cc [198:271]


static void test2(int argc, char *argv[]) {
    if (!strcmp(argv[1], "2")) {
        startChildProcess(L"2:parent");
        return;
    }

    if (!strcmp(argv[1], "2:parent")) {
        g_prefix = "parent: ";
        dumpHandles();
        HANDLE origBuffer = GetStdHandle(STD_OUTPUT_HANDLE);
        writeTest(origBuffer, "<-- origBuffer -->");

        HANDLE newBuffer = createBuffer();
        writeTest(newBuffer, "<-- newBuffer -->");
        setConsoleActiveScreenBuffer(newBuffer);

        Sleep(1000);
        writeTest(newBuffer, "bInheritHandles=FALSE:");
        startChildInSameConsole(L"2:child", FALSE);
        Sleep(1000);
        writeTest(newBuffer, "bInheritHandles=TRUE:");
        startChildInSameConsole(L"2:child", TRUE);

        Sleep(1000);
        trace("parent:----");

        // Close the new buffer.  The active screen buffer doesn't automatically
        // switch back to origBuffer, because the child process has a handle open
        // to the original buffer.
        closeHandle(newBuffer);

        Sleep(600 * 1000);
        return;
    }

    if (!strcmp(argv[1], "2:child")) {
        g_prefix = "child: ";
        dumpHandles();
        // The child's output isn't visible, because it's still writing to
        // origBuffer.
        trace("child:----");
        writeTest("writing to STDOUT");

        // Handle inheritability is curious.  The console handles this program
        // creates are inheritable, but CreateProcess is called with both
        // bInheritHandles=TRUE and bInheritHandles=FALSE.
        //
        // Vista and Windows 7: bInheritHandles has no effect.  The child and
        // parent processes have the same STDIN/STDOUT/STDERR handles:
        // 0x3, 0x7, and 0xB.  The parent has a 0xF handle for newBuffer.
        // The child can only write to 0x7, 0xB, and 0xF.  Only the writes to
        // 0xF are visible (i.e. they touch newBuffer).
        //
        // Windows 8 or Windows 10 (legacy or non-legacy): the lowest 2 bits of
        // the HANDLE to WriteConsole seem to be ignored.  The new process'
        // console handles always refer to the buffer that was active when they
        // started, but the values of the handles depend upon bInheritHandles.
        // With bInheritHandles=TRUE, the child has the same
        // STDIN/STDOUT/STDERR/newBuffer handles as the parent, and the three
        // output handles all work, though their output is all visible.  With
        // bInheritHandles=FALSE, the child has different STDIN/STDOUT/STDERR
        // handles, and only the new STDOUT/STDERR handles work.
        //
        for (unsigned int i = 0x1; i <= 0xB0; ++i) {
            char msg[256];
            sprintf(msg, "Write to handle 0x%x", i);
            HANDLE h = reinterpret_cast<HANDLE>(i);
            writeTest(h, msg);
        }

        Sleep(600 * 1000);
        return;
    }
}