[英]Check in a program if stderr is redirected to stdout
From within a C++ program, is it possible to check whether stderr is redirected into stdout or vice versa? 在C ++程序中,是否可以检查stderr是否重定向到stdout,反之亦然? Basically I want to know if those two file descriptors point to the same place.
基本上我想知道这两个文件描述符是否指向同一个地方。 Platform-specific solutions using native APIs are OK.
使用本机API的特定于平台的解决方案也可以。
Linux,也可能是其他unix-like:fstat fds和比较dev:ino对。
for windows 7 and later console handles - this is real file handles (on XP this is not true, about vista - not remember). 对于Windows 7和更高版本的控制台句柄 - 这是真正的文件句柄(在XP上这不是真的,关于vista - 不记得了)。 we can got this 2 handles by call GetStdHandle with STD_OUTPUT_HANDLE and STD_ERROR_HANDLE.
我们可以通过使用STD_OUTPUT_HANDLE和STD_ERROR_HANDLE调用GetStdHandle获得这2个句柄。 but then need somehow compare files by handle.
但后来需要以某种方式通过句柄比较文件。 this not equal direct compare handles values - because 2 different handles can point to same file.
这不等于直接比较处理值 - 因为2个不同的句柄可以指向同一个文件。 even if we got pointer to FILE_OBJECT from handle (this possible from user mode) - two different FILE_OBJECTs can point to same file (if we speak about filesystem files).
即使我们从句柄获得指向FILE_OBJECT的指针(这可能来自用户模式) - 两个不同的FILE_OBJECT可以指向同一个文件(如果我们谈论文件系统文件)。 so best way here i think - got names of both files - and compare - are they equal.
所以我认为最好的方式 - 得到两个文件的名称 - 并进行比较 - 它们是否相等。 this can be done by ZwQueryObject .
这可以通过ZwQueryObject来完成。 code can be like this
代码可以是这样的
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);
but for xp this will be not work 但对于xp,这将无法正常工作
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.