Yetim süreç gruplarında etkileşimli kabuklar ne yapmalı?


10

( Https://stackoverflow.com/questions/13718394/what-should-interactive-shells-do-in-orphaned-process-groups adresindeki öneri uyarınca unix olarak yeniden gönderme )

Kısa soru şudur: Bir kabuk, tty'ye sahip olmayan yetim bir süreç grubundaysa ne yapmalıdır? Ama uzun soruyu okumanızı tavsiye ederim çünkü eğlenceli.

İşte en sevdiğiniz kabuğu kullanarak dizüstü bilgisayarınızı taşınabilir bir ısıtıcıya dönüştürmenin eğlenceli ve heyecan verici bir yolu (bu tcsh weirdos'tan biri değilseniz):

#include <unistd.h>   
int main(void) {
    if (fork() == 0) {
        execl("/bin/bash", "/bin/bash", NULL);
    }
    return 0;
}

Bu, bash'ın CPU'yu% 100 oranında sabitlemesine neden olur. zsh ve balık da aynısını yapar, ksh ve tcsh iş kontrolü hakkında bir şeyler mırıldanır ve sonra sallanır, ki bu biraz daha iyi, ama çok değil. Oh, ve bu platform agnostik bir suçlu: OS X ve Linux da etkileniyor.

Aşağıdaki gibi Benim (potansiyel olarak yanlış) açıklaması: çocuk kabuk ön planda değildir algılar: tcgetpgrp(0) != getpgrp(). Bu nedenle kendini durdurmaya çalışır: killpg(getpgrp(), SIGTTIN). Ancak süreç grubu yetim kalmıştır, çünkü ebeveyni (C programı) liderdi ve öldü ve SIGTTINyetimsiz bir süreç grubuna gönderildi sadece düştü (aksi takdirde hiçbir şey tekrar başlayamaz). Bu nedenle, çocuk kabuğu durdurulmaz, ancak hala arka plandadır, bu yüzden hemen tekrar yapar. Durulayın ve tekrarlayın.

Benim sorum, bir komut satırı kabuğu bu senaryoyu nasıl algılayabilir ve bunun için doğru olan şey nedir? Her ikisi de ideal olan iki çözümüm var:

  1. Pid'i grup kimliğimizle eşleşen işleme işaret etmeye çalışın. Bu başarısız olursa ESRCH, muhtemelen yetim olduğumuz anlamına gelir.
  2. Bir baytın engellenmeyen bir okumasını deneyin /dev/tty. Bu başarısız olursa EIO, muhtemelen yetim olduğumuz anlamına gelir.

(Bunu izleme sorunumuz https://github.com/fish-shell/fish-shell/issues/422 )

Düşünceleriniz için teşekkürler!

Yanıtlar:


4

Analizinize katılıyorum ve süreç grubunuzun yetim olup olmadığını tespit etmeniz gerektiği anlaşılıyor.

tcsetattrAyrıca dönüş anlamına gelir EIOsüreç grubunun öksüz kalması durumunda (ve SIGTT görmezden / engellememenize OU . Bu bir daha az müdahaleci bir yol olabilir readterminalde.

Şununla çoğaltabileceğinizi unutmayın:

(bash<&1 &)

Yeniden yönlendirmeye ihtiyacınız vardır, aksi takdirde arka planda bir komut çalıştırılırken stdin / dev / null olarak yönlendirilir.

(bash<&1 & sleep 2)

Terminalden iki mermi okuduğunuz için garip davranışlar bile verir. Onlar görmezden geliyorlar SIGTTINve yenisi tespit etmiyor, başladıktan sonra artık ön plan süreç grubunda değil.

ksh93'nin çözümü o kadar da kötü değil: vazgeçmeden önce bu döngüden sadece 20 kez (sonsuz yerine) gidin.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.