2

In C/C++ how can my programs determine if there is a desktop (system or remote) or not?

My project has three separate programs running (now) in separate gnome-terminals. It is launched by the last line of .profile, so it starts whether I am at the system desktop (gnome) or remotely connecting by VPN/telnet or VPN/remote-desktop. My machine is 250 miles away at a test site, so I frequently login remotely to make changes and have to restart the program.

I'd like my program to be able to detect that it is launched from a desktop environment or from a telnet session. Preferably, I want them to continue running after the remote connection is broken.

Obviously, I need to make my programs into daemons so they will persist after I close the connection. But if I start them in a terminal on a desktop environment, where I can actually have three terminals open, I'd like to watch their progress messages. And if I disconnect the remote desktop, I'd like the daemons to detect this and turn off printing (to the now killed terms) but keep on running in normal (silent) daemon mode. Best of all, the programs could recheck for a desktop occasionally and resume printing by opening new terminals.

Is this possible? Any coding suggestions?

Thanks in advance.

Wes Miller
  • 2,191
  • 2
  • 38
  • 64
  • 7
    Have you heard of GNU Screen? – Kerrek SB Jan 06 '12 at 15:35
  • Another possibility (which is almost certainly installed on your existing system) is "nohup" which can be used to run a command even if the terminal is terminated. Although this isn't as cool as screen because you can't reconnect to it later and view any output etc... – Benj Jan 06 '12 at 15:40
  • Yes: Run it in screen. That was made for this sort of thing. Why re-invent the wheel ? – Tonny Jan 06 '12 at 15:41
  • Run it in screen, there is no way to detect whether the terminal it is running in is one you would like it to watch in... – PlasmaHH Jan 06 '12 at 15:43
  • Maybe it sufficient to just write a log file and then watch the log from a terminal using "tail -f". – nob Jan 06 '12 at 16:02
  • Thanks for the quick responses. I went off to read about screen on Friday and I still need to get a better understanding but I think it's what I need. Sorry, I can't mark either answer as "best" since they're comments. So here's a resounding thanks to all of you. – Wes Miller Jan 09 '12 at 12:41
  • FWIW, I found that screen did what I needed and that nohup just did n't want to work. The line "start myprog" is in ~/.profile. It works fine as written but does not work if it is given as "start myprog &" which complains about not being in a terminal. I had hoped it would work with the & so that if I login via telnet I could still have a working command line. Again, thanks for the help. – Wes Miller Jan 09 '12 at 21:39

2 Answers2

2

You can use the isatty function. Detect if stdin is a terminal or pipe?

#include <stdio.h>
#include <io.h>

//...

if (isatty(fileno(stdin)))
    printf( "stdin is a terminaln" );
else
    printf( "stdin is a file or a pipen");

You can find more information at http://www.chemie.fu-berlin.de/chemnet/use/info/libc/libc_12.html

Some more code: http://pastebin.com/S3Lr9tik

Community
  • 1
  • 1
Software_Designer
  • 8,490
  • 3
  • 24
  • 28
  • 1
    That's a bit too much external information, I think. Also, you shouldn't use paste services for code samples (as the code will probably not be available forever). – Niklas B. Jan 06 '12 at 16:16
  • `isatty` will return true for any interactive device: a telnet session, an xterm or an actual console. – James Kanze Jan 06 '12 at 16:22
0

The traditional solution for this problem is an option in the command line. Such programs will typically demonize themselves unless given a special debug option telling them not to.

Another solution would be to use a shell script to start the program as a demon, via the nohup command (and redirecting standard input and output to /dev/null).

As for determining whether your managing terminal is local or not, it could be difficult; both X and telnet use virtual terminals, so if you're running under X, you may not be able to distinguish between a telnet session and a local xterm window. Still, it might be worth trying... Under Linux, /proc/<procid>/fd/0 is a symbolic link to the device connected to standard in (fd 0): using something like readlink, you should be able to determine the actual name. Or fstat will give you the major and minor numbers of the device. Given these, you might be able to determine which is which. If your local terminal is not under X, but a real terminal, it will definitely have a different minor number than a pseudo-terminal. For xterms, it's possible that the minor numbers of the pseudo-terminals fall in different ranges, or even that there are distinct sets of pseudo-terminals for remote links and for X; you'll probably have to experiment some, and there might be no working solution. (For starters, to tty at each terminal, and see what it says. I don't have local access to a Linux machine to check, but I seem to remember that on Solaris, X terminals had names like /dev/ttyxx; my remote terminals on Linux here are /dev/pts/xx. (Where xx is a number in each case.)

James Kanze
  • 150,581
  • 18
  • 184
  • 329