Linux操作系统实验.docx
Project1SystemsProgrammingPractice:TheYalnixShellEducationalObjectives:Studentscometothiscoursewithvariousexperiences.Formanypeoplethisprojectwillbepracticeand/orawarmup.Forothers,itW川bealearningexercise.Regardlessofyourbackground,bytheendofthisproject,wehopethatyouwillcomfortablyandconfidentlybeabletodothefollowing: Developclear,readable,well-documentedandwell-designedprogramsintheCProgrammingLanguage. DevelopsoftwareintheUnix/Linuxusingtoolssuchasgcc,gdb,andmake. 1.ocateandinterpreting,manpages"applicabletoapplication-levelsystemprogramming. UsethePOSIX/UnixAPItosystemfunctionstomanageprocessandsessionsaswellasusesignalsandpipesforinter-processcommunication. Understandinghowsynchronizationmightbecomeproblematicinlightofconcurrency. Understandhowtocommunicateandcooperatewithaprojectpartner.ProjectOverviewInthisprojectyouareaskedtoimplementasimplecommand-interpreter,a.k,a."shell,"forLinux.Theshellthatyouwillimplement,knownasysh,shouldbesimilartopopularshellssuchasbash,csh1tcsh1zsh,&c,butitisnotrequiredtoimplementasmanyfeaturesasthesecommercial-gradeproducts.Althoughwedon'trequireallofthe*,bellsandwhistles"thatareincorporatedintocommercial-gradeproducts,yshshouldhavemuchoftheimportantfunctionality: Allowtheusertoexecuteoneormoreprograms,fromexecutablefilesonthefile-system,asbackgroundorforegroundjobs. Providejob-control,includingajoblistandtoolsforchangingtheforeground/backgroundstatusofcurrentlyrunningjobsandjobsuspension/continuation/termination. Allowforthepipingofseveraltasksaswellasinputandoutputredirection.Withrespecttotheotherprogrammingassignmentsthissemester,andmanyothersinyourexperience,thisislikelytobeasmallproject,butwewantyoutoapproachitasifitisabiggerandmorecomplexprojectsothatyouarepreparedfortheremainingprojects.Specifically,we,dlikeyoutodothefollowing: Usethemakeutilitytobuildyourproject Useadebuggerinsteadofprint-ad-huntdebuggingwheneverpractical. Produceclean,well-documented,andwell-designedsolutions.SpecificationFormYoursolutionshouldbeanapplicationprograminvokedwithoutcommand-lineparametersorconfigurationfiles,&c.Ifyouwanttobefancyandsupportforaresourcefilesimilartothoseusedwithcommercial-gradeshells,e.g.cshrc,you,reawelcometodothis.But,likecsh,yourshellshouldfunctioncorrectlyinabsenceofthisfile.1.ook-and-FeelThelookandfeelofyshshouldbeSimilartothatofotherUNIXshells,suchasbash,tcsh,csh,&c.Forexample,yourshell'sworkloopshouldproduceaprompt,e.g.,ysh>,acceptinputfromtheuser,andthenproduceanotherprompt.Messagesshouldbewrittentothescreenasnecessary,andthepromptshouldbedelayedwhenuserinputshouldn,tbeaccepted,asnecessary.Needlesstosay,yourshellshouldtakeappropriateactioninresponsetotheuser'Sinput.InternalCommandsvs.ExternalProgramsInmostcases,theuser*sinputwillbeacommandtoexecuteprogramsstoredwithinafilesystem.We,Ilcalltheseexternalprograms.Yourshellshouldallowtheseprogramstoexecutewithstdinand/orstdoutreassignedtoafile.ItshouldallowprogramsI/Otobechainedtogetherusingpipes.Forourpurposes,acollectionofpipedprocessesorasingleprocessexecutedbyitselffromthecommandlineiscalledajob.Whenexecutingbackgroundsjobs,theshellshouldnotwaitforthejobtofinishbeforeprompting,reading,andprocessingthenextcommand.Whenabackgroundjobfinallyterminatesamessagetothateffectmustbeprinted,bytheshell,totheterminal.Thismessageshouldbeprintedassoonasthejobterminates.Thesyntaxfordoingthiswillbedescribedinthesectionofthisdocumentdescribingtheshell'Sparser.Yourparsershouldalsosupportseveralinterna!commandsthesecommands,ifissuedbytheuser,shoulddirecttheshelltotakeaparticularactionitselfinsteadofdirectingittoexecuteotherprograms.Thedetailsofthisarediscussedinthesectiondescribinginternalcommands.Foregroundvs.BackgroundJobsYourshellshouldbecapableofexecutingbothforegroundandbackgroundjobs.Whereasyourshellshouldwaitforforegroundjobstocompletebeforecontinuing,itshouldimmediatelycontinue,prompttheuser,&c,afterplacingajobintothebackground.CommandlinesWhentheuserrespondstoaprompt,whattheytypecomposesacommandHnestring.Yourshellshouldstoreeachcommand-linestring,untilthejobisfinishedexecuting.Thisincludesbothbackgroundandsuspendedjobs.Theshellshouldassigneachcommand-linestringanon-negativeintegeridentifier.Thedatastructureusedtostorethejobsshouldallowaccesstoeachelementusingthisidentifier.Oncetheactionsdirectedbyacommand-linestringarecompleted,yourshellshouldremoveitfromthedatastructure.Identifierscanberecycledifyouchoose.Pleasenotethatthisdatastructureshouldkeeptrackofwholecommandlinestrings,notjustthenamesoftheindividualtasksthatmaycomposethem.Youshouldnotkeeptrackofcommandlinestringsthatcontaininternalcommands,since,bytheirnature,theywillcompletebeforethisinformationcouldbecomeuseful.InternalCommandsThefollowingaretheinternalcommands.Ifaninternalcommandissubmittedbytheuser,theshellshouldtakethedescribedactionsitself.exit:Killallchildprocessesandexityshwithameaningfulreturncode.jobs:Printoutthecommandlinestringsforjobsthatarecurrentlyexecutinginthebackgroundandjobsthatarecurrentlysuspended,aswellastheidentifierassociatedwitheachcommandlinestring.Youmayformattheoutputofthiscommandinwaythatisconvenienttotheuser.Pleaserememberthatjobsitselfisaninternalcommandandconsequentlyshouldnotappearintheoutput. echo$status:Printstheexitstatusofthemostrecentforegroundchildprocesstohaveexited.Return0ifnosuchchildhasexisted. fg%<int>:Bringsthejobidentifiedby<it>intotheforeground.Ifthisjobwaspreviouslystopped,itshouldnowberunning.Yourshellshouldwaitforaforegoundchildtoterminatebeforereturningacommandpromptortakinganyotheraction. bg%<int>:Executethesuspendedjobidentifiedby<int>inthebackground. InternalcommandscantakeadvantageofpipedI/O,executeinthebackground,&c,asappropriate.SpecialKeystrokesThroughaninteractionwiththeterminaldriver,certaincombinationsofkeystrokeswillgeneratesignalstoyourshellinsteadofappearingwithinstdin.Yourshellshouldrespondappropriatelytothesesignals. Control-ZgeneratesaSIGSTOP.Thisshouldnotcauseyourshelltobesuspended.Instead,itshouldcauseyourshelltosuspendtheprocessesinthecurrentforegroundjob.Ifthereisnoforegroundjob,itshouldhavenoeffect. Control-CgeneratesaSIGINT.Thisshouldnotkillyourshell.Insteaditshouldcauseyourshelltokilltheprocessesinthecurrentforegroundjob.Ifthereisnoforegroundjob,itshouldhavenoeffect.ParsingUserInput-Overview,DelimitersandSpecialCharactersYourparserforuserinputshouldbecapableofacceptinginputfromtheuserasdescribedinthissection.Itshouldalsodetectimproperinputfromtheuser.Iftheuserenterssomethingimproper,yourshellshouldproduceameaningfulerrormessage.Justlikecommercial-gradeshells,yourshellshouldacceptinputfromtheuseronelineatatime.Youshouldbeginparsingtheusersinputwhenhe/shehitsenter.Emptycommandlinesshouldbetreatedasno-opsandyieldanewprompt.Blank-spacecharactersshouldbetreatedasdelimiters,butyourshellshouldbeinsensitivetorepeatedblankspaces.Itshouldalsobeinsensitivetoblankspacesatthebeginningorendofthecommandline.Certaincharacters,knownasmeta-characters,havespecialmeaningswithinthecontextofuserinput.Thesecharactersinclude&,<,and>,Yourshellcanassumethatthesemeta-characterscannotoccurinsidestringsrepresentingprograms,arguments,orfiles.Insteadtheyarereservedforusebytheshell.Thepurposeofmeta-charactersisdiscussedlaterinthissection.ParsingUserInput-InternalCommandsIfthecommandlinematchestheformatofaninternalcommandasdescribedearlierinthisdocument,itshouldbeacceptedasaninternalcommand.Ifnot,itshouldbeconsideredtospecifytheexecutionofexternalprograms,oranerror,asappropriate.ParsingUserInput-ExecutingASingleProgramTheexecutionofaprogramisspecifiedbyasequenceofdelimitedstrings.Thefirstoftheseisthenameoftheexecutablefilethatcontainsthedesiredprogram(moduloasearchpathasexplainedintheeecvpmanpage,seeman-s2execvp)andtheothersareargumentspassedtotheprogram.Thecommandisanerroriftheexecutablefilenamedbythefirststringdoesnotexist,orisnotanexecutable.ParingUserInput-I/ORedirectionAprogram'sexecutionspecifiedasabovemaybefollowedbythemeta-character<or>whichisinturnfollowedbyafilename.Inthecaseof<1theinputoftheprogramwillberedirectedfromthespecifiedfilename.Inthecaseof>,theoutputoftheprogramwillberedirectedtothespecifiedfilename.Iftheoutputfiledoesnotexist,itshouldbecreated.Iftheinputfiledoesnotexist,thisisanerror.ParsingUserInput-PipesandCooperatingProgramsSeveralprograminvocationscanbepresentinasinglecommandline,whenseparatedbytheshellmetacharacter'T'.Inthiscase,theshellshouldforkallofthem,chainingtheiroutputsandinputsusingpipesappropriately.Forinstance,thecommandlineprogAargAlargA2<infileprogBargBl>outfileshouldforkprogAandprogB,maketheinputforprogAcomefromfileinfile,theoutputfromprogAgototheinputofprogB,andtheoutputofprogBgotothefileoutfile.ThisshouldbeaccomplishedusingapipeIPCprimative.Acommandlinewithoneormore''pipes"isanerrorifanyofitscomponentprograminvocationsisanerror.Acommandlinewith''pipes"isanerroriftheinputofanybutthefirstcommandisredirected,oriftheoutputofanybutthelastcommandisredirected.Ajobconsistingofpipedprocessesisnotconsideredtohavecompleteduntilallofitscomponentprocesseshavecompleted.ParsingUserInput-BackgroundJobsTheusercanspecifythatajobshouldbeexecutedinthebackgroundbyendingthecommandlinewiththemeta-character&.Ifthisisthecase,allprograminvocationsrequiredbythecommandlinearetobecarriedoutinthebackground.ParsingUserInput-AGrammarThegrammarbelowprovidesamoreformaldescriptionofthesyntaxgoverninguserinput.Ifyouareusinglex/yacctoimplementyourparser,you*IlhavetomassagethegrammarslightlytomakeitLALR(I).Thisgrammardoesn,tincludethespecialkeystrokes,becausetheywon'tshowupinstdinasuserinputandshouldbehandledseparately.ACommandLineislegalinputprovidedbytheuser,asadirectiontotheshell,inresponsetotheprompt.Thegrammarassumesthattheexistenceofalexicalanalyzerthatconsidersblank-spacetobeadelimiter,recognizesthemeta-charactersastokens,&c.CommandLine= NULLFgCommandLineFgCommandLine &FgCommandLine:= SimpIeCommandFirstCommand MidCommand LastCommandSimpIeCommand:= Proglnvocation InputRedirect OutputRedirectFirstCommand=Proglnvocation InputRedirectMidCommand := NULL I Proglnvocation MidCommandLastCommand= I Proglnvocation OutputRedirectProglnvocation :=ExecFiIe ArgsInputRedirect :=NULL< STRINGOutputRedirect :=NULL> STRINGExecFiIe :=STRINGA SuggestedPlan Of Attack1) Readthemanpagesforfork,exec,waitandexit.2) Writeafewsmallprogramstoexperimentwiththesecommands.3) Readthemanpagesfortcsetgrp()andsetpgid()4) Writesomecodetoexperimentwithprocessgroups,&c.PayattentiontoSIGTTIN&S1GTTOU.5) Designyourparser.6) Implementyourparser.7) Usingyourparser,writeasimpleshellthatcanexecutesinglecommands.8) Addsupportforrunningprogramsinthebackground,butdon'tworryaboutprintingthemessagewhenabackgroundjobterminates(asynchronousnotification).Addthejobscommandwhileyouaredoingthis-itmayprovehelpfulfordebugging.9) Addinputandoutputredirection10) Addcodetoprintamessagewhenabackgroundjobterminates.11) Addjobcontrolfeatures-implementthebehaviorofControl-Z(and,ifapplicable,CONTROL-C)tfgandbg.12) Addsupportforpipes.13) Finishupallofthedetails14) Test,testtest.15) CelebrateEnvironmentWhereasyoucandothisassignmentonanyUNIX,itmustrunontheLinuxmachinesforyourdemo.Weencourageyoutoworkinthatenvironment,becausethelibrariesforfutureprojectsareonlyavailableintheAndrewenvironment.Althoughyoucansolvethisassignmentinyourchoiceoflanguages,itwouldprobablybemoredifficultinanythingotherthanC(orperhapsC+).WestronglyencourageyoutouseC.Forfutureprojectsyou'llalmostcertainlyhavetouseC.C+maywork,butweoffernoguarantees.Thereisadifferenceinthelinkingconventionbetweenthetwolanguagesthatcausesincompatibilities.We'vetriedtocorrectthis,butwemakenopromisesaboutC+.SomeUsefulInformation(Someofwhichisareview)SystemCallsYouhaveprobablyalreadyheardtheterm"SystemCall,"Doyouknowwhatitmeans?Asitsnameimplies,asystemcallisa',cal*,thatis,atransferofcontrolfromoneinstructiontoadistantinstruction.Asystemcallisdifferentfromaregularprocedurecallinthatthecalleeisexecutedinaprivilegedstate,i.e,thatthecalleeiswithintheoperatingsystem.Because,forsecurityandsanity,callsintotheoperatingsystemmustbecarefullycontrolled,thereisawell-definedandlimitedsetofsystemcalls.Thisrestrictionisenforcedbythehardwarethroughtrapvectors:onlythoseOSaddressesentered,atboottime,intothetrap(interrupt)vectorarevaliddestinationsofasystemcall.Thus,asystemcallisacallthattrespassesaprotectionboundaryinacontrolledmanner.SincetheprocessabstractionismaintainedbytheOS,yshwillneedtomakecallsintotheOSinordertocontrolitschildprocesses.Thesecallsaresystemcalls.InUNIX,youcandistinguishsystemcallsfromuser-levellibrary(programmer'sAPI)callsbecausesystemcallsappearinsection2ofthe''manual",whereasuser-levelcallsappearinsection3ofthe''manual".The''manual"is,inUNIX,whatyougetwhenyouusethe''man"command.Forexample,manforkwillgetyouthe''manpage"insection2ofthemanualthatdescribesthefork()syscall1andman-s2execwillgetyouthe''manpage"thatdescribesthefamilyof''exec"syscalls(asyscall,hence-s2.)ThefollowingUNIXsyscallsmayprovetobeespeciallyusefulinyoursolutiontothisproject.Thereareplentyofothers,soyoumayfind*,ma"andgoodreferencebooksuseful,especiallyifyouarenewtosystemprogramming. pid_tfork(void):ItcreatesaprocessthatisanaImost-exactcopyofthecallingprocess;inparticular,afterasuccessfulreturnfromfork(),bothparentandchildprocessesareexecutingthesameprogram.Thetwoprocessescanbedistinguishedbythereturnvaluefromfork(). intexecvp(constchar*file,char*constargv):Loadstheexecutablefilepath,orafilefoundthroughasearchpath,intothememoryassociatedwiththecallingprocess,andstartsexecutingtheprogramtherein.Ifsuccessful,itobliterateswhateverprogramiscurrentlyrunninginthecallingprocess.Thereareseveralother,similarformsofexec. voidexit(intstatus):Exitsthecallingprogram,destroyingthecallingprocess.Itreturnsstatusastheexitvaluetotheparent,shouldtheparentbeinterested.Theparentreceivesthisexitvaluethroughthewaitsyscall,below.Notethatthelinkerintroducesanexit()callattheendofeveryprogram,forinstance,attheendofacmainprocedure,eveniftheccodedoesn'texplicitlyhaveone. pid_twait(int*stat_loc):Returnstheexitstatusofanexitedchild,ifany.Returnserroriftherearenochildrenrunning.Blocksthecallingprocessuntilachildexitsiftherearechildrenbuttheyareallcurrentlyrunning. pid_twaitpid(pid_tpid,int*stat_loc,intoptions):Similartowait()butallowsyoutowaitforaspecificprocessofgroupofprocesses,andallowsthespecificationofflagssuchaswnohang. wait3(.),wait4(.):Similartowait()butallowdifferentcombinationsofparametersandflags. inttcsetpgrp(intfildes,pid_tpgidjd):Setstheforegroundprocessgroupidtobetheforegroundgroupassociatedwiththecontrollingterminal.Thecontrollingterminalisusuallyassociatedwithstdin,stdout,andstderr(filedescriptorsO11,and2) intsetpgid(pid_tpid,pid_tpgid):SetstheprocessgroupIDoftheprocesswithIDpidtopgid. intdup2(intfiledes,intfiledes2):Causesthefiledescriptorfiledes2torefertothesamefileasfiledes.