#if defined(_WIN32)
+
+
+/**
+ * Checks whether given standard device (standard input, standard output,
+ * or standard error) has been redirected to an on-disk file/pipe.
+ * Win32-only.
+ *
+ * @param[in] nStdHandle The standard device number.
+ *
+ * @return TRUE if device redirected to a file/pipe.
+ */
+
+static gboolean
+VMToolsIsRedirected(DWORD nStdHandle)
+{
+ HANDLE handle = GetStdHandle(nStdHandle);
+ DWORD type = handle ? GetFileType(handle) : FILE_TYPE_UNKNOWN;
+
+ return type == FILE_TYPE_DISK || type == FILE_TYPE_PIPE;
+}
+
+
/**
* Attaches a console to the current process. If the parent process already has
* a console open, reuse it. Otherwise, create a new console for the current
VMTools_AttachConsole(void)
{
typedef BOOL (WINAPI *AttachConsoleFn)(DWORD);
- gboolean ret = FALSE;
+ gboolean ret = TRUE;
AttachConsoleFn _AttachConsole;
+ BOOL reopenStdout, reopenStderr;
if (GetConsoleWindow() != NULL) {
- return TRUE;
+ goto exit;
+ }
+
+ reopenStdout = !VMToolsIsRedirected(STD_OUTPUT_HANDLE);
+ reopenStderr = !VMToolsIsRedirected(STD_ERROR_HANDLE);
+ if (!reopenStdout && !reopenStderr) {
+ goto exit;
}
_AttachConsole = (AttachConsoleFn) GetProcAddress(GetModuleHandleW(L"kernel32.dll"),
"AttachConsole");
if ((_AttachConsole != NULL && _AttachConsole(ATTACH_PARENT_PROCESS)) ||
AllocConsole()) {
- FILE* fptr;
-
- fptr = _wfreopen(L"CONOUT$", L"a", stdout);
- if (fptr == NULL) {
- g_warning("_wfreopen failed for stdout/CONOUT$: %d (%s)",
- errno, strerror(errno));
- goto exit;
+ FILE *fptr;
+
+ if (reopenStdout) {
+ fptr = _wfreopen(L"CONOUT$", L"a", stdout);
+ if (fptr == NULL) {
+ g_warning("_wfreopen failed for stdout/CONOUT$: %d (%s)",
+ errno, strerror(errno));
+ ret = FALSE;
+ }
}
- fptr = _wfreopen(L"CONOUT$", L"a", stderr);
- if (fptr == NULL) {
- g_warning("_wfreopen failed for stderr/CONOUT$: %d (%s)",
- errno, strerror(errno));
- goto exit;
+ if (reopenStderr) {
+ fptr = _wfreopen(L"CONOUT$", L"a", stderr);
+ if (fptr == NULL) {
+ g_warning("_wfreopen failed for stderr/CONOUT$: %d (%s)",
+ errno, strerror(errno));
+ ret = FALSE;
+ } else {
+ setvbuf(fptr, NULL, _IONBF, 0);
+ }
}
- setvbuf(fptr, NULL, _IONBF, 0);
- ret = TRUE;
}
exit: