C/C++ で redirection と pipeline を検知する方法

redirection 、リダイレクト ( ">" でつないで file に書き出し ) と pipeline 、パイプ ( "|" でつないで他の command に出力を渡す ) を C/C++ で検知する方法まとめ。以前使った記憶があるしたしか方法あったよなと思いつつ探したんだけど見つけるのに 2 時間ほど要したので自分で書いとく。で、以下のようにどちらも同じ書き方をする、というか区別する方法ってあるんじゃろうか… ? file descriptor の指定をうまいことアレすればできるんだろうけどその方法がわからんな…。

#include <stdio.h>

#ifdef WIN32
#include <io.h>
#else
#include <unistd.h>
#endif

int main(void) {
#ifdef WIN32
    if (_isatty(_fileno(stdout))) {
#else
    if (isatty(fileno(stdout))) {
#endif
        fprintf(stderr, "stdout\n");
    }
    else {
        fprintf(stderr, "redirected\n");
    }
}

compile が通ることを確認したのは以下。

ただまぁ上 2 つは cmd.exe 上じゃないと意図した動作をしない。少なくとも MSYS 付属の rxvt bash では常に "redirected" が表示される。多分標準出力を表す file descriptor が header に定義されているものと rxvt bash のもので違いがあるということなんだろうけどハマりそうな気がする。あーでも手動で file に redirect させてやりゃ済むハナシか。