2013-10-03 18 views
5

W jaki sposób zmiany wielkości terminala są wysyłane do aplikacji wiersza poleceń przez ssh lub telnet?W jaki sposób zmiany rozmiaru terminala są wysyłane do aplikacji wiersza poleceń przez ssh lub telnet?

  1. użytkownik łączy się ze zdalnym komputerem z ssh lub telnet.

  2. Rozpoczynają edycję dokumentu w VIM.

  3. Następnie zmieniają rozmiar okna terminala.

Terminal musi poinformować ssh/telnet, że rozmiar okna się zmienił. Jak to się stało?

ssh/telnet używa następnie własnej metody wysyłania tej zmiany do sshd/telnetd. Jakie są te metody?

sshd/telnetd następnie informuje aplikację, że zmienił się rozmiar terminala. Jak to się robi. Czy to ta sama metoda, co z terminala do ssh/telnet?

Odpowiedz

7

To jest brudny świat pseudo terminali.

Lokalnie, po zmianie rozmiaru terminala pierwsza grupa procesów otrzymuje numer SIGWINCH i można użyć ioctl, aby pobrać nowy rozmiar. Ale co to ma wspólnego z procesem vim z zdalnym?

Temat jest dość skomplikowana, ale istotą jest to, że serwer remove (sshd) robi to:

  1. Otwiera główny psedoterminal urządzenia za pomocą posix_openpt (lub openpty)
  2. Forks nowe dziecko (zazwyczaj jest związany się powłoki)
  3. zrywa połączenia przez zacisk za pomocą setsid()
  4. otwiera urządzenie terminala (utworzonego w etapie 1), który staje się jej końcówką sterującą
  5. Zastępuje deskryptory Standard (STDIN_FILENO i przyjaciół) z fd od kroku 4

w tym momencie niczego proces serwer zapisuje na stronie głównej kończy się jako wkład do boku niewolnikiem, lecz z terminalem dyscypliny linii, więc jądro robi trochę magii - jak wysyłanie sygnałów - podczas pisania niektórych kombinacji, a także można wywoływać wywołania ioctl z przydatnymi efektami.


Najlepszym sposobem, aby myśleć o to, aby zbadać openssh apartament.

  • Monitory klienckie dla SIGWINCH - patrz clientloop.c i ustawia received_window_change_signal = 1 gdy odbiera go

  • Funkcja client_check_window_change sprawdza, flaga i informuje serwer:

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

Teraz serwer powinien otrzymać pakiet, który s Określa rozmiar (potencjalnie nowy).

  • Serwer nazywa pty_change_window_size z odebranym rozmiarach która robi prawdziwą magię:

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

To ustawia nowe okno rozmiar slave. Jeśli nowy rozmiar różni się od starego, jądro wysyła SIGWINCH do grupy procesów na pierwszym planie związanych z tym pty. Tak więc vim również otrzymuje ten sygnał i może zaktualizować swój pomysł rozmiaru terminala.

+0

Dzięki, to naprawdę dobre wytłumaczenie. – fadedbee

+1

@chrisdew Szczerze mówiąc, kiedy zapytałeś, znałem główną ideę, ale nie znałem szczegółów, więc pomyślałem, co lepiej poświęcić na jej zbadanie. – cnicutar

+0

Dzięki za poświęcenie czasu na badania i nauczenie nas wszystkich z tym dobrym wyjaśnieniem! –

Powiązane problemy