Ini adalah terminal (driver) yang mencegat ^C dan menerjemahkannya menjadi sinyal yang dikirim ke proses terlampir (yang merupakan shell) stty intr ^B
akan menginstruksikan driver terminal untuk mencegat ^B sebagai gantinya. Itu juga driver terminal yang menggemakan ^C kembali ke terminal.
Shell hanyalah sebuah proses yang berada di ujung lain baris, dan menerima stdin dari terminal Anda melalui driver terminal (seperti /dev/ttyX), dan stdout (dan stderr) juga dilampirkan ke tty yang sama .
Perhatikan bahwa (jika gema diaktifkan) terminal mengirimkan penekanan tombol ke keduanya proses (grup) dan kembali ke terminal. Perintah stty hanya membungkus ioctl()s untuk driver tty untuk proses "mengendalikan" tty.
PEMBARUAN:untuk menunjukkan bahwa shell tidak terlibat, saya membuat program kecil berikut. Itu harus dijalankan oleh shell induknya melalui exec ./a.out
(tampaknya shell interaktif akan memotong shell anak perempuan) Program menyetel kunci yang menghasilkan SIGINTR ke ^B, mematikan gema, dan kemudian menunggu input dari stdin.
#include <stdio.h>
#include <string.h>
#include <termios.h>
#include <unistd.h>
#include <signal.h>
#include <errno.h>
int thesignum = 0;
void handler(int signum);
void handler(int signum)
{ thesignum = signum;}
#define THE_KEY 2 /* ^B */
int main(void)
{
int rc;
struct termios mytermios;
rc = tcgetattr(0 , &mytermios);
printf("tcgetattr=%d\n", rc );
mytermios.c_cc[VINTR] = THE_KEY; /* set intr to ^B */
mytermios.c_lflag &= ~ECHO ; /* Dont echo */
rc = tcsetattr(0 , TCSANOW, &mytermios);
printf("tcsetattr(intr,%d) =%d\n", THE_KEY, rc );
printf("Setting handler()\n" );
signal(SIGINT, handler);
printf("entering pause()\n... type something followed by ^%c\n", '@'+THE_KEY );
rc = pause();
printf("Rc=%d: %d(%s), signum=%d\n", rc, errno , strerror(errno), thesignum );
// mytermios.c_cc[VINTR] = 3; /* reset intr to ^C */
mytermios.c_lflag |= ECHO ; /* Do echo */
rc = tcsetattr(0 , TCSANOW, &mytermios);
printf("tcsetattr(intr,%d) =%d\n", THE_KEY, rc );
return 0;
}
intr.sh:
#!/bin/sh
echo $$
exec ./a.out
echo I am back.
Shell menggemakan semua yang Anda ketik, jadi saat Anda mengetik ^C
, itu juga digaungkan (dan dalam kasus Anda dicegat oleh penangan sinyal Anda). Perintah stty -echo
mungkin berguna atau tidak bagi Anda tergantung pada kebutuhan/kendala Anda, lihat halaman manual untuk stty untuk informasi lebih lanjut.
Tentu saja lebih banyak lagi yang terjadi di level yang lebih rendah, kapan saja Anda berkomunikasi dengan sistem melalui driver perangkat periferal (seperti driver keyboard yang Anda gunakan untuk menghasilkan sinyal ^C, dan driver terminal yang menampilkan semuanya) terlibat. Anda dapat menggali lebih dalam lagi di tingkat bahasa rakitan/mesin, register, tabel pencarian, dll. Jika Anda menginginkan tingkat pemahaman yang lebih mendetail dan mendalam, buku-buku di bawah ini adalah tempat yang baik untuk memulai:
Desain OS Unix adalah referensi yang bagus untuk hal-hal semacam ini. Dua referensi klasik lainnya:Lingkungan Pemrograman Unix dan Pemrograman Tingkat Lanjut di Lingkungan UNIX
Ringkasan yang bagus di sini, di pertanyaan SO ini Bagaimana cara Ctrl-C menghentikan proses anak?
"saat Anda menjalankan program, misalnya find
, cangkangnya:
- garpu cangkang itu sendiri
- dan untuk anak atur penanganan sinyal default
- ganti anak dengan perintah yang diberikan (misalnya dengan find)
- ketika Anda menekan CTRL-C, shell induk menangani sinyal ini tetapi anak akan menerimanya - dengan tindakan default - hentikan. (anak juga dapat mengimplementasikan penanganan sinyal)"