How CTRL+C works
The first thing is to understand how CTRL+C works.
When you press CTRL+C, your terminal emulator sends an ETX character (end-of-text / 0x03).
The TTY is configured such that when it receives this character, it sends a SIGINT to the foreground process group of the terminal. This configuration can be viewed by doing stty -a
and looking at intr = ^C;
.
The POSIX specification says that when INTR is received, it should send a SIGINT to the foreground process group of that terminal.
What is the foreground process group?
So, now the question is, how do you determine what the foreground process group is?
The foreground process group is simply the group of processes which will receive any signals generated by the keyboard (SIGTSTP, SIGINT, etc).
Simplest way to determine the process group ID is to use ps
:
ps ax -O tpgid
The second column will be the process group ID.
How do I send a signal to the process group?
Now that we know what the process group ID is, we need to simulate the POSIX behavior of sending a signal to the entire group.
This can be done with kill
by putting a -
in front of the group ID.
For example, if your process group ID is 1234, you would use:
kill -INT -1234
Simulate CTRL+C using the terminal number.
So the above covers how to simulate CTRL+C as a manual process. But what if you know the TTY number, and you want to simulate CTRL+C for that terminal?
This becomes very easy.
Lets assume $tty
is the terminal you want to target (you can get this by running tty | sed 's#^/dev/##'
in the terminal).
kill -INT -$(ps h -t $tty -o tpgid | uniq)
This will send a SIGINT to whatever the foreground process group of $tty
is.
So when a command is fired from a shell, fork() inherits a child
process of it and exec() loads the child process to the memory and
executes.
Not quite. fork()
clones the current process, creating an identical child. exec()
loads a new program into the current process, replacing the existing one.
My qs is:
If the child process contains all the attributes of the parent process(which is the original process), then what is the need of this
child process? The original process also could have been loaded to the
memory.
The need is because the parent process does not want to terminate yet; it wants a new process to go off and do something at the same time that it continues to execute as well.
Does this fork and exec concept apply to all the executable program in
UNIX?Like for shell script also or only for commands? Does it also
apply for shell builtin commands?
For external commands, the shell does a fork()
so that the command runs in a new process. Builtins are just run by the shell directly. Another notable command is exec
, which tells the shell to exec()
the external program without first fork()
ing. This means that the shell itself is replaced with the new program, and so is no longer there for that program to return to when it exits. If you say, exec true
, then /bin/true
will replace your shell, and immediately exit, leaving nothing running in your terminal anymore, so it will close.
when copy on write concept is used if I'll execute a command/script?
Back in the stone age, fork()
actually had to copy all of the memory in the calling process to the new process. Copy on Write is an optimization where the page tables are set up so that the two processes start off sharing all of the same memory, and only the pages that are written to by either process are copied when needed.
Best Answer
Typically the parent process waits until the child process ends by calling
waitpid
. The parent process gets the PID of the process fromfork
.This means the child never signals the parent process in any way that it exited or what happened. This is done by the system and not the child process.
If you are talking about the output of the program, the parent typically never receives the output of the child process unless it provided fds. This also means that the child process prints the output and not the parent process. The parent process just receives information about the state of the process (for more information see the macros in the
waitpid
manpage)