在C ++程序中,是否可以检查stderr是否重定向到stdout,反之亦然?基本上我想知道这两个文件描述符是否指向同一个地方。使用本机API的特定于平台的解决方案是可以的。
答案 0 :(得分:2)
Linux,也可能是其他unix-like:fstat fds和比较dev:ino对。
答案 1 :(得分:1)
对于Windows 7及更高版本的控制台句柄 - 这是真正的文件句柄(在XP上这不是真的,关于vista - 不记得了)。我们可以通过使用STD_OUTPUT_HANDLE和STD_ERROR_HANDLE调用GetStdHandle获得这2个句柄。但后来需要以某种方式通过句柄比较文件。这不等于直接比较处理值 - 因为2个不同的句柄可以指向同一个文件。即使我们从句柄获得指向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);
但对于xp,这将不起作用