9

I have an application that needs to behave differently if run directly from the linux console. So if a user connects with SSH to run FooBar, or the user walks over to the console and logs in directly to run FooBar, I want it to do something different.

What C API do I need to call to tell the difference between these two scenarios? I was thinking I'd have to look at the "tty/pts" information (such as what I see when I run "ps axf"), but I'm not certain if that is the best solution, nor what API to call to get that information.

Hints appreciated. :)

Stéphane
  • 19,459
  • 24
  • 95
  • 136
  • there are other ways of getting a non-tty shell session than connecting over SSH. For instance, right now on my desktop I'm using Konsole within KDE... I'm physically on the computer, but it shows up as a pty when I run `who`. Would this count as a console or "ssh" session for your purposes? Perhaps you should edit your question to be more clear. – rmeador May 25 '10 at 20:12
  • I think you are asking about two different things... the actual question seems to be how to tell if you are running in a local X terminal or via ssh session. "Linux console" typically means the hardware console accessed with [Ctrl+]Alt+F2 etc. The later can be detected if $TERM == "linux". – Gringo Suave Oct 29 '12 at 19:20

5 Answers5

9

Depending on how much you're worried about it being spoofed, an easy check would be for the presence/absence of the SSH_CLIENT and SSH_CONNECTION environment variables, in which case you'd want the getenv function.

developmentalinsanity
  • 6,109
  • 2
  • 22
  • 18
6

Checking the return value of ttyname(3) against your stdin should give you the name of the terminal which is feeding the input of your process.

It will be /dev/console if the program is being run on the console (and doesn't have it's input redirected). You can also check stdout to see if it is connected to /dev/console - see which fits your usage scenario better.

ivans
  • 1,465
  • 10
  • 13
  • 5
    It isn't /dev/console, but /dev/tty[0-9], while the ssh and gnome-terminal sessions show up with names like /dev/pts/[0-9]+. Combined with isatty(), your hint to use ttyname() works great for what I needed to do. – Stéphane May 25 '10 at 21:35
5

ttyname will tell you the name of the terminal connected to a given file descriptor; for example, ttyname(0) will tell you stdin's terminal.

This will of course fail if input or output is redirected.

Barring that, you can check various environment variables (SSH_CONNECTION, SSH_CLIENT, REMOTEHOST, DISPLAY, SESSIONNAME). Wireshark has logic to detect if it's being run remotely so that it doesn't capture network traffic that it generates; you might be interested in the logic that its get_conn_cfilter function uses to implement this.

Josh Kelley
  • 56,064
  • 19
  • 146
  • 246
3

I'd look at environment variables as a reasonable sign of what's going on. I'm not sure what C API you'd want for that, but I'm sure one exists.

For example, both the SSH_CLIENT or SSH_CONNECTION environment variables are set on my machine regardless of the SSH client being used.

It may be worth checking how universal these are based on the SSH server running on the machine.

Darien
  • 3,482
  • 19
  • 35
0

ugly, but works:

// don't force scripts to pause!
if (_isatty(_fileno(stdout)))
{
    _tprintf(_T("\nPress enter to continue..."));
    _gettc(stdin);
}
Mordachai
  • 9,412
  • 6
  • 60
  • 112