2012-12-05 27 views
25

संक्षिप्त सवाल यह है कि अगर एक अनाथ प्रक्रिया समूह में है तो शेल क्या करना चाहिए, जिसका स्वामित्व टीटी नहीं है? लेकिन मैं लंबे सवाल को पढ़ने की सलाह देता हूं क्योंकि यह मनोरंजक है।अनाथाश्रम प्रक्रिया समूहों में इंटरैक्टिव गोले क्या करना चाहिए?

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

इस कारण पार्टी खूंटी करने के लिए:

यहाँ, एक पोर्टेबल अंतरिक्ष हीटर में अपने लैपटॉप चालू करने के लिए अपने पसंदीदा खोल का उपयोग कर (जब तक आप उन में से एक tcsh weirdos रहे हैं) एक मजेदार और रोमांचक तरीका है सीपीयू 100% पर। zsh और fish वही करते हैं, जबकि ksh और tcsh नौकरी नियंत्रण के बारे में कुछ गड़बड़ कर देता है और फिर खत्म हो जाता है, जो थोड़ा बेहतर होता है, लेकिन ज्यादा नहीं। ओह, और यह एक मंच अज्ञेय अपराधी है: ओएस एक्स और लिनक्स दोनों प्रभावित हैं।

मेरा (संभावित रूप से गलत) स्पष्टीकरण निम्नानुसार है: बाल खोल का पता चलता है कि यह अग्रभूमि में नहीं है: tcgetpgrp(0) != getpgrp()। इसलिए यह खुद को रोकने की कोशिश करता है: killpg(getpgrp(), SIGTTIN)। लेकिन इसके प्रक्रिया समूह अनाथ हैं, क्योंकि इसके माता-पिता (सी प्रोग्राम) नेता थे और उनकी मृत्यु हो गई थी, और एक अनाथ प्रक्रिया समूह को भेजा गया सिगटिन अभी गिरा दिया गया है (अन्यथा कुछ भी इसे फिर से शुरू नहीं कर सकता)। इसलिए, बाल खोल बंद नहीं किया गया है, लेकिन यह अभी भी पृष्ठभूमि में है, इसलिए यह फिर से, यह सब फिर से करता है। धोये और दोहराएं।

मेरा सवाल यह है कि कमांड लाइन खोल इस परिदृश्य का पता कैसे लगा सकता है, और इसके लिए क्या सही बात है? मेरा विचार यह है कि शैल stdin से read पर कोशिश करता है, और अगर पढ़ा जाता है तो बस बाहर निकलता है यह ईआईओ देता है।

अपने विचारों के लिए धन्यवाद!

संपादित करें: मैंने शून्य-लंबाई पढ़ने()/dev/tty पर, और यह सफल होने की कोशिश की, जो खराब है। ईआईओ प्राप्त करने के लिए, मुझे वास्तव में/dev/tty से कुछ डेटा पढ़ने के लिए तैयार रहना होगा।

संपादित करें: एक और विचार मैंने kill(getpgrp(), 0) पर किया था। अगर प्रक्रिया समूह अनाथ है, तो मेरा मानना ​​है कि यह हमेशा असफल रहेगा। हालांकि, यह भी असफल हो सकता है क्योंकि मुझे सत्र नेता को सिग्नल करने की अनुमति नहीं है।

संपादित करें: किसी को भी बाद में यह पता लगाने के लिए, मैंने जो किया वह https://github.com/fish-shell/fish-shell/issues/422 पर वर्णित है। इसके अलावा, भविष्य कैसा है?

+5

+1। मैंने giggled;) –

+2

http://unix.stackexchange.com/ – mtk

+1

@Will पर सबसे अच्छा सूट होगा यह कैसे एक प्रोग्रामिंग प्रश्न नहीं है? – Gilles

उत्तर

3

यहाँ strace क्या कहते हो रहा है है:

 
--- SIGTTIN (Stopped (tty input)) @ 0 (0) --- 
rt_sigaction(SIGTTIN, {SIG_IGN, [], SA_RESTORER, 0x7fd5f6989d80}, {SIG_DFL, [], SA_RESTORER, 0x7fd5f6989d80}, 8) = 0 
ioctl(255, TIOCGPGRP, [9954])   = 0 
rt_sigaction(SIGTTIN, {SIG_DFL, [], SA_RESTORER, 0x7fd5f6989d80}, {SIG_IGN, [], SA_RESTORER, 0x7fd5f6989d80}, 8) = 0 
kill(0, SIGTTIN)      = 0 
--- SIGTTIN (Stopped (tty input)) @ 0 (0) --- 
rt_sigaction(SIGTTIN, {SIG_IGN, [], SA_RESTORER, 0x7fd5f6989d80}, {SIG_DFL, [], SA_RESTORER, 0x7fd5f6989d80}, 8) = 0 
ioctl(255, TIOCGPGRP, [9954])   = 0 
rt_sigaction(SIGTTIN, {SIG_DFL, [], SA_RESTORER, 0x7fd5f6989d80}, {SIG_IGN, [], SA_RESTORER, 0x7fd5f6989d80}, 8) = 0 
kill(0, SIGTTIN)      = 0 
[repeat...] 

और यहाँ क्यों, jobs.c से, बैश 4.2 है:

while ((terminal_pgrp = tcgetpgrp (shell_tty)) != -1) 
    { 
     if (shell_pgrp != terminal_pgrp) 
     { 
      SigHandler *ottin; 

      ottin = set_signal_handler(SIGTTIN, SIG_DFL); 
      kill (0, SIGTTIN); 
      set_signal_handler (SIGTTIN, ottin); 
      continue; 
     } 
     break; 
    } 

के संबंध में इसके बारे में क्या करना है ... अच्छी तरह से परे है कि मेरी योग्यता। लेकिन, मैंने सोचा कि यह उपयोगी जानकारी थी, और एक टिप्पणी के लिए थोड़ा सा था। पोर्टेबल स्पेस हीटर टिप्पणी के लिए