Из программы C++ можно ли проверить, перенаправляется ли stderr в stdout или наоборот? В основном я хочу знать, указывают ли эти два дескриптора файла на одно и то же место. Решения, специфичные для платформы, с использованием встроенных API-интерфейсов в порядке.Проверьте программу, если stderr перенаправлен на stdout
ответ
Linux, возможно, другие unix-понравятся: fstat и fds и сравнить dev: ino pairs.
Это, кажется, хорошо работает для моих нужд, спасибо! Теперь мне просто нужно решение для Windows ... – usta
для окон 7 и более поздних консольных ручек - это настоящие файловые дескрипторы (на XP это не правда, про Vista - не помню). мы можем получить эту 2 ручки по телефону GetStdHandle с STD_OUTPUT_HANDLE и STD_ERROR_HANDLE. но затем нужно как-то сравнить файлы с помощью дескриптора. это не равное прямое сравнение обрабатывает значения - потому что две разные ручки могут указывать на один и тот же файл. даже если мы получили указатель на FILE_OBJECT из дескриптора (это возможно из пользовательского режима) - два разных файла FILE_OBJECT могут указывать на один и тот же файл (если говорить о файлах файловой системы). так что лучший способ здесь, я думаю, - получить имена обоих файлов - и сравнить - они равны. это может быть сделано ZwQueryObject. код может быть, как это
NTSTATUS QueryName(HANDLE hFile, PUNICODE_STRING Name)
{
union {
PVOID buf;
POBJECT_NAME_INFORMATION poni;
};
static volatile UCHAR guz;
PVOID stack = alloca(guz);
ULONG cb = 0, rcb = 512;
NTSTATUS status;
do
{
if (cb < rcb)
{
cb = RtlPointerToOffset(buf = alloca(rcb - cb), stack);
}
if (0 <= (status = ZwQueryObject(hFile, ObjectNameInformation, buf, cb, &rcb)))
{
return RtlDuplicateUnicodeString(0, &poni->Name, Name);
}
} while (status == STATUS_BUFFER_TOO_SMALL || status == STATUS_BUFFER_OVERFLOW);
return status;
}
NTSTATUS AreFilesTheSame(HANDLE h1, HANDLE h2, PBOOL pb)
{
if (h1 == h2)
{
*pb = TRUE;
return STATUS_SUCCESS;
}
if (!h1 || !h2)
{
*pb = FALSE;
return STATUS_SUCCESS;
}
UNICODE_STRING name1, name2;
NTSTATUS status;
if (0 <= (status = QueryName(h1, &name1)))
{
if (0 <= (status = QueryName(h2, &name2)))
{
*pb = RtlEqualUnicodeString(&name1, &name2, TRUE);
RtlFreeUnicodeString(&name2);
}
RtlFreeUnicodeString(&name1);
}
return status;
}
BOOL b;
AreFilesTheSame(GetStdHandle(STD_OUTPUT_HANDLE), GetStdHandle(STD_ERROR_HANDLE), &b);
но хр это будет не работать
Спасибо! Наконец, я должен скомпилировать и связать этот код с Windows 7, но, к сожалению, он не работает по желанию. Даже при запуске программы с '2> & 1', имена различаются, например. '\ REGISTRY \ MACHINE \ SOFTWARE \ Microsoft \ Windows NT \ CurrentVersion \ Image File Execut' ... для stdout и' \ KnownDlls' ... для stderr. Этот код работает по вашему желанию? – usta
Также, когда данный дескриптор является трубой, то есть когда выход программы перенаправляется во вход другой программы, 'NtQueryObject()' терпит неудачу с 'STATUS_OBJECT_PATH_INVALID' (0xc0000039). – usta
@usta - конечно этот код работа. и NtQueryObject не может вернуть STATUS_OBJECT_PATH_INVALID – RbMm
- 1. Командный выход (stdout, stderr) не перенаправлен на трубу
- 2. Сообщите, если STDOUT Perl Script перенаправлен
- 3. Проверьте, перенаправлен ли файл Windows на себя
- 4. Почему STDERR перенаправляется на STDOUT
- 5. Как перенаправить 'stdout' в 'stderr' и 'stderr' в 'stdout'?
- 6. Проверьте, если пользователь перенаправлен с другой страницы
- 7. MavenCli - stdout, stderr
- 8. stderr redirection to stdout
- 9. vim фильтры и stdout/stderr
- 10. fork/exec: stderr/stdout lost
- 11. ABAP Stdout и Stderr
- 12. Проверьте, перенаправлен ли вывод
- 13. LLVM stdin/stdout/stderr
- 14. Scons logging stdout/stderr
- 15. Понимание stderr stdout redirection
- 16. tomcat logging stdout stderr
- 17. STDOUT и STDERR аномалии
- 18. Дублирование stdout для stderr
- 19. Stderr и Stdout в C?
- 20. Объединить несколько stdout/stderr в один stdout
- 21. stderr и stdout из ssh?
- 22. NetBeans stdout и stderr на Linux
- 23. Управление выводами stderr и stdout в WildFly
- 24. piping stderr и stdout отдельно
- 25. stdout и stderr кодировка символов
- 26. Как перенаправить STDOUT и STDERR на переменную
- 27. Как перенаправить stderr на stdout и наоборот
- 28. Завершение stderr и перенаправление сообщения на stdout
- 29. Разбиение на Python между stdout и stderr
- 30. Запись stderr и stdout на консоль
Попробуйте GetFinalPathNameByHandle. Я не уверен, работает ли он на трубах или нет, но стоит попробовать. –
@HarryJohnston Пробовал 'GetFinalPathNameByHandle' в Windows 7, и, к сожалению, он не работал для' GetStdHandle (STD_OUTPUT_HANDLE) '. Он потерпел неудачу, с 'GetLastError()' возвращающим 'ERROR_INVALID_HANDLE'. – usta