diff --git a/misc/buffer-tests/HandleTests/CreateProcess_NewConsole.cc b/misc/buffer-tests/HandleTests/CreateProcess_NewConsole.cc new file mode 100755 index 0000000..8d51cf5 --- /dev/null +++ b/misc/buffer-tests/HandleTests/CreateProcess_NewConsole.cc @@ -0,0 +1,56 @@ +#include + +// +// Test CreateProcess when called with these parameters: +// - STARTF_USESTDHANDLES is not specified +// - bInheritHandles=FALSE or bInheritHandles=TRUE +// - CreationConsoleMode=NewConsole +// + +template +static void extend(std::vector &base, const std::vector &to_add) { + base.insert(base.end(), to_add.begin(), to_add.end()); +} + +REGISTER(Test_CreateProcess_NewConsole, always); +static void Test_CreateProcess_NewConsole() { + auto check = [](Worker &p, bool inheritHandles) { + auto c = p.child({ inheritHandles, CREATE_NEW_CONSOLE }); + if (isTraditionalConio()) { + checkInitConsoleHandleSet(c); + } else { + checkModernConsoleHandleInit(c, true, true, true); + } + return c; + }; + { + Worker p; + check(p, true); + check(p, false); + } + { + Worker p; + p.openConin(false).setStdin(); + p.newBuffer(false).setStdout().dup(true).setStderr(); + check(p, true); + check(p, false); + } + + if (isModernConio()) { + // The default Unbound console handles should be inheritable, so with + // bInheritHandles=TRUE, the child process should have six console + // handles, all usable. + Worker p; + auto c = check(p, true); + + std::vector expected; + extend(expected, handleInts(stdHandles(p))); + extend(expected, handleInts(stdHandles(c))); + std::sort(expected.begin(), expected.end()); + + auto correct = handleInts(c.scanForConsoleHandles()); + std::sort(correct.begin(), correct.end()); + + CHECK(expected == correct); + } +} diff --git a/misc/buffer-tests/HandleTests/CreateProcess_UseStdHandles.cc b/misc/buffer-tests/HandleTests/CreateProcess_UseStdHandles.cc index 6b7d4f9..9f7b69d 100755 --- a/misc/buffer-tests/HandleTests/CreateProcess_UseStdHandles.cc +++ b/misc/buffer-tests/HandleTests/CreateProcess_UseStdHandles.cc @@ -147,9 +147,6 @@ static void Test_CreateProcess_UseStdHandles() { } } } else { - auto nonReuseCheck = stdHandles(p); - nonReuseCheck.insert(nonReuseCheck.end(), - newHandles.begin(), newHandles.end()); ObjectSnap snap; bool consoleOpened[3] = {false, false, false}; for (int i = 0; i < 3; ++i) { @@ -176,8 +173,7 @@ static void Test_CreateProcess_UseStdHandles() { checkModernConsoleHandleInit(c, consoleOpened[0], consoleOpened[1], - consoleOpened[2], - nonReuseCheck); + consoleOpened[2]); } }; diff --git a/misc/buffer-tests/Makefile b/misc/buffer-tests/Makefile index 1c7e605..61f412c 100644 --- a/misc/buffer-tests/Makefile +++ b/misc/buffer-tests/Makefile @@ -45,6 +45,7 @@ HANDLETESTS_OBJECTS = \ build/obj/HandleTests/CreateProcess_DefaultInherit.o \ build/obj/HandleTests/CreateProcess_DefaultInherit_PseudoHandleBug.o \ build/obj/HandleTests/CreateProcess_DefaultInherit_XPPipeBug.o \ + build/obj/HandleTests/CreateProcess_NewConsole.o \ build/obj/HandleTests/CreateProcess_UseStdHandles.o \ build/obj/HandleTests/MiscTests.o \ build/obj/HandleTests/Modern.o \ diff --git a/misc/buffer-tests/harness/TestUtil.cc b/misc/buffer-tests/harness/TestUtil.cc index 7eed94a..268de82 100755 --- a/misc/buffer-tests/harness/TestUtil.cc +++ b/misc/buffer-tests/harness/TestUtil.cc @@ -225,16 +225,26 @@ bool isUnboundConsoleObject(RemoteHandle h) { } void checkModernConsoleHandleInit(RemoteWorker &proc, - bool in, bool out, bool err, - std::vector nonReuseCheck) { + bool in, bool out, bool err) { + // List all the usable console handles that weren't just opened. + std::vector preExistingHandles; + for (auto h : proc.scanForConsoleHandles()) { + if ((in && h.value() == proc.getStdin().value()) || + (out && h.value() == proc.getStdout().value()) || + (err && h.value() == proc.getStderr().value())) { + continue; + } + preExistingHandles.push_back(h); + } ObjectSnap snap; auto checkNonReuse = [&](RemoteHandle h) { - // The new Unbound console objects should not be inherited from - // anywhere else -- they should be brand new objects. - for (auto other : nonReuseCheck) { + // The Unbound console objects that were just opened should not be + // inherited from anywhere else -- they should be brand new objects. + for (auto other : preExistingHandles) { CHECK(!snap.eq(h, other)); } }; + if (in) { CHECK(isUsableConsoleInputHandle(proc.getStdin())); CHECK(isUnboundConsoleObject(proc.getStdin())); diff --git a/misc/buffer-tests/harness/TestUtil.h b/misc/buffer-tests/harness/TestUtil.h index e68f284..2a961f5 100755 --- a/misc/buffer-tests/harness/TestUtil.h +++ b/misc/buffer-tests/harness/TestUtil.h @@ -78,5 +78,4 @@ bool isUsableConsoleInputHandle(RemoteHandle h); bool isUsableConsoleOutputHandle(RemoteHandle h); bool isUnboundConsoleObject(RemoteHandle h); void checkModernConsoleHandleInit(RemoteWorker &proc, - bool in, bool out, bool err, - std::vector nonReuseCheck); + bool in, bool out, bool err);