In my C program开发者_C百科 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.
To my knowledge this is not possible and usually not necessary either.
Please explain why you want to do this.
[invalid]
IIRC, getppid() (on *nix systems) will give you the parent id. if it is 0, the 'console' is your parent and so you are running in the background.
[/invalid]
[edit]
int devtty;
if ((devtty = open ("/dev/tty", O_RDWR)) < 0)
printf ("daemon\n");
note that this is only valid on *nix systems (and then only if nobody has deleted /dev/tty -- for whatever reason)
[/edit]
There may be a possibility that you have more than one process running in the background:
$ jobs
[1] Stopped teamviewer
[2]- Stopped vim
[3]+ Stopped firefox
use:
fg %2
to send the vim process back to foreground.To send the last process back to foreground simply use:
fg
with no arguments.- You can also type % process_name to resume the stopped process.
To suspend the process running in the background, use:
kill -19 %job_id.
The -19
signal is SIGSTOP (the signal sent by Ctrl - Z) .
you can always see the list by typing kill -l
Moving jobs between background / foreground:
If you have already typed a command and forgot to use the &
, you can put a foreground job into the background by typing ^Z (CTRL-Z)
to suspend the job, followed by bg
, to put it into the background:
$ sleep 99
^Z
[1]+ Stopped sleep 99
$ bg
[1]+ sleep 99 &
You can list the jobs of the current shell using the jobs
command.
Just remember that "exiting shell" affects jobs as well:
- Jobs running in the background when the shell exits are left running.
- Jobs that are paused (“Stopped”) when the shell exits are terminated.
Sending signals to jobs and processes
You can send signals, including termination signals, to jobs that are started from the current shell using job numbers using %(JOBID) instead of process numbers(PID):
$ kill %1
[1]+ Terminated sleep 99
To send signals to processes or jobs that are not started from the current shell, you first need to use ps
to find their process numbers(PID).
You can refer to this link: processes and jobs
The general job control commands in Linux are:
- jobs - list the current jobs
- fg - resume the job that's next in the queue
- fg %[number] - resume job [number]
- bg - Push the next job in the queue into the background
- bg %[number] - Push the job [number] into the background
- kill %[number] - Kill the job numbered [number]
- kill -[signal] %[number] - Send the signal [signal] to job number [number]
- disown %[number] - disown the process(no more terminal will be owner), so command will be alive even after closing the terminal.
That's pretty much all of them. Note the % infront of the job number in the commands - this is what tells kill you're talking about jobs and not processes.
精彩评论