bloka kosvennoj adresacii. Tak zhe, kak v algoritme read, yadro vhodit v cikl, zapisyvaya na disk po odnomu bloku na kazhdoj iteracii. Pri etom na kazhdoj iteracii yadro opredelya- et, budet li proizvodit'sya zapis' celogo bloka ili tol'ko ego chasti. Esli zapisyvaetsya tol'ko chast' bloka, yadro v pervuyu ochered' schityvaet blok s dis- ka dlya togo, chtoby ne zateret' te chasti, kotorye ostalis' bez izmenenij, a esli zapisyvaetsya celyj blok, yadru ne nuzhno chitat' ves' blok, tak kak v lyu- bom sluchae ono zatret predydushchee soderzhimoe bloka. Zapis' osushchestvlyaetsya poblochno, odnako yadro ispol'zuet otlozhennuyu zapis' (razdel 3.4) dannyh na disk, zapominaya ih v keshe na sluchaj, esli oni ponadobyatsya vskore drugomu processu dlya chteniya ili zapisi, a takzhe dlya togo, chtoby izbezhat' lishnih ob- rashchenij k disku. Otlozhennaya zapis', veroyatno, naibolee effektivna dlya kana- lov, tak kak drugoj process chitaet kanal i udalyaet iz nego dannye (razdel 5.12). No dazhe dlya obychnyh fajlov otlozhennaya zapis' effektivna, esli fajl sozdaetsya vremenno i vskore budet prochitan. Naprimer, mnogie programmy, ta- kie kak redaktory i elektronnaya pochta, sozdayut vremennye fajly v kataloge "/tmp" i bystro udalyayut ih. Ispol'zovanie otlozhennoj zapisi mozhet sokratit' kolichestvo obrashchenij k disku dlya zapisi vo vremennye fajly. 5.4 ZAHVAT FAJLA I ZAPISI V pervoj versii sistemy UNIX, razrabotannoj Tompsonom i Richi, otsutstvo- val vnutrennij mehanizm, s pomoshch'yu kotorogo processu mog by byt' obespechen isklyuchitel'nyj dostup k fajlu. Mehanizm zahvata byl priznan izlishnim, pos- kol'ku, kak otmechaet Richi, "my ne imeem dela s bol'shimi bazami dannyh, sos- toyashchimi iz odnogo fajla, kotorye podderzhivayutsya nezavisimymi processami" (sm. [Ritchie 81]). Dlya togo, chtoby povysit' privlekatel'nost' sistemy UNIX dlya kommercheskih pol'zovatelej, rabotayushchih s bazami dannyh, v versiyu V sis- temy nyne vklyucheny mehanizmy zahvata fajla i zapisi. Zahvat fajla - eto sredstvo, pozvolyayushchee zapretit' drugim processam proizvodit' chtenie ili za- pis' lyuboj chasti fajla, a zahvat zapisi - eto sredstvo, pozvolyayushchee zapre- tit' drugim processam proizvodit' vvod-vyvod ukazannyh zapisej (chastej fajla mezhdu ukazannymi smeshcheniyami). V uprazhnenii 5.9 rassmatrivaetsya realizaciya mehanizma zahvata fajla i zapisi. 5.5 UKAZANIE MESTA V FAJLE, GDE BUDET VYPOLNYATXSYA VVOD-VYVOD - LSEEK Obychnoe ispol'zovanie sistemnyh funkcij read i write obespechivaet posle- dovatel'nyj dostup k fajlu, odnako processy mogut ispol'zovat' vyzov sistem- noj funkcii lseek dlya ukazaniya mesta v fajle, gde budet proizvodit'sya vvod-vyvod, i osushchestvleniya proizvol'nogo dostupa k fajlu. Sintaksis vyzova sistemnoj funkcii: position = lseek(fd,offset,reference); gde fd - deskriptor fajla, identificiruyushchij fajl, offset - smeshchenie v baj- tah, a reference ukazyvaet, yavlyaetsya li znachenie offset smeshcheniem ot nachala fajla, smeshcheniem ot tekushchej pozicii vvoda-vyvoda ili smeshcheniem ot konca faj- la. Vozvrashchaemoe znachenie, position, yavlyaetsya smeshcheniem v bajtah do mesta, 96 gde budet nachinat'sya sleduyushchaya operaciya chteniya ili zapisi. Naprimer, v prog- ramme, privedennoj na Risunke 5.10, process otkryvaet fajl, schityvaet bajt, a zatem vyzyvaet funkciyu lseek, chtoby zamenit' znachenie polya smeshcheniya v tab- lice fajlov velichinoj, ravnoj 1023 (s peremennoj reference, imeyushchej znachenie 1), i vypolnyaet cikl. Takim obrazom, programma schityvaet kazhdyj 1024-j bajt fajla. Esli reference imeet znachenie 0, yadro osushchestvlyaet poisk ot nachala fajla, a esli 2, yadro vedet poisk ot konca fajla. Funkciya lseek nichego ne dolzhna delat', krome operacii poiska, kotoraya pozicioniruet golovku chte- niya-zapisi na ukazannyj diskovyj sektor. Dlya togo, chtoby vypolnit' funkciyu lseek, yadro prosto vybiraet znachenie smeshcheniya iz tablicy fajlov; v posleduyu- shchih vyzovah funkcij read i write smeshchenie iz tablicy fajlov ispol'zuetsya v kachestve nachal'nogo smeshcheniya. 5.6 CLOSE Process zakryvaet otkrytyj fajl, kogda processu bol'she ne nuzhno obra- shchat'sya k nemu. Sintaksis vyzova sistemnoj funkcii close (zakryt'): +--------------------------------------------------------+ | #include | | main(argc,argv) | | int argc; | | char *argv[]; | | { | | int fd,skval; | | char c; | | | | if(argc != 2) | | exit(); | | fd = open(argv[1],O_RDONLY); | | if (fd == -1) | | exit(); | | while ((skval = read(fd,&c,1)) == 1) | | { | | printf("char %c\n",c); | | skval = lseek(fd,1023L,1); | | printf("new seek val %d\n",skval); | | } | | } | +--------------------------------------------------------+ Risunok 5.10. Programma, soderzhashchaya vyzov sistemnoj funkcii lseek close(fd); gde fd - deskriptor otkrytogo fajla. YAdro vypolnyaet operaciyu zakrytiya, is- pol'zuya deskriptor fajla i informaciyu iz sootvetstvuyushchih zapisej v tablice fajlov i tablice indeksov. Esli schetchik ssylok v zapisi tablicy fajlov imeet znachenie, bol'shee, chem 1, v svyazi s tem, chto byli obrashcheniya k funkciyam dup ili fork, to eto oznachaet, chto na zapis' v tablice fajlov delayut ssylku dru- gie pol'zovatel'skie deskriptory, chto my uvidim dalee; yadro umen'shaet znache- nie schetchika i operaciya zakrytiya zavershaetsya. Esli schetchik ssylok v tablice fajlov imeet znachenie, ravnoe 1, yadro osvobozhdaet zapis' v tablice i indeks v pamyati, ranee vydelennyj sistemnoj funkciej open (algoritm iput). Esli drugie processy vse eshche ssylayutsya na indeks, yadro umen'shaet znachenie schetchi- ka ssylok na indeks, no ostavlyaet indeks processam; v protivnom sluchae in- deks osvobozhdaetsya dlya perenaznacheniya, tak kak ego schetchik ssylok soderzhit 0. Kogda vypolnenie sistemnoj funkcii close zavershaetsya, zapis' v tablice 97 pol'zovatel'skih deskriptorov fajla stanovitsya pustoj. Popytki processa is- pol'zovat' dannyj deskriptor zakanchivayutsya oshibkoj do teh por, poka deskrip- tor ne budet perenaznachen drugomu fajlu v rezul'tate vypolneniya drugoj sis- temnoj funkcii. Kogda process zavershaetsya, yadro proveryaet nalichie aktivnyh pol'zovatel'skih deskriptorov fajla, prinadlezhavshih processu, i zakryvaet kazhdyj iz nih. Takim obrazom, ni odin process ne mozhet ostavit' fajl otkry- tym posle svoego zaversheniya. Na Risunke 5.11, naprimer, pokazany zapisi iz tablic, privedennyh na Ri- sunke 5.4, posle togo, kak vtoroj process zakryvaet sootvetstvuyushchie im faj- ly. Zapisi, sootvetstvuyushchie deskriptoram 3 i 4 v tablice pol'zovatel'skih pol'zovatel'skie deskrip- tory fajla tablica fajlov tablica indeksov +---------+ +------------+ +--------------+ 0| | | | | - | +---------+ | | | - | 1| | | | | - | +---------+ +------------+ | - | 2| | | - | | - | +---------+ | - | | - | 3| ----+----+ | - | | - | +---------+ | | - | +--------------+ 4| ----+---+| | - | +---->| schet- | +---------+ || | - | | | chik (/etc/ | 5| ----+--+|| +------------+ | +-->| 2 passwd)| +---------+ ||| | schet- | | | +--------------+ | - | ||+-->| chik +--+ | | - | | - | || | 1 | | | - | | - | || +------------+ | | - | +---------+ || | - | | | - | || | - | | | - | +---------+ || | - | | | - | 0| | || +------------+ | | - | +---------+ || | schet- | | | - | 1| | |+--->| chik +----|+ | - | +---------+ | | 1 | || | - | 2| | | +------------+ || | - | +---------+ | | - | || +--------------+ 3| NULL | | | - | || | schet- | +---------+ | | - | |+->| chik (local)| 4| NULL | | | - | | | 1 | +---------+ | | - | | +--------------+ 5| | | | - | | | - | +---------+ | +------------+ | | - | | - | | | schetchik 0 | | | - | +---------+ | +------------+ | | - | | | - | | +--------------+ | | - | | | schet- | | +------------+ | | chik (private)| | | schetchik 1 | | | 0 | +---->| +----+ +--------------+ +------------+ | - | | - | +--------------+ | - | +------------+ | schetchik 0 | +------------+ Risunok 5.11. Tablicy posle zakrytiya fajla 98 deskriptorov fajlov, pusty. Schetchiki v zapisyah tablicy fajlov teper' imeyut znachenie 0, a sami zapisi pusty. Schetchiki ssylok na fajly "/etc/passwd" i "private" v indeksah takzhe umen'shilis'. Indeks dlya fajla "private" nahoditsya v spiske svobodnyh indeksov, poskol'ku schetchik ssylok na nego raven 0, no zapis' o nem ne pusta. Esli eshche kakoj-nibud' process obratitsya k fajlu "private", poka indeks eshche nahoditsya v spiske svobodnyh indeksov, yadro vostrebuet indeks obratno, kak pokazano v razdele 4.1.2. 5.7 SOZDANIE FAJLA Sistemnaya funkciya open daet processu dostup k sushchestvuyushchemu fajlu, a sistemnaya funkciya creat sozdaet v sisteme novyj fajl. Sintaksis vyzova sis- temnoj funkcii creat: fd = creat(pathname,modes); gde peremennye pathname, modes i fd imeyut tot zhe smysl, chto i v sistemnoj funkcii open. Esli prezhde takogo fajla ne sushchestvovalo, yadro sozdaet novyj fajl s ukazannym imenem i ukazannymi pravami dostupa k nemu; esli zhe takoj fajl uzhe sushchestvoval, yadro usekaet fajl (osvobozhdaet vse sushchestvuyushchie bloki +------------------------------------------------------------+ | algoritm creat | | vhodnaya informaciya: imya fajla | | ustanovki prav dostupa k fajlu | | vyhodnaya informaciya: deskriptor fajla | | { | | poluchit' indeks dlya dannogo imeni fajla (algoritm namei);| | esli (fajl uzhe sushchestvuet) | | { | | esli (dostup ne razreshen) | | { | | osvobodit' indeks (algoritm iput); | | vozvratit' (oshibku); | | } | | } | | v protivnom sluchae /* fajl eshche ne sushchestvuet */ | | { | | naznachit' svobodnyj indeks iz fajlovoj sistemy (algo- | | ritm ialloc); | | sozdat' novuyu tochku vhoda v roditel'skom kataloge: | | vklyuchit' imya novogo fajla i nomer vnov' naznachennogo | | indeksa; | | } | | vydelit' dlya indeksa zapis' v tablice fajlov, inicializi-| | rovat' schetchik; | | esli (fajl sushchestvoval k momentu sozdaniya) | | osvobodit' vse bloki fajla (algoritm free); | | snyat' blokirovku (s indeksa); | | vozvratit' (pol'zovatel'skij deskriptor fajla); | | } | +------------------------------------------------------------+ Risunok 5.12. Algoritm sozdaniya fajla 99 dannyh i ustanavlivaet razmer fajla ravnym 0) pri nalichii sootvetstvuyushchih prav dostupa k nemu (***). Na Risunke 5.12 priveden algoritm sozdaniya fajla. YAdro provodit sintaksicheskij analiz imeni puti poiska, ispol'zuya algo- ritm namei i sleduya etomu algoritmu bukval'no, kogda rech' idet o razbore imen katalogov. Odnako, kogda delo kasaetsya poslednej komponenty imeni puti poiska, a imenno identifikatora sozdavaemogo fajla, namei otmechaet smeshchenie v bajtah do pervoj pustoj pozicii v kataloge i zapominaet eto smeshchenie v prostranstve processa. Esli yadro ne obnaruzhilo v kataloge komponentu imeni puti poiska, ono v ko- nechnom schete vpishet imya komponenty v tol'ko chto najdennuyu pustuyu poziciyu. Esli v kataloge net pustyh pozicij, yadro zapominaet smeshchenie do konca kata- loga i sozdaet novuyu poziciyu tam. Ono takzhe zapominaet v prostranstve pro- cessa indeks prosmatrivaemogo kataloga i derzhit indeks zablokirovannym; ka- talog stanovitsya po otnosheniyu k novomu fajlu roditel'skim katalogom. YAdro ne zapisyvaet poka imya novogo fajla v katalog, tak chto v sluchae vozniknoveniya oshibok yadru prihoditsya men'she peredelyvat'. Ono proveryaet nalichie u processa razresheniya na zapis' v katalog. Poskol'ku process budet proizvodit' zapis' v katalog v rezul'tate vypolneniya funkcii creat, nalichie razresheniya na zapis' v katalog oznachaet, chto processam dozvolyaetsya sozdavat' fajly v kataloge. Predpolozhiv, chto pod dannym imenem ranee ne sushchestvovalo fajla, yadro naznachaet novomu fajlu indeks, ispol'zuya algoritm ialloc (razdel 4.6). Zatem ono zapisyvaet imya novogo fajla i nomer vnov' vydelennogo indeksa v rodi- tel'skij katalog, a smeshchenie v bajtah sohranyaet v prostranstve processa. Vposledstvii yadro osvobozhdaet indeks roditel'skogo kataloga, uderzhivaemyj s togo vremeni, kogda v kataloge proizvodilsya poisk imeni fajla. Roditel'skij katalog teper' soderzhit imya novogo fajla i ego indeks. YAdro zapisyvaet vnov' vydelennyj indeks na disk (algoritm bwrite), prezhde chem zapisat' na disk ka- talog s novym imenem. Esli mezhdu operaciyami zapisi indeksa i kataloga proi- zojdet sboj sistemy, v itoge okazhetsya, chto vydelen indeks, na kotoryj ne ssylaetsya ni odno iz imen putej poiska v sisteme, odnako sistema budet funk- cionirovat' normal'no. Esli, s drugoj storony, katalog byl zapisan ran'she vnov' vydelennogo indeksa i sboj sistemy proizoshel mezhdu nimi, fajlovaya sis- tema budet soderzhat' imya puti poiska, ssylayushcheesya na nevernyj indeks (bolee podrobno ob etom sm. v razdele 5.16.1). Esli dannyj fajl uzhe sushchestvoval do vyzova funkcii creat, yadro obnaruzhi- vaet ego indeks vo vremya poiska imeni fajla. Staryj fajl dolzhen pozvolyat' processu proizvodit' zapis' v nego, chtoby mozhno bylo sozdat' "novyj" fajl s tem zhe samym imenem, tak kak yadro izmenyaet soderzhimoe fajla pri vypolnenii funkcii creat: ono usekaet fajl, osvobozhdaya vse informacionnye bloki po al- goritmu free, tak chto fajl budet vyglyadet' kak vnov' sozdannyj. Tem ne me- nee, vladelec i prava dostupa k fajlu ostayutsya prezhnimi: yadro ne peredaet pravo sobstvennosti na fajl vladel'cu processa i ignoriruet prava dostupa, ukazannye processom v vyzove funkcii. Nakonec, yadro ne proveryaet nalichie razresheniya na zapis' v katalog, yavlyayushchijsya roditel'skim dlya sushchestvuyushchego fajla, poskol'ku ono ne menyaet soderzhimogo kataloga. Funkciya creat prodolzhaet rabotu, vypolnyaya tot zhe algoritm, chto i funkciya open. YAdro vydelyaet sozdannomu fajlu zapis' v tablice fajlov, chtoby process mog chitat' iz fajla, a takzhe zapis' v tablice pol'zovatel'skih deskriptorov fajla, i v konce koncov vozvrashchaet ukazatel' na poslednyuyu zapis' v vide pol'zovatel'skogo deskriptora fajla. --------------------------------------- (***) Sistemnaya funkciya open imeet dva flaga, O_CREAT (sozdanie) i O_TRUNC (usechenie). Esli process ustanavlivaet v vyzove funkcii flag O_CREAT i fajl ne sushchestvuet, yadro sozdast fajl. Esli fajl uzhe sushchestvuet, on ne budet usechen, esli tol'ko ne ustanovlen flag O_TRUNC. 100 5.8 SOZDANIE SPECIALXNYH FAJLOV Sistemnaya funkciya mknod sozdaet v sisteme special'nye fajly, v chislo ko- toryh vklyuchayutsya poimenovannye kanaly, fajly ustrojstv i katalogi. Ona poho- zha na funkciyu creat v tom, chto yadro vydelyaet dlya fajla indeks. Sintaksis vy- zova sistemnoj funkcii mknod: mknod(pathname,type and permissions,dev) gde pathname - imya sozdavaemoj vershiny v ierarhicheskoj strukture fajlovoj sistemy, type and permissions - tip vershiny (naprimer, katalog) i prava dos- tupa k sozdavaemomu fajlu, a dev ukazyvaet starshij i mladshij nomera ustrojs- tva dlya blochnyh i simvol'nyh special'nyh fajlov (glava 10). Na Risunke 5.13 priveden algoritm, realizuemyj funkciej mknod pri sozdanii novoj vershiny. +------------------------------------------------------------+ | algoritm sozdaniya novoj vershiny | | vhodnaya informaciya: vershina (imya fajla) | | tip fajla | | prava dostupa | | starshij, mladshij nomera ustrojstva | | (dlya blochnyh i simvol'nyh special'nyh | | fajlov) | | vyhodnaya informaciya: otsutstvuet | | { | | esli (novaya vershina ne yavlyaetsya poimenovannym kanalom | | i pol'zovatel' ne yavlyaetsya superpol'zovatelem) | | vozvratit' (oshibku); | | poluchit' indeks vershiny, yavlyayushchejsya roditel'skoj dlya | | novoj vershiny (algoritm namei); | | esli (novaya vershina uzhe sushchestvuet) | | { | | osvobodit' roditel'skij indeks (algoritm iput); | | vozvratit' (oshibku); | | } | | naznachit' dlya novoj vershiny svobodnyj indeks iz fajlovoj| | sistemy (algoritm ialloc); | | sozdat' novuyu zapis' v roditel'skom kataloge: vklyuchit' | | imya novoj vershiny i nomer vnov' naznachennogo indeksa; | | osvobodit' indeks roditel'skogo kataloga (algoritm | | iput); | | esli (novaya vershina yavlyaetsya blochnym ili simvol'nym spe-| | cial'nym fajlom) | | zapisat' starshij i mladshij nomera v strukturu indek-| | sa; | | osvobodit' indeks novoj vershiny (algoritm iput); | | } | +------------------------------------------------------------+ Risunok 5.13. Algoritm sozdaniya novoj vershiny YAdro prosmatrivaet fajlovuyu sistemu v poiskah imeni fajla, kotoryj ono sobiraetsya sozdat'. Esli fajl eshche poka ne sushchestvuet, yadro naznachaet emu no- vyj indeks na diske i zapisyvaet imya novogo fajla i nomer indeksa v rodi- tel'skij katalog. Ono ustanavlivaet znachenie polya tipa fajla v indekse, uka- zyvaya, chto fajl yavlyaetsya kanalom, katalogom ili special'nym fajlom. Nakonec, esli fajl yavlyaetsya special'nym fajlom ustrojstva blochnogo ili simvol'nogo tipa, yadro zapisyvaet v indeks starshij i mladshij nomera ustrojstva. Esli funkciya mknod sozdaet katalog, on budet sushchestvovat' po zavershenii vypolne- niya funkcii, no ego soderzhimoe budet imet' nevernyj format (v kataloge budut 101 otsutstvovat' zapisi s imenami "." i ".."). V uprazhnenii 5.33 rassmatrivayut- sya shagi, neobhodimye dlya preobrazovaniya soderzhimogo kataloga v pravil'nyj format. +------------------------------------------------------------+ | algoritm smeny kataloga | | vhodnaya informaciya: imya novogo kataloga | | vyhodnaya informaciya: otsutstvuet | | { | | poluchit' indeks dlya kataloga s novym imenem (algoritm | | namei); | | esli (indeks ne yavlyaetsya indeksom kataloga ili zhe pro- | | cessu ne razreshen dostup k fajlu) | | { | | osvobodit' indeks (algoritm iput); | | vozvratit' (oshibku); | | } | | snyat' blokirovku s indeksa; | | osvobodit' indeks prezhnego tekushchego kataloga (algoritm | | iput); | | pomestit' novyj indeks v poziciyu dlya tekushchego kataloga | | v prostranstve processa; | | } | +------------------------------------------------------------+ Risunok 5.14. Algoritm smeny tekushchego kataloga 5.9 SMENA TEKUSHCHEGO I KORNEVOGO KATALOGA Kogda sistema zagruzhaetsya vpervye, nulevoj process delaet kornevoj kata- log fajlovoj sistemy tekushchim na vremya inicializacii. Dlya indeksa kornevogo kataloga nulevoj process vypolnyaet algoritm iget, sohranyaet etot indeks v prostranstve processa v kachestve indeksa tekushchego kataloga i snimaet s in- deksa blokirovku. Kogda s pomoshch'yu funkcii fork sozdaetsya novyj process, on nasleduet tekushchij katalog starogo processa v svoem adresnom prostranstve, a yadro, sootvetstvenno, uvelichivaet znachenie schetchika ssylok v indekse. Algoritm chdir (Risunok 5.14) izmenyaet imya tekushchego kataloga dlya proces- sa. Sintaksis vyzova sistemnoj funkcii chdir: chdir(pathname); gde pathname - katalog, kotoryj stanovitsya tekushchim dlya processa. YAdro anali- ziruet imya kataloga, ispol'zuya algoritm namei, i proveryaet, yavlyaetsya li dan- nyj fajl katalogom i imeet li vladelec processa pravo dostupa k kataloga. YAdro snimaet s novogo indeksa blokirovku, no uderzhivaet indeks v kachestve vydelennogo i ostavlyaet schetchik ssylok bez izmenenij, osvobozhdaet indeks prezhnego tekushchego kataloga (algoritm iput), hranyashchijsya v prostranstve pro- cessa, i zapominaet v etom prostranstve novyj indeks. Posle smeny processom tekushchego kataloga algoritm namei ispol'zuet indeks v kachestve nachal'nogo ka- taloga pri analize vseh imen putej, kotorye ne berut nachalo ot kornya. Po okonchanii vypolneniya sistemnoj funkcii chdir schetchik ssylok na indeks novogo kataloga imeet znachenie, kak minimum, 1, a schetchik ssylok na indeks prezhnego tekushchego kataloga mozhet stat' ravnym 0. V etom otnoshenii funkciya chdir poho- zha na funkciyu open, poskol'ku obe funkcii obrashchayutsya k fajlu i ostavlyayut ego indeks v kachestve vydelennogo. Indeks, vydelennyj vo vremya vypolneniya funk- cii chdir, osvobozhdaetsya tol'ko togda, kogda process menyaet tekushchij katalog eshche raz ili kogda process zavershaetsya. 102 Processy obychno ispol'zuyut global'nyj kornevoj katalog fajlovoj sistemy dlya vseh imen putej poiska, nachinayushchihsya s "/". YAdro hranit global'nuyu pere- mennuyu, kotoraya ukazyvaet na indeks global'nogo kornya, vydelyaemyj po algo- ritmu iget pri zagruzke sistemy. Processy mogut menyat' svoe predstavlenie o kornevom kataloge fajlovoj sistemy s pomoshch'yu sistemnoj funkcii chroot. |to byvaet polezno, esli pol'zovatelyu nuzhno sozdat' model' obychnoj ierarhicheskoj struktury fajlovoj sistemy i zapustit' processy tam. Sintaksis vyzova funk- cii: chroot(pathname); gde pathname - katalog, kotoryj vposledstvii budet rassmatrivat'sya yadrom v kachestve kornevogo kataloga dlya processa. Vypolnyaya funkciyu chroot, yadro sle- duet tomu zhe algoritmu, chto i pri smene tekushchego kataloga. Ono zapominaet indeks novogo kornya v prostranstve processa, snimaya s indeksa blokirovku po zavershenii vypolneniya funkcii. Tem ne menee, tak kak umolchanie na koren' dlya yadra hranitsya v global'noj peremennoj, yadro osvobozhdaet indeks prezhnego kor- nya ne avtomaticheski, a tol'ko posle togo, kak ono samo ili process-predok ispolnyat vyzov funkcii chroot. Novyj indeks stanovitsya logicheskim kornem fajlovoj sistemy dlya processa (i dlya vseh porozhdennyh im processov) i eto oznachaet, chto vse puti poiska v algoritme namei, nachinayushchiesya s kornya ("/"), voz'mut nachalo s dannogo indeksa i chto vse popytki vojti v katalog ".." nad kornem privedut k tomu, chto rabochim katalogom processa ostanetsya novyj ko- ren'. Process peredaet vsem vnov' porozhdaemym processam etot katalog v ka- chestve kornevogo podobno tomu, kak peredaet svoj tekushchij katalog. 5.10 SMENA VLADELXCA I REZHIMA DOSTUPA K FAJLU Smena vladel'ca ili rezhima (prav) dostupa k fajlu yavlyaetsya operaciej, proizvodimoj nad indeksom, a ne nad fajlom. Sintaksis vyzova sootvetstvuyushchih sistemnyh funkcij: chown(pathname,owner,group) chmod(pathname,mode) Dlya togo, chtoby pomenyat' vladel'ca fajla, yadro preobrazuet imya fajla v identifikator indeksa, ispol'zuya algoritm namei. Vladelec processa dolzhen byt' superpol'zovatelem ili vladel'cem fajla (process ne mozhet rasporyazhat'sya tem, chto ne prinadlezhit emu). Zatem yadro naznachaet fajlu novogo vladel'ca i novogo gruppovogo pol'zovatelya, sbrasyvaet flagi prezhnih ustanovok (sm. raz- del 7.5) i osvobozhdaet indeks po algoritmu iput. Posle etogo prezhnij vlade- lec teryaet pravo "sobstvennosti" na fajl. Dlya togo, chtoby pomenyat' rezhim dostupa k fajlu, yadro vypolnyaet proceduru, podobnuyu opisannoj, vmesto koda vladel'ca menyaya flagi, ustanavlivayushchie rezhim dostupa. 5.11 STAT I FSTAT Sistemnye funkcii stat i fstat pozvolyayut processam zaprashivat' informa- ciyu o statuse fajla: tipe fajla, vladel'ce fajla, pravah dostupa, razmere fajla, chisle svyazej, nomere indeksa i vremeni dostupa k fajlu. Sintaksis vy- zova funkcij: stat(pathname,statbuffer); fstat(fd,statbuffer); gde pathname - imya fajla, fd - deskriptor fajla, vozvrashchaemyj funkciej open, statbuffer - adres struktury dannyh pol'zovatel'skogo processa, gde budet 103 hranit'sya informaciya o statuse fajla posle zaversheniya vypolneniya vyzova. Sistemnye funkcii prosto perepisyvayut polya iz indeksa v strukturu statbuffer. Programma na Risunke 5.33 illyustriruet ispol'zovanie funkcij stat i fstat. Vyzyvaet kanal Ne mogut sovmestno ispol'zovat' - kanal - - - - - - - - - - Process A - - | - - +-------------+--------------+ - - | | - Process B Process C | +-------+-------+ | | Process D - Process E - - - - - - - - - - Sovmestno ispol'zuyut kanal Risunok 5.15. Derevo processov i sovmestnoe ispol'zovanie kanalov 5.12 KANALY Kanaly pozvolyayut peredavat' dannye mezhdu processami v poryadke postuple- niya ("pervym prishel - pervym vyshel"), a takzhe sinhronizirovat' vypolnenie processov. Ih ispol'zovanie daet processam vozmozhnost' vzaimodejstvovat' mezhdu soboj, pust' dazhe ne izvestno, kakie processy nahodyatsya na drugom kon- ce kanala. Tradicionnaya realizaciya kanalov ispol'zuet fajlovuyu sistemu dlya hraneniya dannyh. Razlichayut dva vida kanalov: poimenovannye kanaly i, za ot- sutstviem luchshego termina, nepoimenovannye kanaly, kotorye identichny mezhdu soboj vo vsem, krome sposoba pervonachal'nogo obrashcheniya k nim processov. Dlya poimenovannyh kanalov processy ispol'zuyut sistemnuyu funkciyu open, a sistem- nuyu funkciyu pipe - dlya sozdaniya nepoimenovannogo kanala. Vposledstvii, pri rabote s kanalami processy pol'zuyutsya obychnymi sistemnymi funkciyami dlya faj- lov, takimi kak read, write i close. Tol'ko svyazannye mezhdu soboj processy, yavlyayushchiesya potomkami togo processa, kotoryj vyzval funkciyu pipe, mogut raz- delyat' dostup k nepoimenovannym kanalam. Naprimer (sm. Risunok 5.15), esli process B sozdaet kanal i porozhdaet processy D i E, eti tri processa razde- lyayut mezhdu soboj dostup k kanalu, v otlichie ot processov A i C. Odnako, vse processy mogut obrashchat'sya k poimenovannomu kanalu nezavisimo ot vzaimootno- shenij mezhdu nimi, pri uslovii nalichiya obychnyh prav dostupa k fajlu. Poskol'- ku nepoimenovannye kanaly vstrechayutsya chashche, oni budut rassmotreny pervymi. 5.12.1 Sistemnaya funkciya pipe Sintaksis vyzova funkcii sozdaniya kanala: pipe(fdptr); 104 gde fdptr - ukazatel' na massiv iz dvuh celyh peremennyh, v kotorom budut hranit'sya dva deskriptora fajla dlya chteniya iz kanala i dlya zapisi v kanal. Poskol'ku yadro realizuet kanaly vnutri fajlovoj sistemy i poskol'ku kanal ne sushchestvuet do togo, kak ego budut ispol'zovat', yadro dolzhno pri sozdanii ka- nala naznachit' emu indeks. Ono takzhe naznachaet dlya kanala paru pol'zovatel'- skih deskriptorov i sootvetstvuyushchie im zapisi v tablice fajlov: odin iz des- kriptorov dlya chteniya iz kanala, a drugoj dlya zapisi v kanal. Poskol'ku yadro pol'zuetsya tablicej fajlov, interfejs dlya vyzova funkcij read, write i dr. soglasuetsya s interfejsom dlya obychnyh fajlov. V rezul'tate processam net na- dobnosti znat', vedut li oni chtenie ili zapis' v obychnyj fajl ili v kanal. +------------------------------------------------------------+ | algoritm pipe | | vhodnaya informaciya: otsutstvuet | | vyhodnaya informaciya: deskriptor fajla dlya chteniya | | deskriptor fajla dlya zapisi | | { | | naznachit' novyj indeks iz ustrojstva kanala (algoritm | | ialloc); | | vydelit' odnu zapis' v tablice fajlov dlya chteniya, odnu -| | dlya perepisi; | | inicializirovat' zapisi v tablice fajlov takim obrazom, | | chtoby oni ukazyvali na novyj indeks; | | vydelit' odin pol'zovatel'skij deskriptor fajla dlya chte-| | niya, odin - dlya zapisi, proinicializirovat' ih takim | | obrazom, chtoby oni ukazyvali na sootvetstvuyushchie tochki | | vhoda v tablice fajlov; | | ustanovit' znachenie schetchika ssylok v indekse ravnym 2; | | ustanovit' znachenie schetchika chisla processov, proizvodya-| | shchih chtenie, i processov, proizvodyashchih zapis', ravnym 1;| | } | +------------------------------------------------------------+ Risunok 5.16. Algoritm sozdaniya kanalov (nepoimenovannyh) Na Risunke 5.16 pokazan algoritm sozdaniya nepoimenovannyh kanalov. YAdro naznachaet indeks dlya kanala iz fajlovoj sistemy, oboznachennoj kak "ustrojst- vo kanala", ispol'zuya algoritm ialloc. Ustrojstvo kanala - eto imenno ta fajlovaya sistema, iz kotoroj yadro mozhet naznachat' kanalam indeksy i vydelyat' bloki dlya dannyh. Administratory sistemy ukazyvayut ustrojstvo kanala pri konfigurirovanii sistemy i eti ustrojstva mogut sovpadat' u raznyh fajlovyh sistem. Poka kanal aktiven, yadro ne mozhet perenaznachit' indeks kanala i in- formacionnye bloki kanala drugomu fajlu. Zatem yadro vydelyaet v tablice fajlov dve zapisi, sootvetstvuyushchie desk- riptoram dlya chteniya i zapisi v kanal, i korrektiruet "buhgalterskuyu" infor- maciyu v kopii indeksa v pamyati. V kazhdoj iz vydelennyh zapisej v tablice fajlov hranitsya informaciya o tom, skol'ko ekzemplyarov kanala otkryto dlya chteniya ili zapisi (pervonachal'no 1), a schetchik ssylok v indekse ukazyvaet, skol'ko raz kanal byl "otkryt" (pervonachal'no 2 - po odnomu dlya kazhdoj zapi- si tablicy fajlov). Nakonec, v indekse zapisyvayutsya smeshcheniya v bajtah vnutri kanala do mesta, gde budet nachinat'sya sleduyushchaya operaciya zapisi ili chteniya. Blagodarya sohraneniyu etih smeshchenij v indekse imeetsya vozmozhnost' proizvodit' dostup k dannym v kanale v poryadke ih postupleniya v kanal ("pervym prishel - pervym vyshel"); etot moment yavlyaetsya osobennost'yu kanalov, poskol'ku dlya obychnyh fajlov smeshcheniya hranyatsya v tablice fajlov. Processy ne mogut menyat' eti smeshcheniya s pomoshch'yu sistemnoj funkcii lseek i poetomu proizvol'nyj dostup k dannym kanala nevozmozhen. 105 5.12.2 Otkrytie poimenovannogo kanala Poimenovannyj kanal - eto fajl, imeyushchij pochti takuyu zhe semantiku, kak i nepoimenovannyj kanal, za isklyucheniem togo, chto etomu fajlu sootvetstvuet zapis' v kataloge i obrashchenie k nemu proizvoditsya po imeni. Processy otkry- vayut poimenovannye kanaly tak zhe, kak i obychnye fajly, i, sledovatel'no, s pomoshch'yu poimenovannyh kanalov mogut vzaimodejstvovat' mezhdu soboj dazhe pro- cessy, ne imeyushchie drug k drugu blizkogo otnosheniya. Poimenovannye kanaly pos- toyanno prisutstvuyut v ierarhii fajlovoj sistemy (iz kotoroj oni udalyayutsya s pomoshch'yu sistemnoj funkcii unlink), a nepoimenovannye kanaly yavlyayutsya vremen- nymi: kogda vse processy zakanchivayut rabotu s kanalom, yadro otbiraet nazad ego indeks. Algoritm otkrytiya poimenovannogo kanala identichen algoritmu otkrytiya obychnogo fajla. Odnako, pered vyhodom iz funkcii yadro uvelichivaet znacheniya teh schetchikov v indekse, kotorye pokazyvayut kolichestvo processov, otkryvshih poimenovannyj kanal dlya chteniya ili zapisi. Process, otkryvayushchij poimenovan- nyj kanal dlya chteniya, priostanovit svoe vypolnenie do teh por, poka drugoj process ne otkroet poimenovannyj kanal dlya zapisi, i naoborot. Ne imeet smysla otkryvat' kanal dlya chteniya, esli process ne nadeetsya poluchit' dannye; to zhe samoe kasaetsya zapisi. V zavisimosti ot togo, otkryvaet li process po- imenovannyj kanal dlya zapisi ili dlya chteniya, yadro vozobnovlyaet vypolnenie teh processov, kotorye byli priostanovleny v ozhidanii processa, zapisyvayushche- go v poimenovannyj kanal ili schityvayushchego dannye iz kanala (sootvetstvenno). Esli process otkryvaet poimenovannyj kanal dlya chteniya, prichem process, zapisyvayushchij v kanal, sushchestvuet, otkrytie zavershaetsya. Ili esli process ot- kryvaet poimenovannyj fajl s parametrom "no delay", funkciya open vozvrashchaet upravlenie nemedlenno, dazhe kogda net ni odnogo zapisyvayushchego processa. Vo vseh ostal'nyh sluchayah process priostanavlivaetsya do teh por, poka zapisyva- yushchij process ne otkroet kanal. Analogichnye pravila dejstvuyut dlya processa, otkryvayushchego kanal dlya zapisi. 5.12.3 CHtenie iz kanalov i zapis' v kanaly Kanal sleduet rassmatrivat' pod takim uglom zreniya, chto processy vedut zapis' na odnom konce kanala, a schityvayut dannye na drugom konce. Kak uzhe govorilos' vyshe, processy obrashchayutsya k dannym v kanale v poryadke ih postup- leniya v kanal; eto oznachaet, chto ocherednost', v kotoroj dannye zapisyvayutsya v kanal, sovpadaet s ocherednost'yu ih vyborki iz kanala. Sovpadenie kolichest- va processov, schityvayushchih dannye iz kanala, s kolichestvom processov, vedushchih zapis' v kanal, sovsem ne obyazatel'no; esli odno chislo otlichaetsya ot drugogo bolee, chem na 1, processy dolzhny koordinirovat' svoi dejstviya po ispol'zova- niyu kanala s pomoshch'yu drugih mehanizmov. YAdro obrashchaetsya k dannym v kanale tochno tak zhe, kak i k dannym v obychnom fajle: ono sohranyaet dannye na ust- rojstve kanala i naznachaet kanalu stol'ko blokov, skol'ko nuzhno, vo vremya vypolneniya funkcii write. Razlichie v vydelenii pamyati dlya kanala i dlya +--------------------+--------------------+ | Ukazatel' chteniya | Ukazatel' zapisi | +----------+---------+----------+---------+ | +----------------+ +-- | --------------+ v v +---+---+---+---+---+---+---+---+---+---+ | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | +---+---+---+---+---+---+---+---+---+---+ Bloki pryamoj adresacii v indekse Risunok 5.17. Logicheskaya shema chteniya i zapisi v kanal 106 obychnogo fajla sostoit v tom, chto kanal ispol'zuet v indekse tol'ko bloki pryamoj adresacii v celyah povysheniya effektivnosti raboty, hotya eto i naklady- vaet opredelennye ogranicheniya na ob®em dannyh, odnovremenno pomeshchayushchihsya v kanale. YAdro rabotaet s blokami pryamoj adresacii indeksa kak s ciklicheskoj ochered'yu, podderzhivaya v svoej strukture ukazateli chteniya i zapisi dlya obes- pecheniya ocherednosti obsluzhivaniya "pervym prishel - pervym vyshel" (Risunok 5.17). Rassmotrim chetyre primera vvoda-vyvoda v kanal: zapis' v kanal, v koto- rom est' mesto dlya zapisi dannyh; chtenie iz kanala, v kotorom dostatochno dannyh dlya udovletvoreniya zaprosa na chtenie; chtenie iz kanala, v kotorom dannyh nedostatochno; i zapis' v kanal, gde net mesta dlya zapisi. Rassmotrim pervyj sluchaj, v kotorom process vedet zapis' v kanal, imeyu- shchij mesto dlya vvoda dannyh: summa kolichestva zapisyvaemyh bajt s chislom bajt, uzhe nahodyashchihsya v kanale, men'she ili ravna emkosti kanala. YAdro sledu- et algoritmu zapisi dannyh v obychnyj fajl, za isklyucheniem togo, chto ono uve- lichivaet razmer kanala avtomaticheski posle kazhdogo vypolneniya funkcii write, poskol'ku po opredeleniyu ob®em dannyh v kanale rastet s kazhdoj operaciej za- pisi. Inache proishodit uvelichenie razmera obychnogo fajla: process uvelichiva- et razmer fajla tol'ko togda, kogda on pri zapisi dannyh perestupaet granicu konca fajla. Esli sleduyushchee smeshchenie v kanale trebuet ispol'zovaniya bloka kosvennoj adresacii, yadro ustanavlivaet znachenie smeshcheniya v prostranstve processa takim obrazom, chtoby ono ukazyvalo na nachalo kanala (smeshchenie v bajtah, ravnoe 0). YAdro nikogda ne zatiraet dannye v kanale; ono mozhet sbro- sit' znachenie smeshcheniya v 0, poskol'ku ono uzhe ustanovilo, chto dannye ne bu- dut perepolnyat' emkost' kanala. Kogda process zapishet v kanal vse svoi dan- nye, yadro otkorrektiruet znachenie ukazatelya zapisi (v indekse) kanala takim obrazom, chto sleduyushchij process prodolzhit zapis' v kanal s togo mesta, gde ostanovilas' predydushchaya operaciya write. Zatem yadro vozobnovit vypolnenie vseh drugih processov, priostanovlennyh v ozhidanii schityvaniya dannyh iz ka- nala. Kogda process zapuskaet funkciyu chteniya iz kanala, on proveryaet, pustoj li kanal ili net. Esli v kanale est' dannye, yadro schityvaet ih iz kanala tak, kak esli by kanal byl obychnym fajlom, vypolnyaya sootvetstvuyushchij algo- ritm. Odnako, nachal'nym smeshcheniem budet znachenie ukazatelya chteniya, hranyashche- gosya v indekse i pokazyvayushchego protyazhennost' prochitannyh ranee dannyh. Posl