I don't know exactly if the terminal is the handler of keystrokes like CTRL + C or CTRL + D and many others or the shell.
When I press a keystoke I think about it this way, as the picture describes:
When a keystroke is pressed, the keystrokes is handled by the shell, the shell interprets the keystrokes and do whatever it needs to do, perhaps sending a signal when CTRL + C
is pressed or clearing the screen with CTRL + L
and so on. Therefore, the shell plays the role of the middle-man for the program's inputs. Inputs go from shell to the program's stdin.
The program's stdout goes to the shell, and the shell redirects the output to a terminal or files or pipes.
The terminal sends the shell the bytes of the pressed keys.
Am I right?