Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I know if an C program's executable is run in foreground or background?

In my C program I want to know if my executable is run in foreground like this

$./a.out

or like this

$./a.out &
like image 463
Saradhi Avatar asked Dec 08 '22 04:12

Saradhi


2 Answers

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.

like image 77
ephemient Avatar answered Dec 11 '22 08:12

ephemient


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.

like image 40
Aaron Digulla Avatar answered Dec 11 '22 10:12

Aaron Digulla