Minishell –
Felhasználói útmutató
|
A program elindítása után egy
prompt (>) jelenik meg és a felhasználótól várja a shell-parancsokat. Az ENTER gomb lenyomása után végrehajtja a
kapott parancsot, illetve amennyiben nem tudja végrehajtani, hibaüzenetet ad.
A parancs végrehajtása után újra megjelenik a prompt, ami jelezi, hogy készen
áll az újabb shell-parancs végrehajtására. A program az alábbi feladatok
ellátására alkalmas:
A programból való kilépés az exit parancs beolvasásával történik. |
Fejlesztői
dokumentáció
|
A program a főprogramon kívül néhány eljárást használ, amelyekben
külön végzem el az előbbiekben felsorolt különböző műveleteket
(átirányítás, környezeti változó módosítás, stb.). Elsősorban csatolom a
későbbiekben használandó könyvtári header állományokat, majd a
főprogram által használt eljárások leírása következik és végül a
főprogram. A főprogram változóinak deklarálása,
inicializálása után kiíratom a promptot a képernyőre. A működéshez
szükség van az alábbi változókra: ·
egy s nevű változó,
amelyben a felhasználó által beolvasott parancsot tárolom; ·
egy pid_t típusú pid nevű változó, amely a
program pidszámát tartalmazza; ·
valamint egy merre nevű int típusú változó, amelyben
tárolom azt, hogy melyik irányba lépjek tovább. Ez utóbbira azért van szükség, mert bizonyos
shell-parancsokat nem szabad kombinálni pl. nem végezhetek el olyant, hogy echo xxx > fájlnév
vagy printenv PATH > fájlnev. A prompt megjelenítése után várom a felhasználótól érkező
parancsot, amit az s változóba fogok tárolni. Miután megkaptam, ellenőrzöm, hogy
megegyezik-e az exit-tel, mert ha igen, akkor csak annyi a tennivalóm, hogy kilépek a
programból. Amennyiben nem, akkor kezdődnek a komplikációk, mivel
először ellenőriznem kell, hogy milyen parancsot adott ki a
felhasználó - a fenti visszásságok elkerülése érdekében -, ugyanis például
egy echo
vagy környezeti változó lekérdezés, módosítás vagy könyvtárváltás után nem
engedhetek meg pl. átirányítást. Azt,
hogy milyen parancsot kapott a shell és mi az, amit tennem kell, a tovabbmehet()
nevű eljárásban döntöm el és a visszaadott paraméter függvényében lépek
tovább. Ha a visszaadott paraméter értéke nem nulla akkor a következő
promptot iratom ki, ha 0 és nincs forkhiba, valamint a pid is 0 akkor végrehajtom a
beolvasott shell-parancsot. A végrehajtás az execlp használatával történik,
amely paraméter nélküli parancsokat hajt végre. Ha ez nem sikerült akkor
meghívom a szetszed() eljárást, amely a parancsot lebontja szavakra és úgy próbálja
végrehajtani. Persze ez sem biztos, hogy sikerül, ilyen esetben jelzi a
felhasználónak a parancsvégrehajtás sikertelenségét, majd újra a prompt
jelenik meg. A tovabbmehet() eljárás a beolvasott parancsot kapja paraméterként. A helyi változók
deklarálása után a visszatérő érték inicializálása következik, majd a
kapott parancs lebontása. A visszatérő értéket 0-val teszem
egyenlővé, amivel azt feltételezem, hogy a kapott parancs nem echo, nem könyvtárváltás és nem
környezeti változóval kapcsolatos művelet. Amennyiben tévedtem akkor a
következő lépésekben módosítom az értékét. A kapott parancsot kétfelé
bontom, az elsőbe teszem az első SPACE-szig tartozó részt. Ha ez echo, chdir, setenv vagy printenv, akkor a másodikba
jön a parancs többi része és a visszatérési érték az otodik() nevű eljárás által visszaadott
érték lesz. A végén persze visszaadom az allj nevű változóban
tárolt visszatérési értéket. Az otodik() nevű eljárás két paramétert kap, a tovabbmehet()-ben két részre
lebontott parancsot. Visszatérési értéke 1 lesz. Az eljárás feladata végrehajtani
az echo-t,
a környezeti változókkal kapcsolatos műveleteket valamint a
könyvtárváltásokat. Ha a kapott első paraméter echo, akkor egyszerűen
megjeleníti a képernyőn a kapott második paramétert. Ha a második
paraméter " " jelben van akkor ezt leszűri belőle. A
környezeti változókkal kapcsolatos műveleteket a putenv valamint getenv használatával végzi
el, vagy ellenkező esetben figyelmeztető- és hibaüzenetekkel
igyekszik a felhasználó segítségére.
A könyvtárváltás a chdir használatával került kivitelezésre. A szetszed() eljárás ugyancsak egy paramétert kap, a beolvasott parancsot. Végigmegy
a parancson és annak függvényében, hogy talált-e benne átirányítási jelt vagy
sem, és ha igen, akkor milyent, a van nevű változónak különböző értékeket ad. A van változó értékének
függvényében különböző eljárások kerülnek meghívásra: átirányítási jel
hiányában a masodik(), átirányítási jel létezése esetén az ellenoriz(). Az ellenoriz() eljárás három paramétert kap: a parancssort, azt a pozíciót ahol
valamilyen átirányítási jel található, valamint az előbbiekben említett van változó értékét, ami
tulajdonképpen azt jelzi, hogy milyen átirányítási jelről van szó (< vagy > lehet). Az eljárásban
attól a pozíciótól, ahol az átirányítási jel található, végigmegyek a parancssoron
a végjelig vagy amíg a parancssor végére érek. Végjelet kaphatok abban az
esetben, ha téves a parancssor, vagyis az átirányítási jel után nemcsak egy
fájlnév következik. Természetesen ilyen esetben hibaüzenettel tér vissza a
program. Ha helyes a parancssor akkor az átirányítási jel után következő
fájlnevet kimentem egy változóba, az átirányítási jel előtti részt egy
másik változóba és az átirányítási jel függvényében meghívom a harmadik(), illetve a negyedik() nevű
eljárásokat, melyeknek ezt a két változót adom át paraméterként. A harmadik() illetve a negyedik() eljárások célja ugyanaz, elvégezni a megfelelő átirányítást.
Mindkettőben megpróbálom megnyitni a fájlt a megfelelő módra (írás,
olvasás), majd dup2-vel
elvégzem az átirányítást és meghívom a masodik() nevű eljárást. Sikertelen fájlmegnyitás,
fájllétrehozás esetén hibaüzenetet küldök a felhasználó számára. A masodik() nevű eljárás szintén a beolvasott parancssort
kapja meg paraméterként.
Tulajdonképpen annyit csinál, hogy a kapott parancssort szavakra
bontja és végrehajtja az execvp paranccsal. A szavakra bontás
úgy történik, hogy végigmegy a parancssoron és egy vektorba menti ki a
szavakat, pontosabban az üres karakterig tartó karaktersorozatokat. Szükség
van a malloc-ra, ahhoz hogy a szavakat tudjam megjegyezni. E
parancs hiányában mindig csak az elsőt adja vissza. A szavakra bontás
szükséges az execvp parancs helyes használatához. |
Finta
Annamária |