简体   繁体   English

检查程序是否将stderr重定向到stdout

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM