问题
How can I check if my program's stdout has been redirected to NUL?
That way I can avoid outputting data since it's pointless.
I mainly need this for Windows, but if you have a Linux solution, it might be helpful for others in the future, so feel free to post that as well.
回答1:
There are probably other ways to do this (and it wouldn't be a surprise if there turns out to be a proper function for it I've overlooked), but here's one way:
enum
{
Output_Console,
Output_File,
Output_NUL,
};
bool GetOutputHandleType(int* piType)
{
HANDLE h = GetStdHandle(STD_OUTPUT_HANDLE);
if (h)
{
BY_HANDLE_FILE_INFORMATION fi;
if (GetFileInformationByHandle(h, &fi))
{
*piType = Output_File;
return true;
}
if (GetLastError() == ERROR_INVALID_FUNCTION)
{
*piType = Output_NUL;
return true;
}
if (GetLastError() == ERROR_INVALID_HANDLE)
{
*piType = Output_Console;
return true;
}
}
return false;
}
回答2:
I figured it out myself. It's annoying.
#include <Windows.h>
#include <io.h>
#pragma comment(lib, "ntdll.lib") // can instead use GetProcAddress (below)
extern "C" NTSTATUS __stdcall NtQueryVolumeInformationFile(
HANDLE FileHandle, struct _IO_STATUS_BLOCK *IoStatusBlock,
void *FsInformation, unsigned long Length,
enum _FSINFOCLASS FsInformationClass);
bool isdevnull(FILE *file)
{
struct FILE_FS_DEVICE_INFORMATION
{ unsigned long DeviceType, Characteristics; } fsinfo;
struct { void *info, *status; } iosb;
typedef NTSTATUS (__stdcall *PNTQIF)(
HANDLE FileHandle, struct _IO_STATUS_BLOCK *IoStatusBlock,
void *FsInformation, unsigned long Length,
enum _FSINFOCLASS FsInformationClass);
PNTQIF const ntqif =
true // True if you have ntdll.lib, false otherwise
? NtQueryVolumeInformationFile
: (PNTQIF) GetProcAddress(
GetModuleHandle(TEXT("ntdll.dll")),
"NtQueryVolumeInformationFile");
return ntqif(
(HANDLE) _get_osfhandle(_fileno(stdout)),
(struct _IO_STATUS_BLOCK *)&iosb,
&fsinfo, sizeof(fsinfo),
(enum _FSINFOCLASS)4
) == 0 && fsinfo.DeviceType == 0x00000015 /*FILE_DEVICE_NULL*/;
}
int main()
{
bool b = isdevnull(stdout);
}
来源:https://stackoverflow.com/questions/21069853/how-to-check-if-stdout-has-been-redirected-to-nul-on-windows-a-k-a-dev-null-o