In my C program I want to know if my executable is run in foreground like this
$./a.out
or like this
$./a.out &
If you are the foreground job,
getpgrp() == tcgetpgrp(STDOUT_FILENO)
or STDIN_FILENO
or STDERR_FILENO
or whichever file descriptor you're attached to your controlling terminal by. (If you're not sure, open("/dev/tty")
will always get you a file descriptor to your controlling terminal, if one exists.)
This is what openssh does, and is a bit easier than handling SIGTTIN/SIGTTOU
if you just want a quick check.
On the other hand, you may have been backgrounded
$ ./a.out ^Z [1]+ Stopped ./a.out $ bg [1]+ ./a.out &
or foregrounded
$ fg ./a.out
at any point in time. You cannot expect that you can check this once and it will still be true (or false) later.
From the Bash Reference Manual: Job Control Basics:
Background processes are those whose process group id differs from the terminal's; such processes are immune to keyboard-generated signals. Only foreground processes are allowed to read from or write to the terminal. Background processes which attempt to read from (write to) the terminal are sent a SIGTTIN (SIGTTOU) signal by the terminal driver, which, unless caught, suspends the process.
So the solution is to install a signal handler for SIGTTIN
and then try to read from stdin
(turn buffering off or it will block). If you get "0 bytes read" back, then you're running in the foreground.
[EDIT] Note that the status of a process can change. You can use the job control commands of the shell (Ctrl-Z, bg
, fg
and jobs
) to do this.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With