开发者

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

开发者 https://www.devze.com 2022-12-22 19:55 出处:网络
In my C program开发者_C百科 I want to know if my executable is run in foreground like this $./a.out

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.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号