Determining whether STDERR is going to terminal

旧街凉风 提交于 2019-12-05 11:35:50

I think what you're looking for is isatty(3), in unistd.h. There's no way to tell whether a file handle has been redirected, period, but that'll tell you whether it's still interactive. See the source for the tty command in GNU coreutils.

Brad Mace

After combining @chrylis's pointer with this answer and doing a little tweaking, what I finally ended up with is:

  1. create and compile Java class with native method signature
  2. use javah to generate C header file
  3. create .cpp file, implementing function with isatty
  4. compile C++ code into shared library
  5. run Java program, using -Djava.library.path=... to tell it where your custom library is

Java class:

package com.example.cli;

class LinuxTerminalSupport {

    public native boolean isStderrVisible();

    static {
        System.loadLibrary("term");
    }
}

ant target to generate .h:

<target name="generate-native-headers">
    <javah destdir="native/" verbose="yes">
        <classpath refid="compile.class.path"/>
        <class name="com.example.cli.LinuxTerminalSupport" />
    </javah>
</target>

.cpp file:

#include "com_example_cli_LinuxTerminalSupport.h"
#include "unistd.h"

using namespace std;

JNIEXPORT jboolean JNICALL Java_com_example_cli_LinuxTerminalSupport_isStderrVisible(JNIEnv * env, jobject obj) {
    return isatty(fileno(stderr)) == 1;
}

Makefile (change java includes to reflect your $JAVA_HOME):

linux: LinuxTerminalSupport.o
    g++ -I/usr/java/jdk1.6.0_13/include -I/usr/java/jdk1.6.0_13/include/linux \
            -o libterm.so -shared -Wl,-soname,term.so LinuxTerminalSupport.o -lc

LinuxTerminalSupport.o: LinuxTerminalSupport.cpp
    g++ -c -I/usr/java/jdk1.6.0_13/include -I/usr/java/jdk1.6.0_13/include/linux LinuxTerminalSupport.cpp
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!