# How to detect if a program is not run from a terminal

If I am running a reverse TCP shell and attempt to run su, I get the following message:

su: must be run from a terminal


I would like to emulate this behavior in my own program and am wondering how do I detect if a program is being run from a terminal?

-
Call isatty with STDIN –  Ulrich Dangel Mar 21 '13 at 17:39

In a shell script:

if [ -t 0 ]; then
echo stdin is a terminal
fi


In a perl script:

print "stdin is a terminal\n" if -t;


In C:

if (isatty(0)) puts("stdin is a terminal");


They all do the same, do a tty specific ioctl and return true unless the ioctl fails with a ENOTTY error. On my system, the ioctl is TCGETS and I believe it's fairly common as it's an obvious one.

\$ : | strace -e ioctl su
ioctl(0, TCGETS, 0x7ffff32dfc50) = -1 ENOTTY (Inappropriate ioctl for device)
su: must be run from a terminal

-
Regarding the C solution, it's fine, but don't use puts() and friends. The printf() family is recommended. –  schaiba Mar 21 '13 at 23:46
@schaiba, Why? Even gcc optimises printf("stdin is a terminal\n") to puts("stdin is a terminal") even without any -O flag. –  Stéphane Chazelas Mar 22 '13 at 8:04