Hlavní navigace

Programujeme v jazyce Assembler v Linuxu: I/O Funkce

Martin Podhola

Třetí díl seriálu nás zavede do oblasti vstupně - výstupních (I/O) funkcí, a tím nám dá možnost zacházet se soubory. Budeme u nich mluvit i o vlastnostech přístupových práv.

Sezame, oteři se – otevření souboru

K této operaci použijeme, logicky, systémové volání open. Tento příkaz zapříčiní kromě otevření souboru i jeho vytvoření v případě, že neexistuje. Pokud při jeho vytváření či otevírání dojde k chybě, funce vrací zápornou hodnotu, jak jsem psal v minulém dílu seriálu.

První parametr tohoto systémového volání je ukazatel na jméno souboru, které je ukončeno nulovým byte. Bitové pole příznaků je předáváno v druhém parametru, v něm předáme jádru mód otevření souboru (viz tabulka), třetí parametr modifikuje přístupová práva k souboru, je nepovinný.

V případě Asmutils můžeme použít všeobecné (céčkové) názvy bitových příznaků:

Tabulka č. 586
O_RDONLY Otevření souboru jen pro čtení
O_WRONLY Otevření souboru jen pro zápis
O_RDWR Otevření souboru jen pro čtení a zápis
O_CREAT Soubor se má vytvořit, pokud neexistuje
O_TRUNC Zkrátit soubor na 0 b (smaže obsah)
O_APPEND Otevři a zapisuj od konce souboru
O_LARGEFILE Nutné u 4GB+ velikých souborů

Obsahuje-li druhý parametr bitový příznak O_CREAT, je nutno nově vytvořenému souboru přidělit jeho přístupová práva. Použijeme symbolické konstanty. Trojice nejčastěji používaných je:

Tabulka č. 587
S_IGRP Práva pro čtení skupině
S_IROTH Práva pro čtení ostatním
S_IRWXU Vlastník má práva RWX

Příklad otevření souboru pro čtení a zápis za použití ASMUTILS:

sys_open name, O_RDWR, EMPTY
test eax, eax
js .error_open
name DB "jmeno_souboru", 0

Bitové příznaky můžeme bez starostí kombinovat, oddělme je však | (znak or nebo roura). Takto otevřeme pro čtení a zápis (nebo vytvoříme a poté otevřeme) soubor s právy 700.

sys_open name, O_RDWR | O_CREAT, S_IRWXU
test eax, eax

js .error_open

Sezame zavři se – uzavírání souboru

Toto je velice snadná operace. Použijeme systémové volání close; jediné, co budeme muset udělat, je použít makro sys_close. Jeho jediným parametrem je identifikátor souboru:

sys_close eax

Psát, počítat, my se naučíme číst – čtení ze souboru

Ke čtení dat ze souboru můžeme použít bloky libovolné délky. Bez bližšího určení se data budou číst od pozice posledního čtení nebo zápisu. Tomuto způsobu se říká sekvenční.

Použijeme systémové volání read. Prvním parametrem je identifikace souboru, druhým je ukazatel na místo v paměti, kam se budou nahrávat přečtená data, třetí udává max počet byte, které se přečtou. Návratová hodnota vrací buď návratový kód -, když nastane chyba, nebo počet skutečně zapsaných byte.

Makro, určené pro čtení ze souboru, se nazývá sys_read, lze ho však použít i ke čtení znaků z klávesnice, musíme je ale načítat ze STDIN.

Číst, počítat, my se naučíme psát – zápis do souboru

Funkce write požaduje stejné parametry jako funkce read, jejím výstupem je počet zapsaných byte nebo chyba.

sys_write STDOUT, nejaka_promenna, eax vypíše obsah proměnné nejaka_promenna na standardní výstup.

Stejně tak se zachází se zápisem na disk. Nezapomeňme však na nastavení vhodných přístupových práv při vytvoření souboru a na vhodný režim při jeho otevírání.

Létající koberec – změna polohy v souboru

Můžeme změnit pozici příštího otevření souboru pro čtení i pro zápis. K tomu použijeme systémové volání lseek.

Prvním parametrem je opět identifikační číslo souboru (handle), druhým parametrem je náš výběr nové pozice v souboru, v bytech. Třetím parametrem (je jím jedna ze tří symbolických konstant) je určení, odkud bude nová pozice souboru měřena. Návratová hodnota této funkce je nová pozice souboru v byte od začátku souboru nebo chybová hodnota.

Pokud bychom chtěli novou pozici v souboru určit absolutně od začátku souboru, použijeme symbolickou konstantu SEEK_SET. Přejeme-li si novou pozici v souboru vytvořit přičtením zadané pozice k aktuální, použijeme konstantu SEEK_CUR. A poslední konstantou je SEEK_END, zadanou pozici přičítá ke konci souboru. Tato konstanta se dá využít k zjištění délky souboru, a to takto:

sys_lseek [fd], 0, SEEK_END

Délku souboru najdeme v návratové hodnotě.

Zajímavostí v operačních systémech typu Unix, oproti třeba MS DOS, je to, že kdybychom vytvořili nový soubor a posunuli ukazatel na konec a soubor uzavřeli v OS DOS, bude místo od začátku souboru až do místa prvního zápisu do souboru vyplněno náhodným obsahem disku (nečitelný binární odpad:). V Unixech je tomu zcela jinak, tento soubor je prázdný, jeho logická velikost je větší než fyzická. To se projeví, když by byl vytvořený soubor na disketě. Může být větší než kapacita diskety.

A ti druzí – ostatní funkce pro práci se soubory

Některé Unixové filesystémy umožňují vytvořit souboru referenci (druhé jméno, link).Podle typu reference na soubor lze rozlišit dva druhy odkazů na soubor.

Prvním typem linku je tzv. hardlink (reference obsahem – dnes již méně používaný). V rámci jednoho filesystému existuje více jmen souborů, které mají zcela stejný obsah i práva a vlastníka. Nevýhoda však je ta, že je nemožné vytvořit odkaz na soubor z jiného filesystému. Nový odkaz se vytváří systémovým voláním link.

Prvním parametrem je ukazatel na linkovaný soubor, druhým je ukazatel na nový název. Návratovou hodnotou volání je nula v případě úspěchu.

Avšak druhá varianta je mnohem flexibilnější. Je to tzv. symlink (reference odkazem). Neodkazujeme se v něm přímo na data v souboru, ale na jeho původní název. Odkaz lze vytvořit na libovolný soubor v libovolném souborovém systému, soubor dokonce nemusí existovat. Avšak volání pro smazání nebo přejmenování budou mít vliv pouze na symlink.

Parametry volání jsou stejné jako u funkce link.

Systémové volání unlink smaže jméno souboru. Soubor bude smazán až po odstranění posledního hardlinku na něj. (Většina souborů na disku má jen jeden hardlink, jeho pojmenování při vytvoření.)

Systémové volání má jeden parametr, je jím ukazatel na název souboru, který chceme smazat. V případě úspěchu je návratovou hodnotou 0.

Poslední funkcí bude funkce rename – slouží pro změnu jména souboru. Prvním parametrem je ukazatel na jméno přejmenovávaného souboru, druhým parametrem je ukazatel na jeho nové jméno.

Závěrem

Dnes jsme si řekli věci nezbytné pro práci se soubory na disku a předvedli si jednoduché ukázky přímo z těchto činností. Tyto instrukce ve spojení se základy z minulého dílu lze využít k napsání několika základních primitivních programů.

Příště si povíme o práci s adresáři, vstupem z klávesnice a o alokaci paměti.

Našli jste v článku chybu?