Які обов'язки кожного компонента Pseudo-Terminal (PTY) (програмне забезпечення, сторона управління, підлеглий)?


59

Я намагаюся з’ясувати, як працює tty 1 (робочий потік та обов'язки кожного елемента). Я прочитав кілька цікавих статей про це, але все ж є деякі розмиті ділянки.

Це те, що я розумію поки що:

  • Емульований термінал здійснює різні системні дзвінки /dev/ptmxв головну частину псевдотерміналу.
  • Основна частина псевдотерміналу виділяє файл у /dev/pts/[0-N], що відповідає застарілому послідовному порту, і "приєднує" ведений псевдотермінал.
  • Невідомий псевдотермінал зберігає таку інформацію, як Id сеансу, завдання переднього плану, розмір екрана.

Ось мої запитання:

  1. Чи має ptmx будь-яка мета, крім розподілу рабовласницької частини? Чи надає це якийсь "інтелект" , або емульований термінал (наприклад, xterm) має весь інтелект поводитись як термінал?
  2. Чому xterm повинен взаємодіяти з основною частиною, оскільки він лише передає stdout і stdin частини підлеглого? Чому він не може безпосередньо писати та читати з файлу pts ?
  3. Чи завжди ідентифікатор сеансу додається до одного файлу pts та навпаки? Чи можу я ввести команду ps і знайшла 2 sessionId для того ж / dev / pts / X ?
  4. Яку іншу інформацію містить ptsмагазин? Чи Xterm оновлює всі поля власноруч, чи ptmдодає в нього деяку "інтелект"?

1. Я базую своє розуміння на TTY, демістифікованому Лінусом Акессоном , і Linux Kernel від публікацій Андрія Брауера , як на кількох інших питаннях на цих сайтах

Відповіді:


58

Термінальні емулятори

Основна сторона замінює лінію (пару проводів TX / RX), яка йде до терміналу.

Термінал відображає символи, які він отримує по одному з проводів (деякі з них є керуючими символами і змушують його робити такі дії, як переміщення курсору, зміна кольору ...) і надсилає на інший провід символи, відповідні клавішам, які ви вводите.

Емулятори терміналів, такі як xterm, не відрізняються, за винятком того, що замість того, щоб надсилати та приймати символи по проводах, вони читають і записують символи у своєму дескрипторі файлів на головну сторону. Після того, як вони породили невільницький термінал і запустили вашу оболонку на цьому, вони більше не торкаються цього. На додаток до емуляції пари дроту, xterm також може змінити деякі властивості дисципліни рядків через дескриптор файлу на головну сторону. Наприклад, вони можуть оновити атрибути розміру, щоб SIGWINCH був надісланий програмам, які взаємодіють з підлеглим pty, щоб повідомити їх про змінений розмір.

Крім цього, в емуляторі термінала / терміналу мало інтелекту .

Те, що ви записуєте на термінальний пристрій (як-от pty slave), - це те, що ви маєте на увазі, щоб його відображали, те, що ви читаєте з нього, це те, що ви там ввели, тому для емулятора термінала немає сенсу читати чи записувати в це . Вони є на іншому кінці.


Дисципліна тти лінії

Багато інтелекту знаходиться в с TTY дисципліни лінії . Дисципліна лінійки - це програмний модуль (що знаходиться у драйвері, у ядрі), що надходить на послідовний / pty пристрій, що сидить між цим пристроєм та лінією / провідом (головна сторона для pty).

Послідовна лінія може мати термінал на іншому кінці, але також миша або інший комп'ютер для мереж. Можна, наприклад, приєднати дисципліну SLIP, щоб отримати мережевий інтерфейс поверх послідовного пристрою (або pty пристрою), або у вас може бути дисципліна в рядку tty . Дисципліна tty line - це дисципліна за замовчуванням, принаймні на Linux для послідовних та pty пристроїв. В Linux ви можете змінити дисципліну ліній ldattach.

Ви можете побачити ефект відключення дисципліни tty line, видавши stty raw -echo(зауважте, що bash-підказка чи інші інтерактивні програми, такі як viвстановити термінал у потрібному режимі, який їм потрібен, тому ви хочете використовувати тупу програму, як catце досвід із цим). Потім все, що записується на підлеглий термінальний пристрій, робить його негайно на головну сторону для xterm для читання, і кожен символ, записаний xterm на головну сторону, одразу стає доступним для читання з підлеглого пристрою.

Дисципліна ліній - це те, де реалізований внутрішній редактор ліній термінального пристрою . Наприклад, з stty icanon echo(як це за замовчуванням), коли ви вводите axterm записує aдо головного, тоді дисципліна рядків повторює його назад (робить aдоступним для читання за допомогою xtermдисплея), але не робить нічого доступним для читання на стороні підлеглого . Потім, якщо ви вводите backspace, xterm надсилає a ^?або ^Hсимвол, дисципліна лінії (як така ^?або ^Hвідповідає eraseналаштуванню дисципліни рядка) надсилає назад на майстер a ^H, spaceа також ^Hдля xtermвидаленняaВи щойно набрали на його екрані і досі нічого не надсилає додатку, що читає програму з підлеглого, він просто оновлює свій внутрішній буфер редактора рядків, щоб видалити те, що aви ввели раніше.

Потім, коли ви натискаєте клавішу Enter, xterm надсилає ^M(CR), яка дисципліна ліній перетворює при вході в ^ J (LF), і надсилає те, що ви ввели до цього часу для читання на стороні підлеглого (додаток для читання додатка /dev/pts/xотримає те, що ви набрали включно LF, але не з того aчасу, як ви його видалили), а на головній стороні він надсилає CR та LF для переміщення курсору до наступного рядка та початку екрана.

Лінія дисципліни також відповідає за передачу SIGINTсигналу до групи переднього плану терміналу, коли він приймає ^Cсимвол з боку головного і т.д.

Багато інтерактивних термінальних додатків забороняють більшість функцій цієї лінійки дисципліни реалізовувати її самостійно. Але в будь-якому випадку, майте на увазі, що термінал ( xterm) мало в цьому бере участь (крім показу того, що йому наказано відображати).

І може бути лише один сеанс на процес та на один термінальний пристрій. До сеансу може бути приєднаний контрольний термінал, але це не обов'язково (всі сеанси починаються без терміналу, поки не відкриються). xterm, у процесі, який він має для виконання вашої оболонки, як правило, створить новий сеанс (і тому від'єднається від терміналу, з якого ви запустили, xtermякщо такий є), відкрийте новий, який /dev/pts/xвін породив, приєднавши цей термінальний пристрій до нового сеансу. Потім він виконає вашу оболонку в цьому процесі, тому ваша оболонка стане лідером сесії. Ваша оболонка або будь-яка інтерактивна оболонка під час сеансу зазвичай перемикається з групами процесів і tcsetpgrp()встановлює передній план та фонові завдання для цього терміналу.

Що стосується того, яку інформацію зберігає термінальний пристрій з чіткими дисциплінами (послідовними або pty) , то це, як правило, sttyкоманда відображає та модифікує. Вся конфігурація дисципліни: розмір екрана терміналу, локальний, вхідні прапори виводу, настройки для спеціальних символів (наприклад, ^ C, ^ Z ...), швидкість введення та виведення (не стосується ptys). Це відповідає tcgetattr()/ tcsetattr()функціям, які в Linux відображають TCGETS/ TCSETSioctls, та TIOCGWINSZ/ TIOCSWINSZдля розміру екрана. Ви можете стверджувати, що поточна група процесу переднього плану - це інша інформація, що зберігається в термінальному пристрої ( tcsetpgrp()/ tcgetpgrp(), TIOC{G,S}PGRPйоктлі), або поточному буфері вводу або виводу.

Зауважте, що інформація про розмір екрану, що зберігається в термінальному пристрої, може не відображати реальність. Термінальний емулятор зазвичай встановлює його (через той самий ioctl на головний розмір), коли його вікно змінюється за розміром, але він може вийти з синхронізації, якщо програма викликає ioctl на стороні підлеглого або коли розмір не передається (у випадку з'єднання ssh, що означає інший pty, породжений, sshdякщо, наприклад, sshігнорує SIGWINCH). Деякі термінали також можуть запитувати їх розмір за допомогою послідовностей евакуації, тому програма може запитувати його таким чином і оновлювати дисципліну рядків за допомогою цієї інформації.

Для отримання більш детальної інформації, наприклад, ви можете подивитися на сторінках termiosі tty_ioctlman на Debian.

Грати з іншими лінійками:

  1. Емуляція миші псевдотерміналом:

    socat pty,link=mouse fifo:fifo
    sudo inputattach -msc mouse # sets the MOUSE line discipline and specifies protocol
    xinput list # see the new mouse there
    exec 3<> fifo
    printf '\207\12\0' >&3 # moves the cursor 10 pixels to the right
    

    Вище головна частина pty закінчується socat на названій трубі ( fifo). Ми підключаємо цю фіфою до процесу (оболонки), який записує 0x87 0x0a 0x00, що в протоколі системи миші означає no button pressed, delta(x,y) = (10,0). Тут ми (оболонка) наслідуємо не термінал, а мишею, 3-х байт, які ми надсилаємо, не повинні читатись (потенційно перетворюватися) додатком із термінального пристрою ( mouseнад яким - це посилання, зроблене яким- socatнебудь /dev/pts/xпристроєм) , але слід інтерпретувати як подія введення миші.

  2. Створіть інтерфейс SLIP:

    # on hostA
    socat tcp-listen:12345,reuseaddr pty,link=interface
    # after connection from hostB:
    sudo ldattach SLIP interface
    ifconfig -a # see the new interface there
    sudo ifconfig sl0 192.168.123.1/24
    
    # on hostB
    socat -v -x pty,link=interface tcp:hostA:12345
    sudo ldattach SLIP interface
    sudo ifconfig sl0 192.168.123.2/24
    ping 192.168.123.1 # see the packets on socat output
    

    Вище, послідовний провід емулюється socatяк TCP-розетка між хостомA і хостомB. Дисципліна ліній SLIP інтерпретує ті байти, що обмінюються над цією віртуальною лінією, як IPIP капсульовані IP-пакети для доставки по sl0інтерфейсу.


1
Це найкраща відповідь. Я відзначаю це як правильне і підтримую. Чи можете ви додати останню частину про інформацію, яку зберігають очки? Відповідно до цієї сторінки (глава, що налаштовує пристрій TTY) , очки зберігають такі значення, як кількість рядків та кількість рядків. Чи є у них якась інша інформація, яку він зберігає?
П’єр-Жан

@ П'єр-Жан, додав більше інформації.
Стефан Шазелас

Хоча ваша відповідь набагато виходить задовільною, було б цікаво побачити більш простий приклад того, як ви насправді створюєте / dev / pts / M. Я спробував використовувати, cat /dev/ptmx &що відкриває новий pty, але тоді я не можу знайти пов'язаний з ним процес, тож як би ви його використали? По-друге, я спробував echo "1" >/dev/ptmx, але це нічого не зробило ... Чому мене це цікавить? Оскільки часто, коли один підключається віддалено через ssh(наприклад), ви отримуєте PTY allocation request failedабо No controlling tty: open /dev/ttyпомилку, що заважає контролювати роботу. Було б непогано краще зрозуміти це.
not2qubit

@ user1147688, як створити pty було б інше питання. Це вже занадто багато питань одночасно. Але дивіться ptyсторінку чоловіка для деталей.
Стефан Шазелас

@ StéphaneChazelas Невеликі роз’яснення: 1. Отже, ви говорите, що потік як physical term---- tty---- bashна терміналах, а pty(m)---- tty---- pty(s)---- bashна термінальних емуляторах? Чи відповідала ttyдисципліна також за те, що лунали персонажі на фізичному терміналі? 2. Чи є програма управління емулятором терміналів, яка підключається до клавіатури / екрану для управління входом? 3. Відповідно до того, що я зрозумів, ви сказали, що буферування ліній команд bash / всього термінального введення здійснюється за допомогою ttyдисципліни рядків замість буферів вводу / виводу функцій CI / O. Це правильно?
форумчатор

29

Редагувати: з цієї відповіді я написав у своєму блозі спеціальну статтю для людей, які зацікавляться детальніше.


Після багато прочитаного це я зрозумів.

  • Чи має ptmx будь-яка мета, крім розподілу рабовласницької частини? Чи надає це якийсь "інтелект", або емульований термінал (наприклад, xterm) має весь інтелект поводитись як термінал?

    /dev/ptmxне виділяє підлеглу частину : вона виділяє "основну частину псевдотерміналу". / dev / ptmx не є головним псевдотерміналом : це головний мультиплексор псевдотерміналу . Він створений за стандартом Unix98 PTY, щоб уникнути перегонів при розподілі головного псевдотерміналу ( джерела ).

    Основна частина (ptm) псевдотерміналу не представлена ​​у файловій системі. Він представлений дескриптором файлів.

    Ведена частина (PTS) представлена в файл , /dev/pts/Nде Nцього число.

    КІЗ виходить з PTM через послідовний виклик grandpt, unlockpt, ptsname. ( Джерело )

    Ptm замінить драйвер AUR, призначений для спілкування з пристроєм, та лінійну версію. Таким чином, він ні в якому разі не імітує термінал, але надає функцію редакції рядків і надає спосіб візуалізації та спілкування з очками. ( Джерело )

    Ось графік того, що було TTY, підключене до апаратного пристрою TTY спілкування з AUR

    А ось графік tty, підключений до ptm TTY-зв’язок із PTM

    Файл ptm обробляє різні аргументи Ioctl (ISPTM, UNLKPT, TIOCREMOTE, TIOCSIGNAL), ніж pts.

  • Чому xterm повинен взаємодіяти з основною частиною, оскільки він лише передає stdout і stdin частини підлеглого? Чому він не може безпосередньо писати та читати з файлу pts?

    Процеси взаємодіють із пристроями за допомогою дій, зроблених над віртуальним файлом (читання, запис, ioctl ..). Сам файл не існує, і драйвер використовує файл для запуску дій, коли викликаються методи читання або запису. (Див. Додаток для інформації про водії)

    TTY визначає точний спосіб взаємодії з ним. Процеси запису і зчитування з пристрою і очікують однакової поведінки незалежно від того, який тип TTY реалізований.

    • Функція читання використовується процесами для зчитування записів з терміналу
    • Функція записи використовується процесами для надсилання виводу в термінал

    Очки поводяться як драйвер TTY. Його метод читання і запису використовується для реалізації поведінки драйверів TTY. Оскільки немає реального пристрою для передачі даних, створюється пара потоків, і ptm реалізує функцію зчитування для зчитування даних, які надіслані pts до потоку, і функцію запису для надсилання даних у потік, який буде доступний коли очки прочитають його.

    Пам'ятайте, що файл, що представляє пристрій, не є класичним файлом, і якщо xtermхочеться побачити, що було записано у файл, він не може просто просто викликати відкритий і прочитати його, оскільки тут ці функції мають зовсім іншу поведінку.

  • Чи завжди ідентифікатор сеансу додається до одного файлу pts та навпаки? Чи можу я ввести команду ps і знайшла 2 sessionId для того ж / dev / pts / X?

    Я не думаю, що так, ідентифікатор сеансу визначається першим процесом, який прикріплює pts (bash взагалі), і я не бачу способу створити інший сеанс і приєднати його до тих же pts. Може, такий інструмент socatміг би це зробити?

  • Яку іншу інформацію зберігає тварина? Чи Xterm оновлює всі поля власноруч, чи ptm додає до нього «інтелект»?

    Pts зберігає 2 категорії інформації щодо терміналу, з яким він спілкується: the Terminfoі the Termcap. Зазвичай багато емулятор терміналів базуються на бібліотеці, яка управляє інформацією термінальної капи для них (що надасть усі значення можливостей для імітації, наприклад, VTX100). Прикладом такої бібліотеки є libvte . Редагувати (див. Коментар Стефана Шазеласа): очки не зберігають можливості терміналу.

Додаток


termcap і terminfo - це бази даних про можливості терміналу або терміналу емулятора терміналу, вони не мають нічого спільного з пристроями tty або pty.
Стефан Шазелас

Гаразд, я відредагую свою відповідь. Дякуємо за коментар Чи можете ви додати цю інформацію про бали у своїй відповіді, якщо ви знаєте її (мабуть, pts зберігає розмір екрану, наприклад)?
П’єр-Жан

6
Це приємні образи. Яке програмне забезпечення ви використовували для їх виготовлення?
Жиль

5
@Gilles Дякую Я робив їх з Inkscape , редактором векторної графіки з відкритим кодом. Це, можливо, не найефективніший спосіб зробити такий вид графіки, але якщо вам цікаво, я написав статтю про те, як створити подібні ізометричні малюнки.
П’єр-Жан

Я не думаю, що ви можете коли-небудь приєднати два сеанси до контрольного терміналу або дозволити одному сеансу мати більше одного керуючого терміналу
炸鱼 薯条 德里克

9

Ось схема, яку я створив деякий час тому про те, як sshdпрацює. Це не стосується функціонування лінійної дисципліни та інших предметів, але додає реальну ілюстрацію того, хто з чим взаємодіє:

введіть тут опис зображення


дякую тобі за це. Я пробув 2 дні, намагаючись зрозуміти це. Мені просто цікаво, що станеться, коли жоден pty не створений. stdin не існує, добре, але куди записуються stdout та stderr?
маленький чувак

@emmasculateur радий, що тобі це допомогло. Вибачте, я не можу зрозуміти, що ви маєте на увазі під "коли жодна копія не придумана" Чи можете ви навести приклад того, коли pty не є екземпляром?
Борис Бурков

1
Під "жодним pty не примірник" я маю на увазі, коли ви запускаєте ssh з -T, який чоловік каже, що він вимикає розподіл псевдотерміналів. наприклад: ssh -T emasculateur@localhost "sleep 10" тоді ps aux|grep sleepпоказує це: emasculateur 21826 0.0 0.0 23032 3728 ? Ss 02:49 0:00 zsh -c sleep 10 У тому випадку, де пише bash stdoutі stderr? Сподіваюся, моє питання має сенс.
маленький чувак

@emmasculateur Гм, це гарне питання, має сенс, я просто не думав про це раніше. Я думаю, саме так, ви починаєте свій процес як демон на віддаленій машині, без пов'язаного терміналу. Я здогадуюсь, що його стандартний ввід / вихід / помилка просто /dev/nullподобається звичайному демону, але не впевнений. Дивіться також: serverfault.com/questions/593399/…
Борис Бурков,

@emmasculateur Я також натрапив на інший випадок від вашого: якщо у вашому процесі був термінал, але цей термінал був закритий, процес отримав SIGHUP від ​​ядра при спробі читання / запису stdout / stdin. Це часто вбиває завдання, розпочаті через ssh без nohupабо screen/ tmux.
Борис Бурков

0

man pts каже:

Файл / dev / ptmx - це файл символів з основним числом 5 та другорядним номером 2, як правило, в режимі 0666 та власником.групи root.root. Він використовується для створення псевдо-термінального господаря і підлеглої пари.

Коли процес відкривається / dev / ptmx, він отримує дескриптор файлу для псевдо-термінального ведучого (PTM), а в каталозі / dev / pts створюється пристрій псевдотермінального ведомого (PTS). Кожен дескриптор файлу, отриманий відкриттям / dev / ptmx, є незалежною PTM із власною асоційованою PTS, шлях якої можна знайти, передавши дескриптор ptsname (3).

Перш ніж відкрити псевдотермінальний ведений, ви повинні передати дескриптор файлу головного файлу до grantpt (3) та розблокувати (3).

Після того, як і псевдотермінальний головний, і підлеглий відкриті, ведений забезпечує процеси з інтерфейсом, ідентичним інтерфейсу реального терміналу.

Дані, записані на підлеглому, подаються на головний дескриптор як вхідні дані. Дані, записані ведучому, подаються підлеглому як вхідні дані.

На практиці псевдотермінали використовують для реалізації емуляторів терміналів, таких як xterm (1), в яких дані, зчитувані з головного псевдотерміналу, інтерпретуються додатком так само, як реальний термінал інтерпретував дані, а також для реалізації віддалених -login програми, такі як sshd (8), в яких дані, зчитувані з головного псевдотерміналу, надсилаються по мережі клієнтській програмі, підключеній до терміналу або емулятора терміналу.

Псевдотермінали можуть також використовуватися для надсилання вхідних програм для програм, які зазвичай відмовляються читати вхід з труб (наприклад, su (8) і passwd (8)).

Про /dev/pts/X indexing:

кожен X - це сеанс, який ви відкриваєте, тому рабів потрібно індексувати.

Про TeteType (/dev/ttyN):

Справжня консоль створена вашою системою завантаження, наприклад sysV.

Про те, чому раб покладав господаря: http://commons.wikimedia.org/wiki/File:Termios-script-diagram.png


Вибачте, але ви не відповіли на запитання. Я вже читав сторінку man і бачу цей графік, але поведінка не була зрозумілою. Чи можете ви, як підказує iluminÉ, поширювати свою відповідь відповідно до питань?
П’єр-Жан

СОРІЯ ДЛЯ ЛІЗИ
Перська затока

Для використання підсистеми псевдо-TTY необхідно встановити вузол для ведучого драйвера / dev / ptmx та N кількість ведених драйверів (N визначається при встановленні). Назви ведених пристроїв: / dev / pts / M, де M має значення від 0 до N-1. Користувач отримує доступ до псевдо-TTY-пристрою через головний пристрій (званий ptm), який, в свою чергу, отримує доступ через драйвер клона. Головний пристрій встановлюється як клонний пристрій, де його основний номер пристрою є основним для пристрою клонування та його незначний номер пристрою є основним для драйвера ptm.
Перська затока

так, я читаю сторінку пан ...
Персидська затока

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.