Obligatorisk oppgave 3 - 2001
IN147
Frist
Innleveringsfrist: 4. mai 2001
Løsning på denne oppgaven kreves bare av de som tar hele IN147 og ikke bare IN147A.
Oppgaven
Oppgaven går ut på å programmere `ifish' som skal være en
kommandotolker à la `sh', `csh' eller `bash' men selvfølgelig en god
del enklere.
Besvarelsen skal bestå av den godt kommenterte kildekoden til
programmet. Dessuten skal det stå en referanse til hvor det finnes en
fil med en kjørbar utgave av `ifish' slik at gruppelæreren kan teste
programmet.
Hvis kildekoden ikke er godt kommentert, vil besvarelsen ikke bli
godkjent. Den vil neppe bli rettet engang!
Oppgaven er beregnet på å løses av enkeltpersoner, men den kan også
løses av grupper på to.
ifish
`ifish' skal gå i løkke og gjøre følgende:
- Skrive ut klarsignalet (teksten "ifish> ").
- Lese en kommandolinje fra standard-inn. Hvis det ikke er flere
linjer å lese, skal `ifish' avslutte med statusverdi 0.
NB! Dette er ikke det samme som å lese en tom linje! Når man leser
fra tastaturet, kan brukeren trykke på Ctrl+D («End of file») for å
angi at det ikke er flere linjer å lese.
- Sjekke om linjen avsluttes med en '&' (eventuelt etterfulgt av
blanke).
Hint: Bruk `strchr' siden '&' bare kan forekomme sist på linjen.
- Splitt linjen i kommandonavn og parametre; blanke tegn angir
skillet.
Hvis det ikke er noen kommando eller parametre (dvs linjen er blank),
så gå til punkt 1 igjen.
- Hvis kommandonavnet er "exit", skal `ifish' avslutte.
- `ifish' skal kunne behandle aliaser. Kommandoen "alias" vil lage et
alias for kommandoen som oppgis til alias: "alias la='ls -lag'" vil
lage et alias for kommandoen "ls -lag" som får navn "la". Når "la"
kalles er det "ls -lag" som blir kjørt. Kommandoen "alias" uten
parametre skal skrive ut alle de registrerte aliasene.
Aliaser tas vare på gjennom hele instansen av kommandotolkeren, typisk
i en vektor. Om et alias og et program har samme navn er det aliaset
som skal kjøres. Aliasene må altså gjennomsøkes før
omgivelsesvariabelen `PATH'. Brukeren skal også kunne ha aliaser
lagret i en fil, "ifish_aliaser", som - om den finnes - skal leses ved
oppstart av `ifish'.
Alle de vanlige kommandotolkerene støtter dette, test det i ditt eget
shell. Syntaksen i bash er som vist over ("alias søk='grep'"), mens
den i tcsh er "alias søk 'grep'".
- Start en barneprosess med `safefork'. Denne barneprosessen skal
prøve å utføre angitte kommando med et kall på `execve'. Den skal lete
blant aliasene og deretter filområdene angitt i omgivelsesvariabelen
`PATH' etter hvor kommandoen kan finnes som eksekverbar fil.
Hint: Den enkleste måten å sjekke om det finnes en eksekverbar fil på
et aktuelt område, er å prøve om `execve' fungerer; hvis den ikke gjør
det, er det bare å prøve neste område.
Hvis intet program `xxyz' finnes på områdene angitt i `PATH', skrives
det ut en feilmelding:
ifish: xxyz: command not found
før barneprosessen avsluttes.
- Foreldreprosessen venter til barneprosessen er ferdig, unntatt hvis
kommandolinjen slutter med en '&' (se punkt 3). I så fall skal
foreldreprosessen skrive ut barneprosessens PID og gå videre.
- Gå til punkt 1 igjen.
Hint
- Legg inn mange testutskrifter underveis for å få oversikt over
hva som skjer. Sjekk spesielt om alle tekstoperasjonene fungerer. Ved
å ramme testutskriftene inn i
#ifdef DEBUG
printf(...);
#endif
kan du lett slå testutskriftene på og av etter behov.
- Vær spesielt oppmerksom når du programmerer allokering
(`malloc') og frigjøring (`free') av tekster.
- På grunn av faren for at genereringen av barneprosesser skal
løpe løpsk, må dere benytte `safefork' i stedet for `fork'. Koden til
`safefork' finnes på filen ~in147/Kode/safefork.c.
Lykke til!
Kristin, 3/4-2001