2013-10-03 7 views
5

एसएसएच या टेलनेट के माध्यम से टर्मिनल आकार परिवर्तन कमांड लाइन अनुप्रयोगों को कैसे भेजा जाता है?एसएसएच या टेलनेट हालांकि कमांड लाइन अनुप्रयोगों में टर्मिनल आकार परिवर्तन कैसे भेजे जाते हैं?

  1. कोई उपयोगकर्ता एसएसएच या टेलनेट के साथ रिमोट मशीन से कनेक्ट होता है।

  2. वे वीआईएम में एक दस्तावेज़ संपादित करना शुरू करते हैं।

  3. फिर वे अपनी टर्मिनल विंडो का आकार बदलते हैं।

टर्मिनल को एसएसएच/टेलनेट को यह कहना चाहिए कि खिड़की का आकार बदल गया है। यह कैसे होता है?

एसएसएच/टेलनेट फिर एसएसडी/टेलनेट में उस परिवर्तन को भेजने के लिए अपनी विशेष विधि का उपयोग करता है। इन तरीकों क्या हैं?

sshd/telnetd तब एप्लिकेशन को बताता है कि टर्मिनल आकार बदल गया है। यह कैसे किया जाता है। क्या यह टर्मिनल से एसएसएच/टेलनेट के समान तरीका है?

उत्तर

7

यह छद्म टर्मिनलों की गन्दा दुनिया है।

स्थानीय रूप से, जब आप अपने टर्मिनल का आकार बदलते हैं तो आपके अग्रभूमि प्रक्रिया समूह को SIGWINCH मिल जाता है और आप नए आकार को लाने के लिए ioctl का उपयोग कर सकते हैं। लेकिन रिमोट विम प्रक्रिया के साथ इसका क्या संबंध है?

विषय काफी जटिल है, लेकिन इसे का सार निकालने सर्वर (sshd) करता है जो:

  1. एक मास्टर psedoterminal डिवाइस posix_openpt (या openpty) का उपयोग कर
  2. Forks एक नए बच्चे को खोलता है ((चरण 1) जो अपने को नियंत्रित करने के लिए टर्मिनल
  3. हो जाता है में बनाया आम तौर पर इस एक खोल) बनने के लिए
  4. setsid()
  5. टर्मिनल डिवाइस खोलता है का उपयोग करते हुए अपने टर्मिनल कनेक्शन severs ही है
  6. एक टर्मिनल लाइन अनुशासन के साथ गुलाम ओर करने के लिए इनपुट लेकिन के रूप में समाप्त होता है कदम 4

इस बात कुछ भी सर्वर प्रक्रिया मास्टर ओर करने के लिए लिखते हैं पर से एफडी के साथ मानक वर्णनकर्ता (STDIN_FILENO और दोस्तों) बदलता है इसलिए कर्नेल कुछ जादू करता है - सिग्नल भेजना - कुछ संयोजन लिखते समय, और आप उपयोगी प्रभावों के साथ ioctl कॉल भी जारी कर सकते हैं।


इस बारे में सोचने के लिए सबसे अच्छा तरीका openssh सूट जा सकता है।

  • SIGWINCH के लिए ग्राहक पर नज़र रखता है - clientloop.c देख सकते हैं और सेट received_window_change_signal = 1 जब यह

  • समारोह client_check_window_change जांच करता है कि झंडा और सर्वर बताता प्राप्त करता है:

    packet_start(SSH_CMSG_WINDOW_SIZE); 
    packet_put_int((u_int)ws.ws_row); 
    ... 
    

तो अब सर्वर को एक पैकेट प्राप्त करना चाहिए जो एस है एक (संभावित रूप से नया) आकार pecifies।

  • सर्वर कॉल प्राप्त आकार जो असली जादू करता है के साथ pty_change_window_size:

    struct winsize w; 
    w.ws_row = row; 
    ... 
    (void) ioctl(ptyfd, TIOCSWINSZ, &w); /* This is it! */ 
    

इस दास की नई विंडो का आकार सेट करता है। यदि नया आकार पुराना से अलग है, तो कर्नेल उस पीटीआई से जुड़े अग्रभूमि प्रक्रिया समूह पर SIGWINCH भेजता है। इस प्रकार vim भी उस सिग्नल को प्राप्त करता है और टर्मिनल आकार के अपने विचार को अपडेट कर सकता है।

+0

धन्यवाद, यह वास्तव में एक अच्छा स्पष्टीकरण है। – fadedbee

+1

@chrisdew ईमानदार होने के लिए, जब आपने पूछा कि मुझे मुख्य विचार पता था लेकिन विवरण नहीं पता था, इसलिए मैंने सोचा कि इसका शोध करने का बेहतर समय क्या है। – cnicutar

+0

इस अच्छे स्पष्टीकरण के साथ हम सभी को अनुसंधान और शिक्षण के लिए समय निकालने के लिए धन्यवाद! –

1

टर्मिनल विंडो का आकार बदलना SIGWINCH सिग्नल उत्पन्न करता है।

संबंधित glibc documentation भी देखें।

संबंधित मुद्दे