A UNIX rendszerben egyetlen I/O-vezérlo rendszerhívás van: az ioctl(), de ez a különbözo perifériákon (karakteres speciális fájlokon) más-más dolgokat végezhet (a paramétereit az adott perifériához tartozó device driver kapja meg és úgy értelmezi, ahogyan akarja). A PC-ken például ez a rendszerhívás kapcsolhatja a képernyot grafikus megjelenítési módba.
Egyetlen használatát érdemes megnézni ennek a rendszerhívásnak: a terminál-módok beállítását.
A UNIX rendszerekben a terminál device driverje három különféle módon muködhet: raw, cbreak illetve cooked módban. A raw üzemmódban a terminálon (bilentyuzeten, RS-232 vonalon, ...) beadott karakterek egyenként át lesznek adva a felhasználói programnak, ekkor minden billentyu "egyenrangú", a speciális billentyuknek (pl. backspace, CTRL-S, CTRL-Q stb.) ekkor nincs semmi hatásuk a programra. A cbreak módban a karakterek szintén egyenként lesznek a felhasználói programnak átadva, de a speciális billentyuket ekkor az operációs rendszer "elkapja", feldolgozza, és ezeket nem adja tovább a felhasználói programnak. A speciális billentyuket és hatásukak a következo táblázat foglalja össze (a lista nem teljes):
\
: SIGQUIT signal küldése a futó programnak, hogy álljon le, és
a memória tartalmát az operációs
rendszer egy core nevu fájlba kimenti az
aktuális directoryba. (Azaz egy core-dumpot készít róla az operációs
rendszer, amit késobb egy debuggerrel elemezni lehet ...).
A cooked módban az operációs rendszer sorvége- (vagy fájlvége-)jellel lezárt egész sorokat olvas be a billentyuzetrol, és a beolvasott sort egyben adja á a felhasználói programnak. A felhasználó a backspace billentyut használhatja a beadott karakterek törlésére, és a fent említett speciális funkciójú billentyuk is hatásosak.
A terminál-paraméterek egy termio struktúra típusú változóba lekérdezhetok az operációs rendszertol, és ha akarjuk, akkor ezt megváltoztathatjuk, majd visszaadhatjuk az operációs rendszernek, hogy állítsa be a belso strukturáit ennek megfeleloen. A struktúra szerkezete a következo (itt is a teljesség igénye nélkül):
#define NCC .... struct termio { short c_iflag; short c_oflag; short c_cflag; short c_lflag; char c_line; short c_cc[NCC]; };
Az egyes mezokben a fent említett módokat, RS-232 terminálnál a baudrate
értékét, a karaktertörlo billentyu és más speciális billentyuk
kódját lehet megadni, és még sok-sok más dolgot (pl. az operációs
rendszer
végezzen-e a beadott karaktereken CR-->LF
konverziót vagy sem, ... -- ez
hasznos lehet például terminál-emulátor programok készítésénél, de
errol most nem írok részletesebben).
A terminálparamétereket a
ioctl(tfd, TCGETA, &tpars);
rendszerhívással lehet lekérdezni egy tpars (struct termio típusú) változóba (tfd a terminálhoz kapcsolt fájl, lehet például 0 is, ha a szabványos bemenet a terminálhoz van kötve). A paramétereket átállítani így lehet:
ioctl(tfd, TCPUTA, &tpars);
RAW módba kapcsoláshoz a következo paramétereket kell átállítani:
/* ioctl ... */ oldlflag=lflag; /* Elozo modot elmentem */ lflag=(lflag & ~(ECHO | ISIG | ICANON); /* Karaktervisszairast (ECHO-t) is kikapcsolom */
Vissza az "elozo" módba:
lflag=oldlflag; /* ioctl ... */
(Megjegyzés: ezek a muveletek egyes UNIX rendszerekben lehet, hogy máshogy mennek, esetleg más mezonevek vannak a termio struktúrában, ... ennek érdemes utánanézni mondjuk a "man termio" paranccsal. Ezeknek a beállítására egyébként létezik egy curses nevu standard könyvtár is benne a raw(), cooked(), cbreak() függvényekkel, amit ha kell használhatunk.)
A UNIX kernelnek azt a részét nevezik line discipline modulnak, amely a teriminálinterfaceen bejövo karakterek feldolgozását végzi a fenti szempontok szerint.