Do spisu tresci tematu 7
Pseudoterminale zawsze nalezaly do tajemniczych i slabo udokumentowanych wlasciwosci Unixa. W.R.Stevens
W systemie Linux zdefiniowano specjalne urzadzenia nazywajace sie pseudoterminalami. Z grubsza rzecz biorac taki pseudoterminal sklada sie z 2 czesci: nadrzednej i podrzednej. Te 2 czesci moga sie ze soba komunikowac, tak, ze jesli cos zapiszemy do czesci nadrzednej pseudoterminala, to bedziemy w stanie to odczytac z czesci podrzednej i odrotnie. Dlaczego wiec wprowadzono rozroznienie zamiast po prostu polaczyc dwa urzadzenia ?
Aby odpowiedzec na to pytanie, musimy wiedziec po co one powstaly. Otoz wyobrazmy sobie sytuacje ze chcemy zdalnie zglosic sie do systemu.(Zdalnie tu rozumiem ze poprzez np. siec,a nie przez linie szeregowa podlaczona bezposrednio do
maszyny i obslugiwana rowniez przez pewien rodzaj terminala) Mozna to zrobic na 2 sposoby:
- Napisac sterownik urzadzenia, ktory bedzie widziany przez procesy jako terminal. Niestety, przez siec moze sie zglosic wielu uzytkownikow, a takie urzadzenie mielibysmy tylko jedno.
- Napisac sterownik urzadzenia, jak poprzednio, uruchomic proces-demon ktory bedzie w stanie rozpoznawac zadania wejscia do systemu (jak login) i w odpowiedzi bedzie uruchamial interpretatory polecen, komunikujac sie z nimi za pomoca lacz nienazwanych. To podejscie ma jedna wade (oprocz tej ze serwer jest waskim gardlem). Otoz proces, uzywajac funkcji ioctl(...) jest w stanie rozpoznac, czy pracuje na terminalu, czy na innym pliku i, w przypadku gdy stwierdzi ze nie pracuje na terminalu, odmowic wspolpracy. Takie podejscie ma sens, gdyz jedynie z terminala mozemy np. dostac sygnal. Ponadto czesto chcielibysmy uzywac takich wlasnosci terminala jak "tryb pelnoekranowy", dyscyplina linii itp.
Dlatego tez , do realizacji drugiego pomyslu, chcialoby sie miec urzadzenie, ktore:
- zachowywaloby sie jak lacze,ale
- przynajmniej z jednej strony bylo rozpoznawane jako terminal (w szczegolnosci mialo dyscypline linii, moglo wysylac sygnaly itp.)
- Jednak z drugiej strony (tzn. na drugim koncu) pracowalo w trybie surowym (bez jakiejkolwiek ingerencji w przesylane znaki) tak aby proces zajmujacy sie komunikacja po prostu przeslal te znaki w siec w nadziei, ze w zdalnej maszynie zostana one jakos przetworzone.
Dokladnie cos takiego jest zaimplementowane w Linux'ie.
W tty_struct znajduje pole link. To pole jest jest wskaznikiem na terminal - drugiego czlonka pary. Funkcje zdefiniowane dla tych urzadzen sa dosc proste: np pty_write(...) powoduje po prostu natychmiastowe wywolanie funkcji ldisc->receive_room() u drugiego czlonka pary, nie ma kopiowania, gdyz oba urzadzenia maja wspolny bufor tymczasowy.
Otwarcie pseudoterminala jest tez proste: jesli otwieramy pseudoterminal nadrzedny, to od razu tworzymy strukture opisujaca drugiego czlonka pary. Natomiast jesli otwieramy terminal podrzedny, to czekamy az ktos bedzie otwieral odpowiadajacy mu terminal nadrzedny.
Tu uwaga: terminal nadrzedny moze byc otwarty tylko raz tzn. jesli napiszemy programik:
int main(int argc,char ** argv) {
int w1;
int w2;
if ((w1=open("/dev/ptyp3",O_NDELAY,0666))==-1)
{
syserr("open 1");
exit(1);
};
sleep(15);
if ((w2=open("/dev/ttyp3",O_NDELAY,0666))==-1)
{
syserr("open 2");
exit(1);
};
};
i uruchomimy 2 takie w tle, to w jednym druga instrukcja open zakonczy sie bledem, a w drugim obie.
Ponadto pseudoterminal nadrzedny nie moze byc terminalem sterujacym zadnego procesu. To ograniczenie tez ma sens, bo taki terminal mozna traktowac jako furtke, przez ktora proces np. obslugujacy zdane polaczenia albo X-Server posyla znaczki do programow uzywajacych drugiego czlonka pary jako swojego terminala sterujacego; natomiast podlaczenie z obu koncow procesow ktore mialyby sie tylko ze soba komunikowac, sadzac ze pisza do terminala ?
To w zasadzie tyle, co mozna powiedziec o pseudoterminalach w Linux'ie; jesli chodzi o implementacje sa one dosc latwe (chyba najlatwiejsze) do analizy. Natomiast, jesli ktos chce dokladniej wiedziec, jak sie powinno ich uzywac, powinien zajrzec do ksiazki W.R.Stevensa "Programowanie zastosowan sieciowych w systemie Unix" rozdzial 15.
Autor: Kamil Jonca