Mengapa ed tidak bisa keluar dengan Cc?

20

Program ed, editor teks minimal, tidak dapat keluar dengan mengirimkannya interupsi menggunakan Ctrl- C, alih-alih mencetak pesan kesalahan "?" ke konsol. Mengapa tidak edkeluar begitu saja ketika menerima interupsi? Tentunya tidak ada alasan mengapa pesan kesalahan samar lebih bermanfaat di sini daripada hanya keluar. Perilaku ini mengarahkan banyak pengguna baru ke dalam jenis interaksi berikut:

$ ed
hello
?
help
?
exit
?
quit
?
^C
?
^C
?
?
?
^D
$ su
# rm -f /bin/ed

Sungguh pemborosan yang tragis — mudah dihindari jika edhanya disetujui untuk diinterupsi.

Program keras kepala lainnya yang menunjukkan perilaku serupa adalah lessyang juga tampaknya tidak memiliki banyak alasan untuk diabaikan C-c. Mengapa program-program ini tidak mengambil petunjuk saja?

Lily Chung
sumber
4
Aplikasi interaktif tidak sama dengan non-interaktif. Perilaku Ctrl-C Anda dulu adalah default untuk yang non-interaktif. Yang interaktif dapat mengesampingkan perilaku Ctrl-C untuk tujuan mereka sendiri.
jw013
4
Juga, tidak yakin apakah lelucon
jw013
@ jw013 Ya, "sesi tipikal" adalah lelucon (saya tidak bisa menemukan yang karena alasan tertentu) tetapi pertanyaan saya serius. Yang tidak saya mengerti adalah mengapa aplikasi ini memilih untuk menimpa perilaku Ctrl-C jika sebenarnya tidak memberikan sesuatu yang bermanfaat.
Lily Chung
1
Karena pertanyaan ini muncul sebagai jawaban pencarian google teratas untuk "bagaimana keluar dari ed," Saya ingin menambahkan di sini bahwa itu hanya 'q' diikuti oleh pengembalian. Banyak orang Bothans mati untuk membawakan kami informasi ini.
Dmitri

Jawaban:

19

Ctrl+ Cmengirim SIGINT . Tindakan konvensional untuk SIGINT adalah kembali ke loop tingkat atas program, membatalkan perintah saat ini dan memasuki mode di mana program menunggu perintah berikutnya. Hanya program non-interaktif yang seharusnya mati karena SIGINT.

Jadi wajar jika Ctrl+ Ctidak membunuh ed, tetapi menyebabkannya kembali ke loop tingkat atas. Ctrl+ Cbatalkan baris input saat ini dan kembali ke prompt ed.

Hal yang sama berlaku untuk lebih sedikit: Ctrl+ Cmengganggu perintah saat ini dan membawa Anda kembali ke prompt perintahnya.

Untuk alasan historis, ed mengabaikan SIGQUIT ( Ctrl+ \). Aplikasi normal seharusnya tidak menangkap sinyal ini dan membiarkan diri mereka dihentikan, dengan dump inti jika diaktifkan.

Gilles 'SANGAT berhenti menjadi jahat'
sumber
@ Kzqai Tidak, aplikasi normal seharusnya tidak menangkap SIGQUIT, ini dimaksudkan sebagai pintu keluar darurat.
Gilles 'SANGAT berhenti menjadi jahat'
Ah, mengerti. Baiklah, ditarik.
Kzqai
18

The Unix V7 ed(1)kode sumber adalah sebuah program C 1762-line primitif hanya dengan beberapa komentar, salah satunya adalah header ini komentar yang sangat-mencerahkan:

/*
 * Editor
 */

Karena kode sumbernya sendiri tidak memberikan alasan apa pun, Anda hanya akan mendapatkannya dari pembuat program.

edpada awalnya ditulis oleh Ken Thompson di perakitan PDP-11 , tetapi Anda sebenarnya harus berbicara dengan siapa pun yang mengirimnya ke C. Itu mungkin Dennis Ritchie , karena ia menciptakan C untuk Unix, dan merupakan salah satu dari banyak yang menggunakan C untuk membuat Unix portabel untuk mesin non-PDP. Dr Ritchie tidak lagi ada untuk menjawab pertanyaan seperti itu.

Pembacaan kode saya menunjukkan bahwa itu dilakukan untuk mencoba dan melestarikan isi salinan inti dari dokumen yang diedit. Anda akan melihat bahwa editor teks lain juga tidak mati Ctrl-C.

Inilah yang edterjadi pada Ctrl-C:

onintr()
{
    signal(SIGINT, onintr);
    putchr('\n');
    lastc = '\n';
    error(Q);
}

(Ya, K&R C. Kami tidak memerlukan penspesifikasi tipe pengembalian steenkin atau deklarasi parameter.)

Diterjemahkan ke dalam bahasa Inggris ed,:

  1. Registrasi ulang pengendali sinyal.

    (Unix tidak mendapatkan sinyal pengaturan ulang otomatis hingga 4.3BSD , pada pertengahan 1980-an.)

  2. Menulis baris baru, dan mengingatnya, melalui variabel global lastc.

    ( ed.cmemiliki sekitar enam puluh variabel global.)

  3. Memanggil error()fungsi, yang terkenal tidak lebih dari mencetak ?, dari perspektif pengguna.

Dengan kata lain, itu mengatakan, "Kamu tidak benar-benar bermaksud melakukan itu, bukan?"

Warren Young
sumber
2
Juga perlu dicatat bahwa banyak editor teks tidak keluar pada Control-C. Vim juga tidak. Tidak juga nano. Saya tidak berpikir emacs juga, tetapi tidak menginstalnya untuk menguji.
derobert
3
@derobert Vi memperlakukan Ctrl + C dengan cara Unix: kembali ke tingkat atas. Emacs memiliki ikatan kunci sendiri, karena asalnya yang non-Unix; padanan Emacs dari Unix's Ctrl + C adalah Ctrl + G (karakter bel - membunyikan bel di komputer untuk menghentikannya)
Gilles 'SO- stop being evil'
@derobert: Titik adil. Saya telah menambahkan ini ke jawabannya.
Warren Young
2
@Gilles: Salah satu efek samping dari panggilan error(s)masuk ed.cadalah kembali ke loop pemrosesan utama. Itu melakukannya dengan longjmp()panggilan. gemetar
Warren Young
1
Terima kasih untuk detail dan pelajaran sejarahnya. Ini bacaan yang bagus!
alichaudry
7

ed, seperti program interaktif lainnya, gunakan Ctrl+ Cuntuk mengganggu tugas-tugas program itu sendiri.
Ini sangat mirip dengan kasus normal, di mana ia mengganggu tugas yang berjalan di shell - perintah.

Dari perspektif pengguna, kedua varian sangat mirip. Penanganan sinyal berbeda: dalam kasus biasa, sinyal SIGINTdikirim ke proses latar depan, perintah berjalan, dan perintah menanganinya dengan keluar.
Dalam kasus ed, sinyal dikirim ke proses latar depan, edmisalnya. Jika ada tugas yang sedang berjalan ed, itu terputus dan prompt ditampilkan. Jika tidak ada tugas yang berjalan, tidak ada yang berubah.

Perhatikan bagaimana shell juga tidak keluar pada Ctrl+ C, sama seperti ed. Dan itu keluar pada Ctrl+ D. Sekali lagi, sama sepertied

Volker Siegel
sumber
3

Ada tiga sinyal yang edpeduli:

  1. INT
  2. HUP
  3. QUIT

Spesifikasi POSIX daried kata berikut ini:

SIGINT

The edutilitas akan mengganggu aktivitas saat ini, menulis string ?\nke output standar, dan kembali ke modus perintah (lihat bagian KETERANGAN EXTENDED).

SIGHUP

Jika buffer tidak kosong dan telah berubah sejak penulisan terakhir, edutilitas akan berusaha untuk menulis salinan buffer dalam file. Pertama, file yang disebutkan ed.hupdalam direktori saat ini harus digunakan; jika itu gagal, file yang disebutkan ed.hupdalam direktori yang dinamai oleh HOMEvariabel environment harus digunakan. Bagaimanapun, edutilitas harus keluar tanpa menulis file ke pathname yang diingat saat ini dan tanpa kembali ke mode perintah.

SIGQUIT

The edutilitas akan mengabaikan acara ini.

Jadi, apa pun implementasi yang edAnda gunakan, itu sesuai dengan spesifikasi POSIX sehubungan dengan INTsinyal (yang Ctrl+Cdikirimkan).

Dalam hal ini, editor berperilaku seperti shell interaktif, yang juga tidak berakhir setelah menerima INTsinyal. Editor lain, seperti vidan nanomelakukan hal yang sama.

Kusalananda
sumber
1
Beberapa implementasi program dengan sengaja bertentangan dengan POSIX, jadi mungkin berguna untuk menjelaskan alasan standar / biaya untuk memecahkannya dalam kasus ini. stackoverflow.com/questions/38605463/…
sourcejedi
1
@sourcejedi Standar tidak mengatakan apa pun tentang sinyal dalam alasannya. Saya tidak menemukan alasan untuk mengatakan apa-apa tentang mengapa standar diikuti dalam sumber-sumber edyang saya miliki. Berperilaku dengan cara yang sama seperti shell, yang juga tidak berhenti saat menerima INTsinyal.
Kusalananda