ash.c 293 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878387938803881388238833884388538863887388838893890389138923893389438953896389738983899390039013902390339043905390639073908390939103911391239133914391539163917391839193920392139223923392439253926392739283929393039313932393339343935393639373938393939403941394239433944394539463947394839493950395139523953395439553956395739583959396039613962396339643965396639673968396939703971397239733974397539763977397839793980398139823983398439853986398739883989399039913992399339943995399639973998399940004001400240034004400540064007400840094010401140124013401440154016401740184019402040214022402340244025402640274028402940304031403240334034403540364037403840394040404140424043404440454046404740484049405040514052405340544055405640574058405940604061406240634064406540664067406840694070407140724073407440754076407740784079408040814082408340844085408640874088408940904091409240934094409540964097409840994100410141024103410441054106410741084109411041114112411341144115411641174118411941204121412241234124412541264127412841294130413141324133413441354136413741384139414041414142414341444145414641474148414941504151415241534154415541564157415841594160416141624163416441654166416741684169417041714172417341744175417641774178417941804181418241834184418541864187418841894190419141924193419441954196419741984199420042014202420342044205420642074208420942104211421242134214421542164217421842194220422142224223422442254226422742284229423042314232423342344235423642374238423942404241424242434244424542464247424842494250425142524253425442554256425742584259426042614262426342644265426642674268426942704271427242734274427542764277427842794280428142824283428442854286428742884289429042914292429342944295429642974298429943004301430243034304430543064307430843094310431143124313431443154316431743184319432043214322432343244325432643274328432943304331433243334334433543364337433843394340434143424343434443454346434743484349435043514352435343544355435643574358435943604361436243634364436543664367436843694370437143724373437443754376437743784379438043814382438343844385438643874388438943904391439243934394439543964397439843994400440144024403440444054406440744084409441044114412441344144415441644174418441944204421442244234424442544264427442844294430443144324433443444354436443744384439444044414442444344444445444644474448444944504451445244534454445544564457445844594460446144624463446444654466446744684469447044714472447344744475447644774478447944804481448244834484448544864487448844894490449144924493449444954496449744984499450045014502450345044505450645074508450945104511451245134514451545164517451845194520452145224523452445254526452745284529453045314532453345344535453645374538453945404541454245434544454545464547454845494550455145524553455445554556455745584559456045614562456345644565456645674568456945704571457245734574457545764577457845794580458145824583458445854586458745884589459045914592459345944595459645974598459946004601460246034604460546064607460846094610461146124613461446154616461746184619462046214622462346244625462646274628462946304631463246334634463546364637463846394640464146424643464446454646464746484649465046514652465346544655465646574658465946604661466246634664466546664667466846694670467146724673467446754676467746784679468046814682468346844685468646874688468946904691469246934694469546964697469846994700470147024703470447054706470747084709471047114712471347144715471647174718471947204721472247234724472547264727472847294730473147324733473447354736473747384739474047414742474347444745474647474748474947504751475247534754475547564757475847594760476147624763476447654766476747684769477047714772477347744775477647774778477947804781478247834784478547864787478847894790479147924793479447954796479747984799480048014802480348044805480648074808480948104811481248134814481548164817481848194820482148224823482448254826482748284829483048314832483348344835483648374838483948404841484248434844484548464847484848494850485148524853485448554856485748584859486048614862486348644865486648674868486948704871487248734874487548764877487848794880488148824883488448854886488748884889489048914892489348944895489648974898489949004901490249034904490549064907490849094910491149124913491449154916491749184919492049214922492349244925492649274928492949304931493249334934493549364937493849394940494149424943494449454946494749484949495049514952495349544955495649574958495949604961496249634964496549664967496849694970497149724973497449754976497749784979498049814982498349844985498649874988498949904991499249934994499549964997499849995000500150025003500450055006500750085009501050115012501350145015501650175018501950205021502250235024502550265027502850295030503150325033503450355036503750385039504050415042504350445045504650475048504950505051505250535054505550565057505850595060506150625063506450655066506750685069507050715072507350745075507650775078507950805081508250835084508550865087508850895090509150925093509450955096509750985099510051015102510351045105510651075108510951105111511251135114511551165117511851195120512151225123512451255126512751285129513051315132513351345135513651375138513951405141514251435144514551465147514851495150515151525153515451555156515751585159516051615162516351645165516651675168516951705171517251735174517551765177517851795180518151825183518451855186518751885189519051915192519351945195519651975198519952005201520252035204520552065207520852095210521152125213521452155216521752185219522052215222522352245225522652275228522952305231523252335234523552365237523852395240524152425243524452455246524752485249525052515252525352545255525652575258525952605261526252635264526552665267526852695270527152725273527452755276527752785279528052815282528352845285528652875288528952905291529252935294529552965297529852995300530153025303530453055306530753085309531053115312531353145315531653175318531953205321532253235324532553265327532853295330533153325333533453355336533753385339534053415342534353445345534653475348534953505351535253535354535553565357535853595360536153625363536453655366536753685369537053715372537353745375537653775378537953805381538253835384538553865387538853895390539153925393539453955396539753985399540054015402540354045405540654075408540954105411541254135414541554165417541854195420542154225423542454255426542754285429543054315432543354345435543654375438543954405441544254435444544554465447544854495450545154525453545454555456545754585459546054615462546354645465546654675468546954705471547254735474547554765477547854795480548154825483548454855486548754885489549054915492549354945495549654975498549955005501550255035504550555065507550855095510551155125513551455155516551755185519552055215522552355245525552655275528552955305531553255335534553555365537553855395540554155425543554455455546554755485549555055515552555355545555555655575558555955605561556255635564556555665567556855695570557155725573557455755576557755785579558055815582558355845585558655875588558955905591559255935594559555965597559855995600560156025603560456055606560756085609561056115612561356145615561656175618561956205621562256235624562556265627562856295630563156325633563456355636563756385639564056415642564356445645564656475648564956505651565256535654565556565657565856595660566156625663566456655666566756685669567056715672567356745675567656775678567956805681568256835684568556865687568856895690569156925693569456955696569756985699570057015702570357045705570657075708570957105711571257135714571557165717571857195720572157225723572457255726572757285729573057315732573357345735573657375738573957405741574257435744574557465747574857495750575157525753575457555756575757585759576057615762576357645765576657675768576957705771577257735774577557765777577857795780578157825783578457855786578757885789579057915792579357945795579657975798579958005801580258035804580558065807580858095810581158125813581458155816581758185819582058215822582358245825582658275828582958305831583258335834583558365837583858395840584158425843584458455846584758485849585058515852585358545855585658575858585958605861586258635864586558665867586858695870587158725873587458755876587758785879588058815882588358845885588658875888588958905891589258935894589558965897589858995900590159025903590459055906590759085909591059115912591359145915591659175918591959205921592259235924592559265927592859295930593159325933593459355936593759385939594059415942594359445945594659475948594959505951595259535954595559565957595859595960596159625963596459655966596759685969597059715972597359745975597659775978597959805981598259835984598559865987598859895990599159925993599459955996599759985999600060016002600360046005600660076008600960106011601260136014601560166017601860196020602160226023602460256026602760286029603060316032603360346035603660376038603960406041604260436044604560466047604860496050605160526053605460556056605760586059606060616062606360646065606660676068606960706071607260736074607560766077607860796080608160826083608460856086608760886089609060916092609360946095609660976098609961006101610261036104610561066107610861096110611161126113611461156116611761186119612061216122612361246125612661276128612961306131613261336134613561366137613861396140614161426143614461456146614761486149615061516152615361546155615661576158615961606161616261636164616561666167616861696170617161726173617461756176617761786179618061816182618361846185618661876188618961906191619261936194619561966197619861996200620162026203620462056206620762086209621062116212621362146215621662176218621962206221622262236224622562266227622862296230623162326233623462356236623762386239624062416242624362446245624662476248624962506251625262536254625562566257625862596260626162626263626462656266626762686269627062716272627362746275627662776278627962806281628262836284628562866287628862896290629162926293629462956296629762986299630063016302630363046305630663076308630963106311631263136314631563166317631863196320632163226323632463256326632763286329633063316332633363346335633663376338633963406341634263436344634563466347634863496350635163526353635463556356635763586359636063616362636363646365636663676368636963706371637263736374637563766377637863796380638163826383638463856386638763886389639063916392639363946395639663976398639964006401640264036404640564066407640864096410641164126413641464156416641764186419642064216422642364246425642664276428642964306431643264336434643564366437643864396440644164426443644464456446644764486449645064516452645364546455645664576458645964606461646264636464646564666467646864696470647164726473647464756476647764786479648064816482648364846485648664876488648964906491649264936494649564966497649864996500650165026503650465056506650765086509651065116512651365146515651665176518651965206521652265236524652565266527652865296530653165326533653465356536653765386539654065416542654365446545654665476548654965506551655265536554655565566557655865596560656165626563656465656566656765686569657065716572657365746575657665776578657965806581658265836584658565866587658865896590659165926593659465956596659765986599660066016602660366046605660666076608660966106611661266136614661566166617661866196620662166226623662466256626662766286629663066316632663366346635663666376638663966406641664266436644664566466647664866496650665166526653665466556656665766586659666066616662666366646665666666676668666966706671667266736674667566766677667866796680668166826683668466856686668766886689669066916692669366946695669666976698669967006701670267036704670567066707670867096710671167126713671467156716671767186719672067216722672367246725672667276728672967306731673267336734673567366737673867396740674167426743674467456746674767486749675067516752675367546755675667576758675967606761676267636764676567666767676867696770677167726773677467756776677767786779678067816782678367846785678667876788678967906791679267936794679567966797679867996800680168026803680468056806680768086809681068116812681368146815681668176818681968206821682268236824682568266827682868296830683168326833683468356836683768386839684068416842684368446845684668476848684968506851685268536854685568566857685868596860686168626863686468656866686768686869687068716872687368746875687668776878687968806881688268836884688568866887688868896890689168926893689468956896689768986899690069016902690369046905690669076908690969106911691269136914691569166917691869196920692169226923692469256926692769286929693069316932693369346935693669376938693969406941694269436944694569466947694869496950695169526953695469556956695769586959696069616962696369646965696669676968696969706971697269736974697569766977697869796980698169826983698469856986698769886989699069916992699369946995699669976998699970007001700270037004700570067007700870097010701170127013701470157016701770187019702070217022702370247025702670277028702970307031703270337034703570367037703870397040704170427043704470457046704770487049705070517052705370547055705670577058705970607061706270637064706570667067706870697070707170727073707470757076707770787079708070817082708370847085708670877088708970907091709270937094709570967097709870997100710171027103710471057106710771087109711071117112711371147115711671177118711971207121712271237124712571267127712871297130713171327133713471357136713771387139714071417142714371447145714671477148714971507151715271537154715571567157715871597160716171627163716471657166716771687169717071717172717371747175717671777178717971807181718271837184718571867187718871897190719171927193719471957196719771987199720072017202720372047205720672077208720972107211721272137214721572167217721872197220722172227223722472257226722772287229723072317232723372347235723672377238723972407241724272437244724572467247724872497250725172527253725472557256725772587259726072617262726372647265726672677268726972707271727272737274727572767277727872797280728172827283728472857286728772887289729072917292729372947295729672977298729973007301730273037304730573067307730873097310731173127313731473157316731773187319732073217322732373247325732673277328732973307331733273337334733573367337733873397340734173427343734473457346734773487349735073517352735373547355735673577358735973607361736273637364736573667367736873697370737173727373737473757376737773787379738073817382738373847385738673877388738973907391739273937394739573967397739873997400740174027403740474057406740774087409741074117412741374147415741674177418741974207421742274237424742574267427742874297430743174327433743474357436743774387439744074417442744374447445744674477448744974507451745274537454745574567457745874597460746174627463746474657466746774687469747074717472747374747475747674777478747974807481748274837484748574867487748874897490749174927493749474957496749774987499750075017502750375047505750675077508750975107511751275137514751575167517751875197520752175227523752475257526752775287529753075317532753375347535753675377538753975407541754275437544754575467547754875497550755175527553755475557556755775587559756075617562756375647565756675677568756975707571757275737574757575767577757875797580758175827583758475857586758775887589759075917592759375947595759675977598759976007601760276037604760576067607760876097610761176127613761476157616761776187619762076217622762376247625762676277628762976307631763276337634763576367637763876397640764176427643764476457646764776487649765076517652765376547655765676577658765976607661766276637664766576667667766876697670767176727673767476757676767776787679768076817682768376847685768676877688768976907691769276937694769576967697769876997700770177027703770477057706770777087709771077117712771377147715771677177718771977207721772277237724772577267727772877297730773177327733773477357736773777387739774077417742774377447745774677477748774977507751775277537754775577567757775877597760776177627763776477657766776777687769777077717772777377747775777677777778777977807781778277837784778577867787778877897790779177927793779477957796779777987799780078017802780378047805780678077808780978107811781278137814781578167817781878197820782178227823782478257826782778287829783078317832783378347835783678377838783978407841784278437844784578467847784878497850785178527853785478557856785778587859786078617862786378647865786678677868786978707871787278737874787578767877787878797880788178827883788478857886788778887889789078917892789378947895789678977898789979007901790279037904790579067907790879097910791179127913791479157916791779187919792079217922792379247925792679277928792979307931793279337934793579367937793879397940794179427943794479457946794779487949795079517952795379547955795679577958795979607961796279637964796579667967796879697970797179727973797479757976797779787979798079817982798379847985798679877988798979907991799279937994799579967997799879998000800180028003800480058006800780088009801080118012801380148015801680178018801980208021802280238024802580268027802880298030803180328033803480358036803780388039804080418042804380448045804680478048804980508051805280538054805580568057805880598060806180628063806480658066806780688069807080718072807380748075807680778078807980808081808280838084808580868087808880898090809180928093809480958096809780988099810081018102810381048105810681078108810981108111811281138114811581168117811881198120812181228123812481258126812781288129813081318132813381348135813681378138813981408141814281438144814581468147814881498150815181528153815481558156815781588159816081618162816381648165816681678168816981708171817281738174817581768177817881798180818181828183818481858186818781888189819081918192819381948195819681978198819982008201820282038204820582068207820882098210821182128213821482158216821782188219822082218222822382248225822682278228822982308231823282338234823582368237823882398240824182428243824482458246824782488249825082518252825382548255825682578258825982608261826282638264826582668267826882698270827182728273827482758276827782788279828082818282828382848285828682878288828982908291829282938294829582968297829882998300830183028303830483058306830783088309831083118312831383148315831683178318831983208321832283238324832583268327832883298330833183328333833483358336833783388339834083418342834383448345834683478348834983508351835283538354835583568357835883598360836183628363836483658366836783688369837083718372837383748375837683778378837983808381838283838384838583868387838883898390839183928393839483958396839783988399840084018402840384048405840684078408840984108411841284138414841584168417841884198420842184228423842484258426842784288429843084318432843384348435843684378438843984408441844284438444844584468447844884498450845184528453845484558456845784588459846084618462846384648465846684678468846984708471847284738474847584768477847884798480848184828483848484858486848784888489849084918492849384948495849684978498849985008501850285038504850585068507850885098510851185128513851485158516851785188519852085218522852385248525852685278528852985308531853285338534853585368537853885398540854185428543854485458546854785488549855085518552855385548555855685578558855985608561856285638564856585668567856885698570857185728573857485758576857785788579858085818582858385848585858685878588858985908591859285938594859585968597859885998600860186028603860486058606860786088609861086118612861386148615861686178618861986208621862286238624862586268627862886298630863186328633863486358636863786388639864086418642864386448645864686478648864986508651865286538654865586568657865886598660866186628663866486658666866786688669867086718672867386748675867686778678867986808681868286838684868586868687868886898690869186928693869486958696869786988699870087018702870387048705870687078708870987108711871287138714871587168717871887198720872187228723872487258726872787288729873087318732873387348735873687378738873987408741874287438744874587468747874887498750875187528753875487558756875787588759876087618762876387648765876687678768876987708771877287738774877587768777877887798780878187828783878487858786878787888789879087918792879387948795879687978798879988008801880288038804880588068807880888098810881188128813881488158816881788188819882088218822882388248825882688278828882988308831883288338834883588368837883888398840884188428843884488458846884788488849885088518852885388548855885688578858885988608861886288638864886588668867886888698870887188728873887488758876887788788879888088818882888388848885888688878888888988908891889288938894889588968897889888998900890189028903890489058906890789088909891089118912891389148915891689178918891989208921892289238924892589268927892889298930893189328933893489358936893789388939894089418942894389448945894689478948894989508951895289538954895589568957895889598960896189628963896489658966896789688969897089718972897389748975897689778978897989808981898289838984898589868987898889898990899189928993899489958996899789988999900090019002900390049005900690079008900990109011901290139014901590169017901890199020902190229023902490259026902790289029903090319032903390349035903690379038903990409041904290439044904590469047904890499050905190529053905490559056905790589059906090619062906390649065906690679068906990709071907290739074907590769077907890799080908190829083908490859086908790889089909090919092909390949095909690979098909991009101910291039104910591069107910891099110911191129113911491159116911791189119912091219122912391249125912691279128912991309131913291339134913591369137913891399140914191429143914491459146914791489149915091519152915391549155915691579158915991609161916291639164916591669167916891699170917191729173917491759176917791789179918091819182918391849185918691879188918991909191919291939194919591969197919891999200920192029203920492059206920792089209921092119212921392149215921692179218921992209221922292239224922592269227922892299230923192329233923492359236923792389239924092419242924392449245924692479248924992509251925292539254925592569257925892599260926192629263926492659266926792689269927092719272927392749275927692779278927992809281928292839284928592869287928892899290929192929293929492959296929792989299930093019302930393049305930693079308930993109311931293139314931593169317931893199320932193229323932493259326932793289329933093319332933393349335933693379338933993409341934293439344934593469347934893499350935193529353935493559356935793589359936093619362936393649365936693679368936993709371937293739374937593769377937893799380938193829383938493859386938793889389939093919392939393949395939693979398939994009401940294039404940594069407940894099410941194129413941494159416941794189419942094219422942394249425942694279428942994309431943294339434943594369437943894399440944194429443944494459446944794489449945094519452945394549455945694579458945994609461946294639464946594669467946894699470947194729473947494759476947794789479948094819482948394849485948694879488948994909491949294939494949594969497949894999500950195029503950495059506950795089509951095119512951395149515951695179518951995209521952295239524952595269527952895299530953195329533953495359536953795389539954095419542954395449545954695479548954995509551955295539554955595569557955895599560956195629563956495659566956795689569957095719572957395749575957695779578957995809581958295839584958595869587958895899590959195929593959495959596959795989599960096019602960396049605960696079608960996109611961296139614961596169617961896199620962196229623962496259626962796289629963096319632963396349635963696379638963996409641964296439644964596469647964896499650965196529653965496559656965796589659966096619662966396649665966696679668966996709671967296739674967596769677967896799680968196829683968496859686968796889689969096919692969396949695969696979698969997009701970297039704970597069707970897099710971197129713971497159716971797189719972097219722972397249725972697279728972997309731973297339734973597369737973897399740974197429743974497459746974797489749975097519752975397549755975697579758975997609761976297639764976597669767976897699770977197729773977497759776977797789779978097819782978397849785978697879788978997909791979297939794979597969797979897999800980198029803980498059806980798089809981098119812981398149815981698179818981998209821982298239824982598269827982898299830983198329833983498359836983798389839984098419842984398449845984698479848984998509851985298539854985598569857985898599860986198629863986498659866986798689869987098719872987398749875987698779878987998809881988298839884988598869887988898899890989198929893989498959896989798989899990099019902990399049905990699079908990999109911991299139914991599169917991899199920992199229923992499259926992799289929993099319932993399349935993699379938993999409941994299439944994599469947994899499950995199529953995499559956995799589959996099619962996399649965996699679968996999709971997299739974997599769977997899799980998199829983998499859986998799889989999099919992999399949995999699979998999910000100011000210003100041000510006100071000810009100101001110012100131001410015100161001710018100191002010021100221002310024100251002610027100281002910030100311003210033100341003510036100371003810039100401004110042100431004410045100461004710048100491005010051100521005310054100551005610057100581005910060100611006210063100641006510066100671006810069100701007110072100731007410075100761007710078100791008010081100821008310084100851008610087100881008910090100911009210093100941009510096100971009810099101001010110102101031010410105101061010710108101091011010111101121011310114101151011610117101181011910120101211012210123101241012510126101271012810129101301013110132101331013410135101361013710138101391014010141101421014310144101451014610147101481014910150101511015210153101541015510156101571015810159101601016110162101631016410165101661016710168101691017010171101721017310174101751017610177101781017910180101811018210183101841018510186101871018810189101901019110192101931019410195101961019710198101991020010201102021020310204102051020610207102081020910210102111021210213102141021510216102171021810219102201022110222102231022410225102261022710228102291023010231102321023310234102351023610237102381023910240102411024210243102441024510246102471024810249102501025110252102531025410255102561025710258102591026010261102621026310264102651026610267102681026910270102711027210273102741027510276102771027810279102801028110282102831028410285102861028710288102891029010291102921029310294102951029610297102981029910300103011030210303103041030510306103071030810309103101031110312103131031410315103161031710318103191032010321103221032310324103251032610327103281032910330103311033210333103341033510336103371033810339103401034110342103431034410345103461034710348103491035010351103521035310354103551035610357103581035910360103611036210363103641036510366103671036810369103701037110372103731037410375103761037710378103791038010381103821038310384103851038610387103881038910390103911039210393103941039510396103971039810399104001040110402104031040410405104061040710408104091041010411104121041310414104151041610417104181041910420104211042210423104241042510426104271042810429104301043110432104331043410435104361043710438104391044010441104421044310444104451044610447104481044910450104511045210453104541045510456104571045810459104601046110462104631046410465104661046710468104691047010471104721047310474104751047610477104781047910480104811048210483104841048510486104871048810489104901049110492104931049410495104961049710498104991050010501105021050310504105051050610507105081050910510105111051210513105141051510516105171051810519105201052110522105231052410525105261052710528105291053010531105321053310534105351053610537105381053910540105411054210543105441054510546105471054810549105501055110552105531055410555105561055710558105591056010561105621056310564105651056610567105681056910570105711057210573105741057510576105771057810579105801058110582105831058410585105861058710588105891059010591105921059310594105951059610597105981059910600106011060210603106041060510606106071060810609106101061110612106131061410615106161061710618106191062010621106221062310624106251062610627106281062910630106311063210633106341063510636106371063810639106401064110642106431064410645106461064710648106491065010651106521065310654106551065610657106581065910660106611066210663106641066510666106671066810669106701067110672106731067410675106761067710678106791068010681106821068310684106851068610687106881068910690106911069210693106941069510696106971069810699107001070110702107031070410705107061070710708107091071010711107121071310714107151071610717107181071910720107211072210723107241072510726107271072810729107301073110732107331073410735107361073710738107391074010741107421074310744107451074610747107481074910750107511075210753107541075510756107571075810759107601076110762107631076410765107661076710768107691077010771107721077310774107751077610777107781077910780107811078210783107841078510786107871078810789107901079110792107931079410795107961079710798107991080010801108021080310804108051080610807108081080910810108111081210813108141081510816108171081810819108201082110822108231082410825108261082710828108291083010831108321083310834108351083610837108381083910840108411084210843108441084510846108471084810849108501085110852108531085410855108561085710858108591086010861108621086310864108651086610867108681086910870108711087210873108741087510876108771087810879108801088110882108831088410885108861088710888108891089010891108921089310894108951089610897108981089910900109011090210903109041090510906109071090810909109101091110912109131091410915109161091710918109191092010921109221092310924109251092610927109281092910930109311093210933109341093510936109371093810939109401094110942109431094410945109461094710948109491095010951109521095310954109551095610957109581095910960109611096210963109641096510966109671096810969109701097110972109731097410975109761097710978109791098010981109821098310984109851098610987109881098910990109911099210993109941099510996109971099810999110001100111002110031100411005110061100711008110091101011011110121101311014110151101611017110181101911020110211102211023110241102511026110271102811029110301103111032110331103411035110361103711038110391104011041110421104311044110451104611047110481104911050110511105211053110541105511056110571105811059110601106111062110631106411065110661106711068110691107011071110721107311074110751107611077110781107911080110811108211083110841108511086110871108811089110901109111092110931109411095110961109711098110991110011101111021110311104111051110611107111081110911110111111111211113111141111511116111171111811119111201112111122111231112411125111261112711128111291113011131111321113311134111351113611137111381113911140111411114211143111441114511146111471114811149111501115111152111531115411155111561115711158111591116011161111621116311164111651116611167111681116911170111711117211173111741117511176111771117811179111801118111182111831118411185111861118711188111891119011191111921119311194111951119611197111981119911200112011120211203112041120511206112071120811209112101121111212112131121411215112161121711218112191122011221112221122311224112251122611227112281122911230112311123211233112341123511236112371123811239112401124111242112431124411245112461124711248112491125011251112521125311254112551125611257112581125911260112611126211263112641126511266112671126811269112701127111272112731127411275112761127711278112791128011281112821128311284112851128611287112881128911290112911129211293112941129511296112971129811299113001130111302113031130411305113061130711308113091131011311113121131311314113151131611317113181131911320113211132211323113241132511326113271132811329113301133111332113331133411335113361133711338113391134011341113421134311344113451134611347113481134911350113511135211353113541135511356113571135811359113601136111362113631136411365113661136711368113691137011371113721137311374113751137611377113781137911380113811138211383113841138511386113871138811389113901139111392113931139411395113961139711398113991140011401114021140311404114051140611407114081140911410114111141211413114141141511416114171141811419114201142111422114231142411425114261142711428114291143011431114321143311434114351143611437114381143911440114411144211443114441144511446114471144811449114501145111452114531145411455114561145711458114591146011461114621146311464114651146611467114681146911470114711147211473114741147511476114771147811479114801148111482114831148411485114861148711488114891149011491114921149311494114951149611497114981149911500115011150211503115041150511506115071150811509115101151111512115131151411515115161151711518115191152011521115221152311524115251152611527115281152911530115311153211533115341153511536115371153811539115401154111542115431154411545115461154711548115491155011551115521155311554115551155611557115581155911560115611156211563115641156511566115671156811569115701157111572115731157411575115761157711578115791158011581115821158311584115851158611587115881158911590115911159211593115941159511596115971159811599116001160111602116031160411605116061160711608116091161011611116121161311614116151161611617116181161911620116211162211623116241162511626116271162811629116301163111632116331163411635116361163711638116391164011641116421164311644116451164611647116481164911650116511165211653116541165511656116571165811659116601166111662116631166411665116661166711668116691167011671116721167311674116751167611677116781167911680116811168211683116841168511686116871168811689116901169111692116931169411695116961169711698116991170011701117021170311704117051170611707117081170911710117111171211713117141171511716117171171811719117201172111722117231172411725117261172711728117291173011731117321173311734117351173611737117381173911740117411174211743117441174511746117471174811749117501175111752117531175411755117561175711758117591176011761117621176311764117651176611767117681176911770117711177211773117741177511776117771177811779117801178111782117831178411785117861178711788117891179011791117921179311794117951179611797117981179911800118011180211803118041180511806118071180811809118101181111812118131181411815118161181711818118191182011821118221182311824118251182611827118281182911830118311183211833118341183511836118371183811839118401184111842118431184411845118461184711848118491185011851118521185311854118551185611857118581185911860118611186211863118641186511866118671186811869118701187111872118731187411875118761187711878118791188011881118821188311884118851188611887118881188911890118911189211893118941189511896118971189811899119001190111902119031190411905119061190711908119091191011911119121191311914119151191611917119181191911920119211192211923119241192511926119271192811929119301193111932119331193411935119361193711938119391194011941119421194311944119451194611947119481194911950119511195211953119541195511956119571195811959119601196111962119631196411965119661196711968119691197011971119721197311974119751197611977119781197911980119811198211983119841198511986119871198811989119901199111992119931199411995119961199711998119991200012001120021200312004120051200612007120081200912010120111201212013120141201512016120171201812019120201202112022120231202412025120261202712028120291203012031120321203312034120351203612037120381203912040120411204212043120441204512046120471204812049120501205112052120531205412055120561205712058120591206012061120621206312064120651206612067120681206912070120711207212073120741207512076120771207812079120801208112082120831208412085120861208712088120891209012091120921209312094120951209612097120981209912100121011210212103121041210512106121071210812109121101211112112121131211412115121161211712118121191212012121121221212312124121251212612127121281212912130121311213212133121341213512136121371213812139121401214112142121431214412145121461214712148121491215012151121521215312154121551215612157121581215912160121611216212163121641216512166121671216812169121701217112172121731217412175121761217712178121791218012181121821218312184121851218612187121881218912190121911219212193121941219512196121971219812199122001220112202122031220412205122061220712208122091221012211122121221312214122151221612217122181221912220122211222212223122241222512226122271222812229122301223112232122331223412235122361223712238122391224012241122421224312244122451224612247122481224912250122511225212253122541225512256122571225812259122601226112262122631226412265122661226712268122691227012271122721227312274122751227612277122781227912280122811228212283122841228512286122871228812289122901229112292122931229412295122961229712298122991230012301123021230312304123051230612307123081230912310123111231212313123141231512316123171231812319123201232112322123231232412325123261232712328123291233012331123321233312334123351233612337123381233912340123411234212343123441234512346123471234812349123501235112352123531235412355123561235712358123591236012361123621236312364123651236612367123681236912370123711237212373123741237512376123771237812379123801238112382123831238412385123861238712388123891239012391123921239312394123951239612397123981239912400124011240212403124041240512406124071240812409124101241112412124131241412415124161241712418124191242012421124221242312424124251242612427124281242912430124311243212433124341243512436124371243812439124401244112442124431244412445124461244712448124491245012451124521245312454124551245612457124581245912460124611246212463124641246512466124671246812469124701247112472124731247412475124761247712478124791248012481124821248312484124851248612487124881248912490124911249212493124941249512496124971249812499125001250112502125031250412505125061250712508125091251012511125121251312514125151251612517125181251912520125211252212523125241252512526125271252812529125301253112532125331253412535125361253712538125391254012541125421254312544125451254612547125481254912550125511255212553125541255512556125571255812559125601256112562125631256412565125661256712568125691257012571125721257312574125751257612577125781257912580125811258212583125841258512586125871258812589125901259112592125931259412595125961259712598125991260012601126021260312604126051260612607126081260912610126111261212613126141261512616126171261812619126201262112622126231262412625126261262712628126291263012631126321263312634126351263612637126381263912640126411264212643126441264512646126471264812649126501265112652126531265412655126561265712658126591266012661126621266312664126651266612667126681266912670126711267212673126741267512676126771267812679126801268112682126831268412685126861268712688126891269012691126921269312694126951269612697126981269912700127011270212703127041270512706127071270812709127101271112712127131271412715127161271712718127191272012721127221272312724127251272612727127281272912730127311273212733127341273512736127371273812739127401274112742127431274412745127461274712748127491275012751127521275312754127551275612757127581275912760127611276212763127641276512766127671276812769127701277112772127731277412775127761277712778127791278012781127821278312784127851278612787127881278912790127911279212793127941279512796127971279812799128001280112802128031280412805128061280712808128091281012811128121281312814128151281612817128181281912820128211282212823128241282512826128271282812829128301283112832128331283412835128361283712838128391284012841128421284312844128451284612847128481284912850128511285212853128541285512856128571285812859128601286112862128631286412865128661286712868128691287012871128721287312874128751287612877128781287912880128811288212883128841288512886128871288812889128901289112892128931289412895128961289712898128991290012901129021290312904129051290612907129081290912910129111291212913129141291512916129171291812919129201292112922129231292412925129261292712928129291293012931129321293312934129351293612937129381293912940129411294212943129441294512946129471294812949129501295112952129531295412955129561295712958129591296012961129621296312964129651296612967129681296912970129711297212973129741297512976129771297812979129801298112982129831298412985129861298712988129891299012991129921299312994129951299612997129981299913000130011300213003130041300513006130071300813009130101301113012130131301413015130161301713018130191302013021130221302313024130251302613027130281302913030130311303213033130341303513036130371303813039130401304113042130431304413045130461304713048130491305013051130521305313054130551305613057130581305913060130611306213063130641306513066130671306813069130701307113072130731307413075130761307713078130791308013081130821308313084130851308613087130881308913090130911309213093130941309513096130971309813099131001310113102131031310413105131061310713108131091311013111131121311313114131151311613117131181311913120131211312213123131241312513126131271312813129131301313113132131331313413135131361313713138131391314013141131421314313144131451314613147131481314913150131511315213153131541315513156131571315813159131601316113162131631316413165131661316713168131691317013171131721317313174131751317613177131781317913180131811318213183131841318513186131871318813189131901319113192131931319413195131961319713198131991320013201132021320313204132051320613207132081320913210132111321213213132141321513216132171321813219132201322113222132231322413225132261322713228132291323013231132321323313234132351323613237132381323913240132411324213243132441324513246132471324813249132501325113252132531325413255132561325713258132591326013261132621326313264132651326613267132681326913270132711327213273132741327513276132771327813279132801328113282132831328413285132861328713288132891329013291132921329313294132951329613297132981329913300133011330213303133041330513306133071330813309133101331113312133131331413315133161331713318133191332013321133221332313324133251332613327133281332913330133311333213333
  1. /* vi: set sw=4 ts=4: */
  2. /*
  3. * ash shell port for busybox
  4. *
  5. * This code is derived from software contributed to Berkeley by
  6. * Kenneth Almquist.
  7. *
  8. * Original BSD copyright notice is retained at the end of this file.
  9. *
  10. * Copyright (c) 1989, 1991, 1993, 1994
  11. * The Regents of the University of California. All rights reserved.
  12. *
  13. * Copyright (c) 1997-2005 Herbert Xu <herbert@gondor.apana.org.au>
  14. * was re-ported from NetBSD and debianized.
  15. *
  16. * Licensed under GPLv2 or later, see file LICENSE in this source tree.
  17. */
  18. /*
  19. * The following should be set to reflect the type of system you have:
  20. * JOBS -> 1 if you have Berkeley job control, 0 otherwise.
  21. * define SYSV if you are running under System V.
  22. * define DEBUG=1 to compile in debugging ('set -o debug' to turn on)
  23. * define DEBUG=2 to compile in and turn on debugging.
  24. *
  25. * When debugging is on (DEBUG is 1 and "set -o debug" was executed),
  26. * debugging info will be written to ./trace and a quit signal
  27. * will generate a core dump.
  28. */
  29. #define DEBUG 0
  30. /* Tweak debug output verbosity here */
  31. #define DEBUG_TIME 0
  32. #define DEBUG_PID 1
  33. #define DEBUG_SIG 1
  34. #define PROFILE 0
  35. #define JOBS ENABLE_ASH_JOB_CONTROL
  36. #include <paths.h>
  37. #include <setjmp.h>
  38. #include <fnmatch.h>
  39. #include <sys/times.h>
  40. #include "busybox.h" /* for applet_names */
  41. #include "unicode.h"
  42. #include "shell_common.h"
  43. #if ENABLE_SH_MATH_SUPPORT
  44. # include "math.h"
  45. #endif
  46. #if ENABLE_ASH_RANDOM_SUPPORT
  47. # include "random.h"
  48. #else
  49. # define CLEAR_RANDOM_T(rnd) ((void)0)
  50. #endif
  51. #include "NUM_APPLETS.h"
  52. #if NUM_APPLETS == 1
  53. /* STANDALONE does not make sense, and won't compile */
  54. # undef CONFIG_FEATURE_SH_STANDALONE
  55. # undef ENABLE_FEATURE_SH_STANDALONE
  56. # undef IF_FEATURE_SH_STANDALONE
  57. # undef IF_NOT_FEATURE_SH_STANDALONE
  58. # define ENABLE_FEATURE_SH_STANDALONE 0
  59. # define IF_FEATURE_SH_STANDALONE(...)
  60. # define IF_NOT_FEATURE_SH_STANDALONE(...) __VA_ARGS__
  61. #endif
  62. #ifndef PIPE_BUF
  63. # define PIPE_BUF 4096 /* amount of buffering in a pipe */
  64. #endif
  65. #if !BB_MMU
  66. # error "Do not even bother, ash will not run on NOMMU machine"
  67. #endif
  68. //config:config ASH
  69. //config: bool "ash"
  70. //config: default y
  71. //config: depends on !NOMMU
  72. //config: help
  73. //config: Tha 'ash' shell adds about 60k in the default configuration and is
  74. //config: the most complete and most pedantically correct shell included with
  75. //config: busybox. This shell is actually a derivative of the Debian 'dash'
  76. //config: shell (by Herbert Xu), which was created by porting the 'ash' shell
  77. //config: (written by Kenneth Almquist) from NetBSD.
  78. //config:
  79. //config:config ASH_BASH_COMPAT
  80. //config: bool "bash-compatible extensions"
  81. //config: default y
  82. //config: depends on ASH
  83. //config: help
  84. //config: Enable bash-compatible extensions.
  85. //config:
  86. //config:config ASH_IDLE_TIMEOUT
  87. //config: bool "Idle timeout variable"
  88. //config: default n
  89. //config: depends on ASH
  90. //config: help
  91. //config: Enables bash-like auto-logout after $TMOUT seconds of idle time.
  92. //config:
  93. //config:config ASH_JOB_CONTROL
  94. //config: bool "Job control"
  95. //config: default y
  96. //config: depends on ASH
  97. //config: help
  98. //config: Enable job control in the ash shell.
  99. //config:
  100. //config:config ASH_ALIAS
  101. //config: bool "Alias support"
  102. //config: default y
  103. //config: depends on ASH
  104. //config: help
  105. //config: Enable alias support in the ash shell.
  106. //config:
  107. //config:config ASH_GETOPTS
  108. //config: bool "Builtin getopt to parse positional parameters"
  109. //config: default y
  110. //config: depends on ASH
  111. //config: help
  112. //config: Enable support for getopts builtin in ash.
  113. //config:
  114. //config:config ASH_BUILTIN_ECHO
  115. //config: bool "Builtin version of 'echo'"
  116. //config: default y
  117. //config: depends on ASH
  118. //config: help
  119. //config: Enable support for echo builtin in ash.
  120. //config:
  121. //config:config ASH_BUILTIN_PRINTF
  122. //config: bool "Builtin version of 'printf'"
  123. //config: default y
  124. //config: depends on ASH
  125. //config: help
  126. //config: Enable support for printf builtin in ash.
  127. //config:
  128. //config:config ASH_BUILTIN_TEST
  129. //config: bool "Builtin version of 'test'"
  130. //config: default y
  131. //config: depends on ASH
  132. //config: help
  133. //config: Enable support for test builtin in ash.
  134. //config:
  135. //config:config ASH_CMDCMD
  136. //config: bool "'command' command to override shell builtins"
  137. //config: default y
  138. //config: depends on ASH
  139. //config: help
  140. //config: Enable support for the ash 'command' builtin, which allows
  141. //config: you to run the specified command with the specified arguments,
  142. //config: even when there is an ash builtin command with the same name.
  143. //config:
  144. //config:config ASH_MAIL
  145. //config: bool "Check for new mail on interactive shells"
  146. //config: default n
  147. //config: depends on ASH
  148. //config: help
  149. //config: Enable "check for new mail" function in the ash shell.
  150. //config:
  151. //config:config ASH_OPTIMIZE_FOR_SIZE
  152. //config: bool "Optimize for size instead of speed"
  153. //config: default y
  154. //config: depends on ASH
  155. //config: help
  156. //config: Compile ash for reduced size at the price of speed.
  157. //config:
  158. //config:config ASH_RANDOM_SUPPORT
  159. //config: bool "Pseudorandom generator and $RANDOM variable"
  160. //config: default y
  161. //config: depends on ASH
  162. //config: help
  163. //config: Enable pseudorandom generator and dynamic variable "$RANDOM".
  164. //config: Each read of "$RANDOM" will generate a new pseudorandom value.
  165. //config: You can reset the generator by using a specified start value.
  166. //config: After "unset RANDOM" the generator will switch off and this
  167. //config: variable will no longer have special treatment.
  168. //config:
  169. //config:config ASH_EXPAND_PRMT
  170. //config: bool "Expand prompt string"
  171. //config: default y
  172. //config: depends on ASH
  173. //config: help
  174. //config: "PS#" may contain volatile content, such as backquote commands.
  175. //config: This option recreates the prompt string from the environment
  176. //config: variable each time it is displayed.
  177. //config:
  178. //applet:IF_ASH(APPLET(ash, BB_DIR_BIN, BB_SUID_DROP))
  179. //applet:IF_FEATURE_SH_IS_ASH(APPLET_ODDNAME(sh, ash, BB_DIR_BIN, BB_SUID_DROP, sh))
  180. //applet:IF_FEATURE_BASH_IS_ASH(APPLET_ODDNAME(bash, ash, BB_DIR_BIN, BB_SUID_DROP, bash))
  181. //kbuild:lib-$(CONFIG_ASH) += ash.o ash_ptr_hack.o shell_common.o
  182. //kbuild:lib-$(CONFIG_ASH_RANDOM_SUPPORT) += random.o
  183. /* ============ Hash table sizes. Configurable. */
  184. #define VTABSIZE 39
  185. #define ATABSIZE 39
  186. #define CMDTABLESIZE 31 /* should be prime */
  187. /* ============ Shell options */
  188. static const char *const optletters_optnames[] = {
  189. "e" "errexit",
  190. "f" "noglob",
  191. "I" "ignoreeof",
  192. "i" "interactive",
  193. "m" "monitor",
  194. "n" "noexec",
  195. "s" "stdin",
  196. "x" "xtrace",
  197. "v" "verbose",
  198. "C" "noclobber",
  199. "a" "allexport",
  200. "b" "notify",
  201. "u" "nounset",
  202. "\0" "vi"
  203. #if ENABLE_ASH_BASH_COMPAT
  204. ,"\0" "pipefail"
  205. #endif
  206. #if DEBUG
  207. ,"\0" "nolog"
  208. ,"\0" "debug"
  209. #endif
  210. };
  211. #define optletters(n) optletters_optnames[n][0]
  212. #define optnames(n) (optletters_optnames[n] + 1)
  213. enum { NOPTS = ARRAY_SIZE(optletters_optnames) };
  214. /* ============ Misc data */
  215. #define msg_illnum "Illegal number: %s"
  216. /*
  217. * We enclose jmp_buf in a structure so that we can declare pointers to
  218. * jump locations. The global variable handler contains the location to
  219. * jump to when an exception occurs, and the global variable exception_type
  220. * contains a code identifying the exception. To implement nested
  221. * exception handlers, the user should save the value of handler on entry
  222. * to an inner scope, set handler to point to a jmploc structure for the
  223. * inner scope, and restore handler on exit from the scope.
  224. */
  225. struct jmploc {
  226. jmp_buf loc;
  227. };
  228. struct globals_misc {
  229. /* pid of main shell */
  230. int rootpid;
  231. /* shell level: 0 for the main shell, 1 for its children, and so on */
  232. int shlvl;
  233. #define rootshell (!shlvl)
  234. char *minusc; /* argument to -c option */
  235. char *curdir; // = nullstr; /* current working directory */
  236. char *physdir; // = nullstr; /* physical working directory */
  237. char *arg0; /* value of $0 */
  238. struct jmploc *exception_handler;
  239. volatile int suppress_int; /* counter */
  240. volatile /*sig_atomic_t*/ smallint pending_int; /* 1 = got SIGINT */
  241. /* last pending signal */
  242. volatile /*sig_atomic_t*/ smallint pending_sig;
  243. smallint exception_type; /* kind of exception (0..5) */
  244. /* exceptions */
  245. #define EXINT 0 /* SIGINT received */
  246. #define EXERROR 1 /* a generic error */
  247. #define EXSHELLPROC 2 /* execute a shell procedure */
  248. #define EXEXEC 3 /* command execution failed */
  249. #define EXEXIT 4 /* exit the shell */
  250. #define EXSIG 5 /* trapped signal in wait(1) */
  251. smallint isloginsh;
  252. char nullstr[1]; /* zero length string */
  253. char optlist[NOPTS];
  254. #define eflag optlist[0]
  255. #define fflag optlist[1]
  256. #define Iflag optlist[2]
  257. #define iflag optlist[3]
  258. #define mflag optlist[4]
  259. #define nflag optlist[5]
  260. #define sflag optlist[6]
  261. #define xflag optlist[7]
  262. #define vflag optlist[8]
  263. #define Cflag optlist[9]
  264. #define aflag optlist[10]
  265. #define bflag optlist[11]
  266. #define uflag optlist[12]
  267. #define viflag optlist[13]
  268. #if ENABLE_ASH_BASH_COMPAT
  269. # define pipefail optlist[14]
  270. #else
  271. # define pipefail 0
  272. #endif
  273. #if DEBUG
  274. # define nolog optlist[14 + ENABLE_ASH_BASH_COMPAT]
  275. # define debug optlist[15 + ENABLE_ASH_BASH_COMPAT]
  276. #endif
  277. /* trap handler commands */
  278. /*
  279. * Sigmode records the current value of the signal handlers for the various
  280. * modes. A value of zero means that the current handler is not known.
  281. * S_HARD_IGN indicates that the signal was ignored on entry to the shell.
  282. */
  283. char sigmode[NSIG - 1];
  284. #define S_DFL 1 /* default signal handling (SIG_DFL) */
  285. #define S_CATCH 2 /* signal is caught */
  286. #define S_IGN 3 /* signal is ignored (SIG_IGN) */
  287. #define S_HARD_IGN 4 /* signal is ignored permenantly */
  288. /* indicates specified signal received */
  289. uint8_t gotsig[NSIG - 1]; /* offset by 1: "signal" 0 is meaningless */
  290. uint8_t may_have_traps; /* 0: definitely no traps are set, 1: some traps may be set */
  291. char *trap[NSIG];
  292. char **trap_ptr; /* used only by "trap hack" */
  293. /* Rarely referenced stuff */
  294. #if ENABLE_ASH_RANDOM_SUPPORT
  295. random_t random_gen;
  296. #endif
  297. pid_t backgndpid; /* pid of last background process */
  298. smallint job_warning; /* user was warned about stopped jobs (can be 2, 1 or 0). */
  299. };
  300. extern struct globals_misc *const ash_ptr_to_globals_misc;
  301. #define G_misc (*ash_ptr_to_globals_misc)
  302. #define rootpid (G_misc.rootpid )
  303. #define shlvl (G_misc.shlvl )
  304. #define minusc (G_misc.minusc )
  305. #define curdir (G_misc.curdir )
  306. #define physdir (G_misc.physdir )
  307. #define arg0 (G_misc.arg0 )
  308. #define exception_handler (G_misc.exception_handler)
  309. #define exception_type (G_misc.exception_type )
  310. #define suppress_int (G_misc.suppress_int )
  311. #define pending_int (G_misc.pending_int )
  312. #define pending_sig (G_misc.pending_sig )
  313. #define isloginsh (G_misc.isloginsh )
  314. #define nullstr (G_misc.nullstr )
  315. #define optlist (G_misc.optlist )
  316. #define sigmode (G_misc.sigmode )
  317. #define gotsig (G_misc.gotsig )
  318. #define may_have_traps (G_misc.may_have_traps )
  319. #define trap (G_misc.trap )
  320. #define trap_ptr (G_misc.trap_ptr )
  321. #define random_gen (G_misc.random_gen )
  322. #define backgndpid (G_misc.backgndpid )
  323. #define job_warning (G_misc.job_warning)
  324. #define INIT_G_misc() do { \
  325. (*(struct globals_misc**)&ash_ptr_to_globals_misc) = xzalloc(sizeof(G_misc)); \
  326. barrier(); \
  327. curdir = nullstr; \
  328. physdir = nullstr; \
  329. trap_ptr = trap; \
  330. } while (0)
  331. /* ============ DEBUG */
  332. #if DEBUG
  333. static void trace_printf(const char *fmt, ...);
  334. static void trace_vprintf(const char *fmt, va_list va);
  335. # define TRACE(param) trace_printf param
  336. # define TRACEV(param) trace_vprintf param
  337. # define close(fd) do { \
  338. int dfd = (fd); \
  339. if (close(dfd) < 0) \
  340. bb_error_msg("bug on %d: closing %d(0x%x)", \
  341. __LINE__, dfd, dfd); \
  342. } while (0)
  343. #else
  344. # define TRACE(param)
  345. # define TRACEV(param)
  346. #endif
  347. /* ============ Utility functions */
  348. #define xbarrier() do { __asm__ __volatile__ ("": : :"memory"); } while (0)
  349. #define is_name(c) ((c) == '_' || isalpha((unsigned char)(c)))
  350. #define is_in_name(c) ((c) == '_' || isalnum((unsigned char)(c)))
  351. static int isdigit_str9(const char *str)
  352. {
  353. int maxlen = 9 + 1; /* max 9 digits: 999999999 */
  354. while (--maxlen && isdigit(*str))
  355. str++;
  356. return (*str == '\0');
  357. }
  358. static const char *var_end(const char *var)
  359. {
  360. while (*var)
  361. if (*var++ == '=')
  362. break;
  363. return var;
  364. }
  365. /* ============ Interrupts / exceptions */
  366. static void exitshell(void) NORETURN;
  367. /*
  368. * These macros allow the user to suspend the handling of interrupt signals
  369. * over a period of time. This is similar to SIGHOLD or to sigblock, but
  370. * much more efficient and portable. (But hacking the kernel is so much
  371. * more fun than worrying about efficiency and portability. :-))
  372. */
  373. #define INT_OFF do { \
  374. suppress_int++; \
  375. xbarrier(); \
  376. } while (0)
  377. /*
  378. * Called to raise an exception. Since C doesn't include exceptions, we
  379. * just do a longjmp to the exception handler. The type of exception is
  380. * stored in the global variable "exception_type".
  381. */
  382. static void raise_exception(int) NORETURN;
  383. static void
  384. raise_exception(int e)
  385. {
  386. #if DEBUG
  387. if (exception_handler == NULL)
  388. abort();
  389. #endif
  390. INT_OFF;
  391. exception_type = e;
  392. longjmp(exception_handler->loc, 1);
  393. }
  394. #if DEBUG
  395. #define raise_exception(e) do { \
  396. TRACE(("raising exception %d on line %d\n", (e), __LINE__)); \
  397. raise_exception(e); \
  398. } while (0)
  399. #endif
  400. /*
  401. * Called from trap.c when a SIGINT is received. (If the user specifies
  402. * that SIGINT is to be trapped or ignored using the trap builtin, then
  403. * this routine is not called.) Suppressint is nonzero when interrupts
  404. * are held using the INT_OFF macro. (The test for iflag is just
  405. * defensive programming.)
  406. */
  407. static void raise_interrupt(void) NORETURN;
  408. static void
  409. raise_interrupt(void)
  410. {
  411. int ex_type;
  412. pending_int = 0;
  413. /* Signal is not automatically unmasked after it is raised,
  414. * do it ourself - unmask all signals */
  415. sigprocmask_allsigs(SIG_UNBLOCK);
  416. /* pending_sig = 0; - now done in signal_handler() */
  417. ex_type = EXSIG;
  418. if (gotsig[SIGINT - 1] && !trap[SIGINT]) {
  419. if (!(rootshell && iflag)) {
  420. /* Kill ourself with SIGINT */
  421. signal(SIGINT, SIG_DFL);
  422. raise(SIGINT);
  423. }
  424. ex_type = EXINT;
  425. }
  426. raise_exception(ex_type);
  427. /* NOTREACHED */
  428. }
  429. #if DEBUG
  430. #define raise_interrupt() do { \
  431. TRACE(("raising interrupt on line %d\n", __LINE__)); \
  432. raise_interrupt(); \
  433. } while (0)
  434. #endif
  435. static IF_ASH_OPTIMIZE_FOR_SIZE(inline) void
  436. int_on(void)
  437. {
  438. xbarrier();
  439. if (--suppress_int == 0 && pending_int) {
  440. raise_interrupt();
  441. }
  442. }
  443. #define INT_ON int_on()
  444. static IF_ASH_OPTIMIZE_FOR_SIZE(inline) void
  445. force_int_on(void)
  446. {
  447. xbarrier();
  448. suppress_int = 0;
  449. if (pending_int)
  450. raise_interrupt();
  451. }
  452. #define FORCE_INT_ON force_int_on()
  453. #define SAVE_INT(v) ((v) = suppress_int)
  454. #define RESTORE_INT(v) do { \
  455. xbarrier(); \
  456. suppress_int = (v); \
  457. if (suppress_int == 0 && pending_int) \
  458. raise_interrupt(); \
  459. } while (0)
  460. /* ============ Stdout/stderr output */
  461. static void
  462. outstr(const char *p, FILE *file)
  463. {
  464. INT_OFF;
  465. fputs(p, file);
  466. INT_ON;
  467. }
  468. static void
  469. flush_stdout_stderr(void)
  470. {
  471. INT_OFF;
  472. fflush_all();
  473. INT_ON;
  474. }
  475. static void
  476. outcslow(int c, FILE *dest)
  477. {
  478. INT_OFF;
  479. putc(c, dest);
  480. fflush(dest);
  481. INT_ON;
  482. }
  483. static int out1fmt(const char *, ...) __attribute__((__format__(__printf__,1,2)));
  484. static int
  485. out1fmt(const char *fmt, ...)
  486. {
  487. va_list ap;
  488. int r;
  489. INT_OFF;
  490. va_start(ap, fmt);
  491. r = vprintf(fmt, ap);
  492. va_end(ap);
  493. INT_ON;
  494. return r;
  495. }
  496. static int fmtstr(char *, size_t, const char *, ...) __attribute__((__format__(__printf__,3,4)));
  497. static int
  498. fmtstr(char *outbuf, size_t length, const char *fmt, ...)
  499. {
  500. va_list ap;
  501. int ret;
  502. va_start(ap, fmt);
  503. INT_OFF;
  504. ret = vsnprintf(outbuf, length, fmt, ap);
  505. va_end(ap);
  506. INT_ON;
  507. return ret;
  508. }
  509. static void
  510. out1str(const char *p)
  511. {
  512. outstr(p, stdout);
  513. }
  514. static void
  515. out2str(const char *p)
  516. {
  517. outstr(p, stderr);
  518. flush_stdout_stderr();
  519. }
  520. /* ============ Parser structures */
  521. /* control characters in argument strings */
  522. #define CTL_FIRST CTLESC
  523. #define CTLESC ((unsigned char)'\201') /* escape next character */
  524. #define CTLVAR ((unsigned char)'\202') /* variable defn */
  525. #define CTLENDVAR ((unsigned char)'\203')
  526. #define CTLBACKQ ((unsigned char)'\204')
  527. #define CTLQUOTE 01 /* ored with CTLBACKQ code if in quotes */
  528. /* CTLBACKQ | CTLQUOTE == '\205' */
  529. #define CTLARI ((unsigned char)'\206') /* arithmetic expression */
  530. #define CTLENDARI ((unsigned char)'\207')
  531. #define CTLQUOTEMARK ((unsigned char)'\210')
  532. #define CTL_LAST CTLQUOTEMARK
  533. /* variable substitution byte (follows CTLVAR) */
  534. #define VSTYPE 0x0f /* type of variable substitution */
  535. #define VSNUL 0x10 /* colon--treat the empty string as unset */
  536. #define VSQUOTE 0x80 /* inside double quotes--suppress splitting */
  537. /* values of VSTYPE field */
  538. #define VSNORMAL 0x1 /* normal variable: $var or ${var} */
  539. #define VSMINUS 0x2 /* ${var-text} */
  540. #define VSPLUS 0x3 /* ${var+text} */
  541. #define VSQUESTION 0x4 /* ${var?message} */
  542. #define VSASSIGN 0x5 /* ${var=text} */
  543. #define VSTRIMRIGHT 0x6 /* ${var%pattern} */
  544. #define VSTRIMRIGHTMAX 0x7 /* ${var%%pattern} */
  545. #define VSTRIMLEFT 0x8 /* ${var#pattern} */
  546. #define VSTRIMLEFTMAX 0x9 /* ${var##pattern} */
  547. #define VSLENGTH 0xa /* ${#var} */
  548. #if ENABLE_ASH_BASH_COMPAT
  549. #define VSSUBSTR 0xc /* ${var:position:length} */
  550. #define VSREPLACE 0xd /* ${var/pattern/replacement} */
  551. #define VSREPLACEALL 0xe /* ${var//pattern/replacement} */
  552. #endif
  553. static const char dolatstr[] ALIGN1 = {
  554. CTLVAR, VSNORMAL|VSQUOTE, '@', '=', '\0'
  555. };
  556. #define NCMD 0
  557. #define NPIPE 1
  558. #define NREDIR 2
  559. #define NBACKGND 3
  560. #define NSUBSHELL 4
  561. #define NAND 5
  562. #define NOR 6
  563. #define NSEMI 7
  564. #define NIF 8
  565. #define NWHILE 9
  566. #define NUNTIL 10
  567. #define NFOR 11
  568. #define NCASE 12
  569. #define NCLIST 13
  570. #define NDEFUN 14
  571. #define NARG 15
  572. #define NTO 16
  573. #if ENABLE_ASH_BASH_COMPAT
  574. #define NTO2 17
  575. #endif
  576. #define NCLOBBER 18
  577. #define NFROM 19
  578. #define NFROMTO 20
  579. #define NAPPEND 21
  580. #define NTOFD 22
  581. #define NFROMFD 23
  582. #define NHERE 24
  583. #define NXHERE 25
  584. #define NNOT 26
  585. #define N_NUMBER 27
  586. union node;
  587. struct ncmd {
  588. smallint type; /* Nxxxx */
  589. union node *assign;
  590. union node *args;
  591. union node *redirect;
  592. };
  593. struct npipe {
  594. smallint type;
  595. smallint pipe_backgnd;
  596. struct nodelist *cmdlist;
  597. };
  598. struct nredir {
  599. smallint type;
  600. union node *n;
  601. union node *redirect;
  602. };
  603. struct nbinary {
  604. smallint type;
  605. union node *ch1;
  606. union node *ch2;
  607. };
  608. struct nif {
  609. smallint type;
  610. union node *test;
  611. union node *ifpart;
  612. union node *elsepart;
  613. };
  614. struct nfor {
  615. smallint type;
  616. union node *args;
  617. union node *body;
  618. char *var;
  619. };
  620. struct ncase {
  621. smallint type;
  622. union node *expr;
  623. union node *cases;
  624. };
  625. struct nclist {
  626. smallint type;
  627. union node *next;
  628. union node *pattern;
  629. union node *body;
  630. };
  631. struct narg {
  632. smallint type;
  633. union node *next;
  634. char *text;
  635. struct nodelist *backquote;
  636. };
  637. /* nfile and ndup layout must match!
  638. * NTOFD (>&fdnum) uses ndup structure, but we may discover mid-flight
  639. * that it is actually NTO2 (>&file), and change its type.
  640. */
  641. struct nfile {
  642. smallint type;
  643. union node *next;
  644. int fd;
  645. int _unused_dupfd;
  646. union node *fname;
  647. char *expfname;
  648. };
  649. struct ndup {
  650. smallint type;
  651. union node *next;
  652. int fd;
  653. int dupfd;
  654. union node *vname;
  655. char *_unused_expfname;
  656. };
  657. struct nhere {
  658. smallint type;
  659. union node *next;
  660. int fd;
  661. union node *doc;
  662. };
  663. struct nnot {
  664. smallint type;
  665. union node *com;
  666. };
  667. union node {
  668. smallint type;
  669. struct ncmd ncmd;
  670. struct npipe npipe;
  671. struct nredir nredir;
  672. struct nbinary nbinary;
  673. struct nif nif;
  674. struct nfor nfor;
  675. struct ncase ncase;
  676. struct nclist nclist;
  677. struct narg narg;
  678. struct nfile nfile;
  679. struct ndup ndup;
  680. struct nhere nhere;
  681. struct nnot nnot;
  682. };
  683. /*
  684. * NODE_EOF is returned by parsecmd when it encounters an end of file.
  685. * It must be distinct from NULL.
  686. */
  687. #define NODE_EOF ((union node *) -1L)
  688. struct nodelist {
  689. struct nodelist *next;
  690. union node *n;
  691. };
  692. struct funcnode {
  693. int count;
  694. union node n;
  695. };
  696. /*
  697. * Free a parse tree.
  698. */
  699. static void
  700. freefunc(struct funcnode *f)
  701. {
  702. if (f && --f->count < 0)
  703. free(f);
  704. }
  705. /* ============ Debugging output */
  706. #if DEBUG
  707. static FILE *tracefile;
  708. static void
  709. trace_printf(const char *fmt, ...)
  710. {
  711. va_list va;
  712. if (debug != 1)
  713. return;
  714. if (DEBUG_TIME)
  715. fprintf(tracefile, "%u ", (int) time(NULL));
  716. if (DEBUG_PID)
  717. fprintf(tracefile, "[%u] ", (int) getpid());
  718. if (DEBUG_SIG)
  719. fprintf(tracefile, "pending s:%d i:%d(supp:%d) ", pending_sig, pending_int, suppress_int);
  720. va_start(va, fmt);
  721. vfprintf(tracefile, fmt, va);
  722. va_end(va);
  723. }
  724. static void
  725. trace_vprintf(const char *fmt, va_list va)
  726. {
  727. if (debug != 1)
  728. return;
  729. if (DEBUG_TIME)
  730. fprintf(tracefile, "%u ", (int) time(NULL));
  731. if (DEBUG_PID)
  732. fprintf(tracefile, "[%u] ", (int) getpid());
  733. if (DEBUG_SIG)
  734. fprintf(tracefile, "pending s:%d i:%d(supp:%d) ", pending_sig, pending_int, suppress_int);
  735. vfprintf(tracefile, fmt, va);
  736. }
  737. static void
  738. trace_puts(const char *s)
  739. {
  740. if (debug != 1)
  741. return;
  742. fputs(s, tracefile);
  743. }
  744. static void
  745. trace_puts_quoted(char *s)
  746. {
  747. char *p;
  748. char c;
  749. if (debug != 1)
  750. return;
  751. putc('"', tracefile);
  752. for (p = s; *p; p++) {
  753. switch ((unsigned char)*p) {
  754. case '\n': c = 'n'; goto backslash;
  755. case '\t': c = 't'; goto backslash;
  756. case '\r': c = 'r'; goto backslash;
  757. case '\"': c = '\"'; goto backslash;
  758. case '\\': c = '\\'; goto backslash;
  759. case CTLESC: c = 'e'; goto backslash;
  760. case CTLVAR: c = 'v'; goto backslash;
  761. case CTLVAR+CTLQUOTE: c = 'V'; goto backslash;
  762. case CTLBACKQ: c = 'q'; goto backslash;
  763. case CTLBACKQ+CTLQUOTE: c = 'Q'; goto backslash;
  764. backslash:
  765. putc('\\', tracefile);
  766. putc(c, tracefile);
  767. break;
  768. default:
  769. if (*p >= ' ' && *p <= '~')
  770. putc(*p, tracefile);
  771. else {
  772. putc('\\', tracefile);
  773. putc((*p >> 6) & 03, tracefile);
  774. putc((*p >> 3) & 07, tracefile);
  775. putc(*p & 07, tracefile);
  776. }
  777. break;
  778. }
  779. }
  780. putc('"', tracefile);
  781. }
  782. static void
  783. trace_puts_args(char **ap)
  784. {
  785. if (debug != 1)
  786. return;
  787. if (!*ap)
  788. return;
  789. while (1) {
  790. trace_puts_quoted(*ap);
  791. if (!*++ap) {
  792. putc('\n', tracefile);
  793. break;
  794. }
  795. putc(' ', tracefile);
  796. }
  797. }
  798. static void
  799. opentrace(void)
  800. {
  801. char s[100];
  802. #ifdef O_APPEND
  803. int flags;
  804. #endif
  805. if (debug != 1) {
  806. if (tracefile)
  807. fflush(tracefile);
  808. /* leave open because libedit might be using it */
  809. return;
  810. }
  811. strcpy(s, "./trace");
  812. if (tracefile) {
  813. if (!freopen(s, "a", tracefile)) {
  814. fprintf(stderr, "Can't re-open %s\n", s);
  815. debug = 0;
  816. return;
  817. }
  818. } else {
  819. tracefile = fopen(s, "a");
  820. if (tracefile == NULL) {
  821. fprintf(stderr, "Can't open %s\n", s);
  822. debug = 0;
  823. return;
  824. }
  825. }
  826. #ifdef O_APPEND
  827. flags = fcntl(fileno(tracefile), F_GETFL);
  828. if (flags >= 0)
  829. fcntl(fileno(tracefile), F_SETFL, flags | O_APPEND);
  830. #endif
  831. setlinebuf(tracefile);
  832. fputs("\nTracing started.\n", tracefile);
  833. }
  834. static void
  835. indent(int amount, char *pfx, FILE *fp)
  836. {
  837. int i;
  838. for (i = 0; i < amount; i++) {
  839. if (pfx && i == amount - 1)
  840. fputs(pfx, fp);
  841. putc('\t', fp);
  842. }
  843. }
  844. /* little circular references here... */
  845. static void shtree(union node *n, int ind, char *pfx, FILE *fp);
  846. static void
  847. sharg(union node *arg, FILE *fp)
  848. {
  849. char *p;
  850. struct nodelist *bqlist;
  851. unsigned char subtype;
  852. if (arg->type != NARG) {
  853. out1fmt("<node type %d>\n", arg->type);
  854. abort();
  855. }
  856. bqlist = arg->narg.backquote;
  857. for (p = arg->narg.text; *p; p++) {
  858. switch ((unsigned char)*p) {
  859. case CTLESC:
  860. p++;
  861. putc(*p, fp);
  862. break;
  863. case CTLVAR:
  864. putc('$', fp);
  865. putc('{', fp);
  866. subtype = *++p;
  867. if (subtype == VSLENGTH)
  868. putc('#', fp);
  869. while (*p != '=') {
  870. putc(*p, fp);
  871. p++;
  872. }
  873. if (subtype & VSNUL)
  874. putc(':', fp);
  875. switch (subtype & VSTYPE) {
  876. case VSNORMAL:
  877. putc('}', fp);
  878. break;
  879. case VSMINUS:
  880. putc('-', fp);
  881. break;
  882. case VSPLUS:
  883. putc('+', fp);
  884. break;
  885. case VSQUESTION:
  886. putc('?', fp);
  887. break;
  888. case VSASSIGN:
  889. putc('=', fp);
  890. break;
  891. case VSTRIMLEFT:
  892. putc('#', fp);
  893. break;
  894. case VSTRIMLEFTMAX:
  895. putc('#', fp);
  896. putc('#', fp);
  897. break;
  898. case VSTRIMRIGHT:
  899. putc('%', fp);
  900. break;
  901. case VSTRIMRIGHTMAX:
  902. putc('%', fp);
  903. putc('%', fp);
  904. break;
  905. case VSLENGTH:
  906. break;
  907. default:
  908. out1fmt("<subtype %d>", subtype);
  909. }
  910. break;
  911. case CTLENDVAR:
  912. putc('}', fp);
  913. break;
  914. case CTLBACKQ:
  915. case CTLBACKQ|CTLQUOTE:
  916. putc('$', fp);
  917. putc('(', fp);
  918. shtree(bqlist->n, -1, NULL, fp);
  919. putc(')', fp);
  920. break;
  921. default:
  922. putc(*p, fp);
  923. break;
  924. }
  925. }
  926. }
  927. static void
  928. shcmd(union node *cmd, FILE *fp)
  929. {
  930. union node *np;
  931. int first;
  932. const char *s;
  933. int dftfd;
  934. first = 1;
  935. for (np = cmd->ncmd.args; np; np = np->narg.next) {
  936. if (!first)
  937. putc(' ', fp);
  938. sharg(np, fp);
  939. first = 0;
  940. }
  941. for (np = cmd->ncmd.redirect; np; np = np->nfile.next) {
  942. if (!first)
  943. putc(' ', fp);
  944. dftfd = 0;
  945. switch (np->nfile.type) {
  946. case NTO: s = ">>"+1; dftfd = 1; break;
  947. case NCLOBBER: s = ">|"; dftfd = 1; break;
  948. case NAPPEND: s = ">>"; dftfd = 1; break;
  949. #if ENABLE_ASH_BASH_COMPAT
  950. case NTO2:
  951. #endif
  952. case NTOFD: s = ">&"; dftfd = 1; break;
  953. case NFROM: s = "<"; break;
  954. case NFROMFD: s = "<&"; break;
  955. case NFROMTO: s = "<>"; break;
  956. default: s = "*error*"; break;
  957. }
  958. if (np->nfile.fd != dftfd)
  959. fprintf(fp, "%d", np->nfile.fd);
  960. fputs(s, fp);
  961. if (np->nfile.type == NTOFD || np->nfile.type == NFROMFD) {
  962. fprintf(fp, "%d", np->ndup.dupfd);
  963. } else {
  964. sharg(np->nfile.fname, fp);
  965. }
  966. first = 0;
  967. }
  968. }
  969. static void
  970. shtree(union node *n, int ind, char *pfx, FILE *fp)
  971. {
  972. struct nodelist *lp;
  973. const char *s;
  974. if (n == NULL)
  975. return;
  976. indent(ind, pfx, fp);
  977. if (n == NODE_EOF) {
  978. fputs("<EOF>", fp);
  979. return;
  980. }
  981. switch (n->type) {
  982. case NSEMI:
  983. s = "; ";
  984. goto binop;
  985. case NAND:
  986. s = " && ";
  987. goto binop;
  988. case NOR:
  989. s = " || ";
  990. binop:
  991. shtree(n->nbinary.ch1, ind, NULL, fp);
  992. /* if (ind < 0) */
  993. fputs(s, fp);
  994. shtree(n->nbinary.ch2, ind, NULL, fp);
  995. break;
  996. case NCMD:
  997. shcmd(n, fp);
  998. if (ind >= 0)
  999. putc('\n', fp);
  1000. break;
  1001. case NPIPE:
  1002. for (lp = n->npipe.cmdlist; lp; lp = lp->next) {
  1003. shtree(lp->n, 0, NULL, fp);
  1004. if (lp->next)
  1005. fputs(" | ", fp);
  1006. }
  1007. if (n->npipe.pipe_backgnd)
  1008. fputs(" &", fp);
  1009. if (ind >= 0)
  1010. putc('\n', fp);
  1011. break;
  1012. default:
  1013. fprintf(fp, "<node type %d>", n->type);
  1014. if (ind >= 0)
  1015. putc('\n', fp);
  1016. break;
  1017. }
  1018. }
  1019. static void
  1020. showtree(union node *n)
  1021. {
  1022. trace_puts("showtree called\n");
  1023. shtree(n, 1, NULL, stderr);
  1024. }
  1025. #endif /* DEBUG */
  1026. /* ============ Parser data */
  1027. /*
  1028. * ash_vmsg() needs parsefile->fd, hence parsefile definition is moved up.
  1029. */
  1030. struct strlist {
  1031. struct strlist *next;
  1032. char *text;
  1033. };
  1034. struct alias;
  1035. struct strpush {
  1036. struct strpush *prev; /* preceding string on stack */
  1037. char *prev_string;
  1038. int prev_left_in_line;
  1039. #if ENABLE_ASH_ALIAS
  1040. struct alias *ap; /* if push was associated with an alias */
  1041. #endif
  1042. char *string; /* remember the string since it may change */
  1043. };
  1044. struct parsefile {
  1045. struct parsefile *prev; /* preceding file on stack */
  1046. int linno; /* current line */
  1047. int pf_fd; /* file descriptor (or -1 if string) */
  1048. int left_in_line; /* number of chars left in this line */
  1049. int left_in_buffer; /* number of chars left in this buffer past the line */
  1050. char *next_to_pgetc; /* next char in buffer */
  1051. char *buf; /* input buffer */
  1052. struct strpush *strpush; /* for pushing strings at this level */
  1053. struct strpush basestrpush; /* so pushing one is fast */
  1054. };
  1055. static struct parsefile basepf; /* top level input file */
  1056. static struct parsefile *g_parsefile = &basepf; /* current input file */
  1057. static int startlinno; /* line # where last token started */
  1058. static char *commandname; /* currently executing command */
  1059. static struct strlist *cmdenviron; /* environment for builtin command */
  1060. static uint8_t exitstatus; /* exit status of last command */
  1061. /* ============ Message printing */
  1062. static void
  1063. ash_vmsg(const char *msg, va_list ap)
  1064. {
  1065. fprintf(stderr, "%s: ", arg0);
  1066. if (commandname) {
  1067. if (strcmp(arg0, commandname))
  1068. fprintf(stderr, "%s: ", commandname);
  1069. if (!iflag || g_parsefile->pf_fd > 0)
  1070. fprintf(stderr, "line %d: ", startlinno);
  1071. }
  1072. vfprintf(stderr, msg, ap);
  1073. outcslow('\n', stderr);
  1074. }
  1075. /*
  1076. * Exverror is called to raise the error exception. If the second argument
  1077. * is not NULL then error prints an error message using printf style
  1078. * formatting. It then raises the error exception.
  1079. */
  1080. static void ash_vmsg_and_raise(int, const char *, va_list) NORETURN;
  1081. static void
  1082. ash_vmsg_and_raise(int cond, const char *msg, va_list ap)
  1083. {
  1084. #if DEBUG
  1085. if (msg) {
  1086. TRACE(("ash_vmsg_and_raise(%d, \"", cond));
  1087. TRACEV((msg, ap));
  1088. TRACE(("\") pid=%d\n", getpid()));
  1089. } else
  1090. TRACE(("ash_vmsg_and_raise(%d, NULL) pid=%d\n", cond, getpid()));
  1091. if (msg)
  1092. #endif
  1093. ash_vmsg(msg, ap);
  1094. flush_stdout_stderr();
  1095. raise_exception(cond);
  1096. /* NOTREACHED */
  1097. }
  1098. static void ash_msg_and_raise_error(const char *, ...) NORETURN;
  1099. static void
  1100. ash_msg_and_raise_error(const char *msg, ...)
  1101. {
  1102. va_list ap;
  1103. va_start(ap, msg);
  1104. ash_vmsg_and_raise(EXERROR, msg, ap);
  1105. /* NOTREACHED */
  1106. va_end(ap);
  1107. }
  1108. static void raise_error_syntax(const char *) NORETURN;
  1109. static void
  1110. raise_error_syntax(const char *msg)
  1111. {
  1112. ash_msg_and_raise_error("syntax error: %s", msg);
  1113. /* NOTREACHED */
  1114. }
  1115. static void ash_msg_and_raise(int, const char *, ...) NORETURN;
  1116. static void
  1117. ash_msg_and_raise(int cond, const char *msg, ...)
  1118. {
  1119. va_list ap;
  1120. va_start(ap, msg);
  1121. ash_vmsg_and_raise(cond, msg, ap);
  1122. /* NOTREACHED */
  1123. va_end(ap);
  1124. }
  1125. /*
  1126. * error/warning routines for external builtins
  1127. */
  1128. static void
  1129. ash_msg(const char *fmt, ...)
  1130. {
  1131. va_list ap;
  1132. va_start(ap, fmt);
  1133. ash_vmsg(fmt, ap);
  1134. va_end(ap);
  1135. }
  1136. /*
  1137. * Return a string describing an error. The returned string may be a
  1138. * pointer to a static buffer that will be overwritten on the next call.
  1139. * Action describes the operation that got the error.
  1140. */
  1141. static const char *
  1142. errmsg(int e, const char *em)
  1143. {
  1144. if (e == ENOENT || e == ENOTDIR) {
  1145. return em;
  1146. }
  1147. return strerror(e);
  1148. }
  1149. /* ============ Memory allocation */
  1150. #if 0
  1151. /* I consider these wrappers nearly useless:
  1152. * ok, they return you to nearest exception handler, but
  1153. * how much memory do you leak in the process, making
  1154. * memory starvation worse?
  1155. */
  1156. static void *
  1157. ckrealloc(void * p, size_t nbytes)
  1158. {
  1159. p = realloc(p, nbytes);
  1160. if (!p)
  1161. ash_msg_and_raise_error(bb_msg_memory_exhausted);
  1162. return p;
  1163. }
  1164. static void *
  1165. ckmalloc(size_t nbytes)
  1166. {
  1167. return ckrealloc(NULL, nbytes);
  1168. }
  1169. static void *
  1170. ckzalloc(size_t nbytes)
  1171. {
  1172. return memset(ckmalloc(nbytes), 0, nbytes);
  1173. }
  1174. static char *
  1175. ckstrdup(const char *s)
  1176. {
  1177. char *p = strdup(s);
  1178. if (!p)
  1179. ash_msg_and_raise_error(bb_msg_memory_exhausted);
  1180. return p;
  1181. }
  1182. #else
  1183. /* Using bbox equivalents. They exit if out of memory */
  1184. # define ckrealloc xrealloc
  1185. # define ckmalloc xmalloc
  1186. # define ckzalloc xzalloc
  1187. # define ckstrdup xstrdup
  1188. #endif
  1189. /*
  1190. * It appears that grabstackstr() will barf with such alignments
  1191. * because stalloc() will return a string allocated in a new stackblock.
  1192. */
  1193. #define SHELL_ALIGN(nbytes) (((nbytes) + SHELL_SIZE) & ~SHELL_SIZE)
  1194. enum {
  1195. /* Most machines require the value returned from malloc to be aligned
  1196. * in some way. The following macro will get this right
  1197. * on many machines. */
  1198. SHELL_SIZE = sizeof(union { int i; char *cp; double d; }) - 1,
  1199. /* Minimum size of a block */
  1200. MINSIZE = SHELL_ALIGN(504),
  1201. };
  1202. struct stack_block {
  1203. struct stack_block *prev;
  1204. char space[MINSIZE];
  1205. };
  1206. struct stackmark {
  1207. struct stack_block *stackp;
  1208. char *stacknxt;
  1209. size_t stacknleft;
  1210. struct stackmark *marknext;
  1211. };
  1212. struct globals_memstack {
  1213. struct stack_block *g_stackp; // = &stackbase;
  1214. struct stackmark *markp;
  1215. char *g_stacknxt; // = stackbase.space;
  1216. char *sstrend; // = stackbase.space + MINSIZE;
  1217. size_t g_stacknleft; // = MINSIZE;
  1218. int herefd; // = -1;
  1219. struct stack_block stackbase;
  1220. };
  1221. extern struct globals_memstack *const ash_ptr_to_globals_memstack;
  1222. #define G_memstack (*ash_ptr_to_globals_memstack)
  1223. #define g_stackp (G_memstack.g_stackp )
  1224. #define markp (G_memstack.markp )
  1225. #define g_stacknxt (G_memstack.g_stacknxt )
  1226. #define sstrend (G_memstack.sstrend )
  1227. #define g_stacknleft (G_memstack.g_stacknleft)
  1228. #define herefd (G_memstack.herefd )
  1229. #define stackbase (G_memstack.stackbase )
  1230. #define INIT_G_memstack() do { \
  1231. (*(struct globals_memstack**)&ash_ptr_to_globals_memstack) = xzalloc(sizeof(G_memstack)); \
  1232. barrier(); \
  1233. g_stackp = &stackbase; \
  1234. g_stacknxt = stackbase.space; \
  1235. g_stacknleft = MINSIZE; \
  1236. sstrend = stackbase.space + MINSIZE; \
  1237. herefd = -1; \
  1238. } while (0)
  1239. #define stackblock() ((void *)g_stacknxt)
  1240. #define stackblocksize() g_stacknleft
  1241. /*
  1242. * Parse trees for commands are allocated in lifo order, so we use a stack
  1243. * to make this more efficient, and also to avoid all sorts of exception
  1244. * handling code to handle interrupts in the middle of a parse.
  1245. *
  1246. * The size 504 was chosen because the Ultrix malloc handles that size
  1247. * well.
  1248. */
  1249. static void *
  1250. stalloc(size_t nbytes)
  1251. {
  1252. char *p;
  1253. size_t aligned;
  1254. aligned = SHELL_ALIGN(nbytes);
  1255. if (aligned > g_stacknleft) {
  1256. size_t len;
  1257. size_t blocksize;
  1258. struct stack_block *sp;
  1259. blocksize = aligned;
  1260. if (blocksize < MINSIZE)
  1261. blocksize = MINSIZE;
  1262. len = sizeof(struct stack_block) - MINSIZE + blocksize;
  1263. if (len < blocksize)
  1264. ash_msg_and_raise_error(bb_msg_memory_exhausted);
  1265. INT_OFF;
  1266. sp = ckmalloc(len);
  1267. sp->prev = g_stackp;
  1268. g_stacknxt = sp->space;
  1269. g_stacknleft = blocksize;
  1270. sstrend = g_stacknxt + blocksize;
  1271. g_stackp = sp;
  1272. INT_ON;
  1273. }
  1274. p = g_stacknxt;
  1275. g_stacknxt += aligned;
  1276. g_stacknleft -= aligned;
  1277. return p;
  1278. }
  1279. static void *
  1280. stzalloc(size_t nbytes)
  1281. {
  1282. return memset(stalloc(nbytes), 0, nbytes);
  1283. }
  1284. static void
  1285. stunalloc(void *p)
  1286. {
  1287. #if DEBUG
  1288. if (!p || (g_stacknxt < (char *)p) || ((char *)p < g_stackp->space)) {
  1289. write(STDERR_FILENO, "stunalloc\n", 10);
  1290. abort();
  1291. }
  1292. #endif
  1293. g_stacknleft += g_stacknxt - (char *)p;
  1294. g_stacknxt = p;
  1295. }
  1296. /*
  1297. * Like strdup but works with the ash stack.
  1298. */
  1299. static char *
  1300. ststrdup(const char *p)
  1301. {
  1302. size_t len = strlen(p) + 1;
  1303. return memcpy(stalloc(len), p, len);
  1304. }
  1305. static void
  1306. setstackmark(struct stackmark *mark)
  1307. {
  1308. mark->stackp = g_stackp;
  1309. mark->stacknxt = g_stacknxt;
  1310. mark->stacknleft = g_stacknleft;
  1311. mark->marknext = markp;
  1312. markp = mark;
  1313. }
  1314. static void
  1315. popstackmark(struct stackmark *mark)
  1316. {
  1317. struct stack_block *sp;
  1318. if (!mark->stackp)
  1319. return;
  1320. INT_OFF;
  1321. markp = mark->marknext;
  1322. while (g_stackp != mark->stackp) {
  1323. sp = g_stackp;
  1324. g_stackp = sp->prev;
  1325. free(sp);
  1326. }
  1327. g_stacknxt = mark->stacknxt;
  1328. g_stacknleft = mark->stacknleft;
  1329. sstrend = mark->stacknxt + mark->stacknleft;
  1330. INT_ON;
  1331. }
  1332. /*
  1333. * When the parser reads in a string, it wants to stick the string on the
  1334. * stack and only adjust the stack pointer when it knows how big the
  1335. * string is. Stackblock (defined in stack.h) returns a pointer to a block
  1336. * of space on top of the stack and stackblocklen returns the length of
  1337. * this block. Growstackblock will grow this space by at least one byte,
  1338. * possibly moving it (like realloc). Grabstackblock actually allocates the
  1339. * part of the block that has been used.
  1340. */
  1341. static void
  1342. growstackblock(void)
  1343. {
  1344. size_t newlen;
  1345. newlen = g_stacknleft * 2;
  1346. if (newlen < g_stacknleft)
  1347. ash_msg_and_raise_error(bb_msg_memory_exhausted);
  1348. if (newlen < 128)
  1349. newlen += 128;
  1350. if (g_stacknxt == g_stackp->space && g_stackp != &stackbase) {
  1351. struct stack_block *oldstackp;
  1352. struct stackmark *xmark;
  1353. struct stack_block *sp;
  1354. struct stack_block *prevstackp;
  1355. size_t grosslen;
  1356. INT_OFF;
  1357. oldstackp = g_stackp;
  1358. sp = g_stackp;
  1359. prevstackp = sp->prev;
  1360. grosslen = newlen + sizeof(struct stack_block) - MINSIZE;
  1361. sp = ckrealloc(sp, grosslen);
  1362. sp->prev = prevstackp;
  1363. g_stackp = sp;
  1364. g_stacknxt = sp->space;
  1365. g_stacknleft = newlen;
  1366. sstrend = sp->space + newlen;
  1367. /*
  1368. * Stack marks pointing to the start of the old block
  1369. * must be relocated to point to the new block
  1370. */
  1371. xmark = markp;
  1372. while (xmark != NULL && xmark->stackp == oldstackp) {
  1373. xmark->stackp = g_stackp;
  1374. xmark->stacknxt = g_stacknxt;
  1375. xmark->stacknleft = g_stacknleft;
  1376. xmark = xmark->marknext;
  1377. }
  1378. INT_ON;
  1379. } else {
  1380. char *oldspace = g_stacknxt;
  1381. size_t oldlen = g_stacknleft;
  1382. char *p = stalloc(newlen);
  1383. /* free the space we just allocated */
  1384. g_stacknxt = memcpy(p, oldspace, oldlen);
  1385. g_stacknleft += newlen;
  1386. }
  1387. }
  1388. static void
  1389. grabstackblock(size_t len)
  1390. {
  1391. len = SHELL_ALIGN(len);
  1392. g_stacknxt += len;
  1393. g_stacknleft -= len;
  1394. }
  1395. /*
  1396. * The following routines are somewhat easier to use than the above.
  1397. * The user declares a variable of type STACKSTR, which may be declared
  1398. * to be a register. The macro STARTSTACKSTR initializes things. Then
  1399. * the user uses the macro STPUTC to add characters to the string. In
  1400. * effect, STPUTC(c, p) is the same as *p++ = c except that the stack is
  1401. * grown as necessary. When the user is done, she can just leave the
  1402. * string there and refer to it using stackblock(). Or she can allocate
  1403. * the space for it using grabstackstr(). If it is necessary to allow
  1404. * someone else to use the stack temporarily and then continue to grow
  1405. * the string, the user should use grabstack to allocate the space, and
  1406. * then call ungrabstr(p) to return to the previous mode of operation.
  1407. *
  1408. * USTPUTC is like STPUTC except that it doesn't check for overflow.
  1409. * CHECKSTACKSPACE can be called before USTPUTC to ensure that there
  1410. * is space for at least one character.
  1411. */
  1412. static void *
  1413. growstackstr(void)
  1414. {
  1415. size_t len = stackblocksize();
  1416. if (herefd >= 0 && len >= 1024) {
  1417. full_write(herefd, stackblock(), len);
  1418. return stackblock();
  1419. }
  1420. growstackblock();
  1421. return (char *)stackblock() + len;
  1422. }
  1423. /*
  1424. * Called from CHECKSTRSPACE.
  1425. */
  1426. static char *
  1427. makestrspace(size_t newlen, char *p)
  1428. {
  1429. size_t len = p - g_stacknxt;
  1430. size_t size = stackblocksize();
  1431. for (;;) {
  1432. size_t nleft;
  1433. size = stackblocksize();
  1434. nleft = size - len;
  1435. if (nleft >= newlen)
  1436. break;
  1437. growstackblock();
  1438. }
  1439. return (char *)stackblock() + len;
  1440. }
  1441. static char *
  1442. stack_nputstr(const char *s, size_t n, char *p)
  1443. {
  1444. p = makestrspace(n, p);
  1445. p = (char *)memcpy(p, s, n) + n;
  1446. return p;
  1447. }
  1448. static char *
  1449. stack_putstr(const char *s, char *p)
  1450. {
  1451. return stack_nputstr(s, strlen(s), p);
  1452. }
  1453. static char *
  1454. _STPUTC(int c, char *p)
  1455. {
  1456. if (p == sstrend)
  1457. p = growstackstr();
  1458. *p++ = c;
  1459. return p;
  1460. }
  1461. #define STARTSTACKSTR(p) ((p) = stackblock())
  1462. #define STPUTC(c, p) ((p) = _STPUTC((c), (p)))
  1463. #define CHECKSTRSPACE(n, p) do { \
  1464. char *q = (p); \
  1465. size_t l = (n); \
  1466. size_t m = sstrend - q; \
  1467. if (l > m) \
  1468. (p) = makestrspace(l, q); \
  1469. } while (0)
  1470. #define USTPUTC(c, p) (*(p)++ = (c))
  1471. #define STACKSTRNUL(p) do { \
  1472. if ((p) == sstrend) \
  1473. (p) = growstackstr(); \
  1474. *(p) = '\0'; \
  1475. } while (0)
  1476. #define STUNPUTC(p) (--(p))
  1477. #define STTOPC(p) ((p)[-1])
  1478. #define STADJUST(amount, p) ((p) += (amount))
  1479. #define grabstackstr(p) stalloc((char *)(p) - (char *)stackblock())
  1480. #define ungrabstackstr(s, p) stunalloc(s)
  1481. #define stackstrend() ((void *)sstrend)
  1482. /* ============ String helpers */
  1483. /*
  1484. * prefix -- see if pfx is a prefix of string.
  1485. */
  1486. static char *
  1487. prefix(const char *string, const char *pfx)
  1488. {
  1489. while (*pfx) {
  1490. if (*pfx++ != *string++)
  1491. return NULL;
  1492. }
  1493. return (char *) string;
  1494. }
  1495. /*
  1496. * Check for a valid number. This should be elsewhere.
  1497. */
  1498. static int
  1499. is_number(const char *p)
  1500. {
  1501. do {
  1502. if (!isdigit(*p))
  1503. return 0;
  1504. } while (*++p != '\0');
  1505. return 1;
  1506. }
  1507. /*
  1508. * Convert a string of digits to an integer, printing an error message on
  1509. * failure.
  1510. */
  1511. static int
  1512. number(const char *s)
  1513. {
  1514. if (!is_number(s))
  1515. ash_msg_and_raise_error(msg_illnum, s);
  1516. return atoi(s);
  1517. }
  1518. /*
  1519. * Produce a possibly single quoted string suitable as input to the shell.
  1520. * The return string is allocated on the stack.
  1521. */
  1522. static char *
  1523. single_quote(const char *s)
  1524. {
  1525. char *p;
  1526. STARTSTACKSTR(p);
  1527. do {
  1528. char *q;
  1529. size_t len;
  1530. len = strchrnul(s, '\'') - s;
  1531. q = p = makestrspace(len + 3, p);
  1532. *q++ = '\'';
  1533. q = (char *)memcpy(q, s, len) + len;
  1534. *q++ = '\'';
  1535. s += len;
  1536. STADJUST(q - p, p);
  1537. if (*s != '\'')
  1538. break;
  1539. len = 0;
  1540. do len++; while (*++s == '\'');
  1541. q = p = makestrspace(len + 3, p);
  1542. *q++ = '"';
  1543. q = (char *)memcpy(q, s - len, len) + len;
  1544. *q++ = '"';
  1545. STADJUST(q - p, p);
  1546. } while (*s);
  1547. USTPUTC('\0', p);
  1548. return stackblock();
  1549. }
  1550. /* ============ nextopt */
  1551. static char **argptr; /* argument list for builtin commands */
  1552. static char *optionarg; /* set by nextopt (like getopt) */
  1553. static char *optptr; /* used by nextopt */
  1554. /*
  1555. * XXX - should get rid of. Have all builtins use getopt(3).
  1556. * The library getopt must have the BSD extension static variable
  1557. * "optreset", otherwise it can't be used within the shell safely.
  1558. *
  1559. * Standard option processing (a la getopt) for builtin routines.
  1560. * The only argument that is passed to nextopt is the option string;
  1561. * the other arguments are unnecessary. It returns the character,
  1562. * or '\0' on end of input.
  1563. */
  1564. static int
  1565. nextopt(const char *optstring)
  1566. {
  1567. char *p;
  1568. const char *q;
  1569. char c;
  1570. p = optptr;
  1571. if (p == NULL || *p == '\0') {
  1572. /* We ate entire "-param", take next one */
  1573. p = *argptr;
  1574. if (p == NULL)
  1575. return '\0';
  1576. if (*p != '-')
  1577. return '\0';
  1578. if (*++p == '\0') /* just "-" ? */
  1579. return '\0';
  1580. argptr++;
  1581. if (LONE_DASH(p)) /* "--" ? */
  1582. return '\0';
  1583. /* p => next "-param" */
  1584. }
  1585. /* p => some option char in the middle of a "-param" */
  1586. c = *p++;
  1587. for (q = optstring; *q != c;) {
  1588. if (*q == '\0')
  1589. ash_msg_and_raise_error("illegal option -%c", c);
  1590. if (*++q == ':')
  1591. q++;
  1592. }
  1593. if (*++q == ':') {
  1594. if (*p == '\0') {
  1595. p = *argptr++;
  1596. if (p == NULL)
  1597. ash_msg_and_raise_error("no arg for -%c option", c);
  1598. }
  1599. optionarg = p;
  1600. p = NULL;
  1601. }
  1602. optptr = p;
  1603. return c;
  1604. }
  1605. /* ============ Shell variables */
  1606. /*
  1607. * The parsefile structure pointed to by the global variable parsefile
  1608. * contains information about the current file being read.
  1609. */
  1610. struct shparam {
  1611. int nparam; /* # of positional parameters (without $0) */
  1612. #if ENABLE_ASH_GETOPTS
  1613. int optind; /* next parameter to be processed by getopts */
  1614. int optoff; /* used by getopts */
  1615. #endif
  1616. unsigned char malloced; /* if parameter list dynamically allocated */
  1617. char **p; /* parameter list */
  1618. };
  1619. /*
  1620. * Free the list of positional parameters.
  1621. */
  1622. static void
  1623. freeparam(volatile struct shparam *param)
  1624. {
  1625. if (param->malloced) {
  1626. char **ap, **ap1;
  1627. ap = ap1 = param->p;
  1628. while (*ap)
  1629. free(*ap++);
  1630. free(ap1);
  1631. }
  1632. }
  1633. #if ENABLE_ASH_GETOPTS
  1634. static void FAST_FUNC getoptsreset(const char *value);
  1635. #endif
  1636. struct var {
  1637. struct var *next; /* next entry in hash list */
  1638. int flags; /* flags are defined above */
  1639. const char *var_text; /* name=value */
  1640. void (*var_func)(const char *) FAST_FUNC; /* function to be called when */
  1641. /* the variable gets set/unset */
  1642. };
  1643. struct localvar {
  1644. struct localvar *next; /* next local variable in list */
  1645. struct var *vp; /* the variable that was made local */
  1646. int flags; /* saved flags */
  1647. const char *text; /* saved text */
  1648. };
  1649. /* flags */
  1650. #define VEXPORT 0x01 /* variable is exported */
  1651. #define VREADONLY 0x02 /* variable cannot be modified */
  1652. #define VSTRFIXED 0x04 /* variable struct is statically allocated */
  1653. #define VTEXTFIXED 0x08 /* text is statically allocated */
  1654. #define VSTACK 0x10 /* text is allocated on the stack */
  1655. #define VUNSET 0x20 /* the variable is not set */
  1656. #define VNOFUNC 0x40 /* don't call the callback function */
  1657. #define VNOSET 0x80 /* do not set variable - just readonly test */
  1658. #define VNOSAVE 0x100 /* when text is on the heap before setvareq */
  1659. #if ENABLE_ASH_RANDOM_SUPPORT
  1660. # define VDYNAMIC 0x200 /* dynamic variable */
  1661. #else
  1662. # define VDYNAMIC 0
  1663. #endif
  1664. /* Need to be before varinit_data[] */
  1665. #if ENABLE_LOCALE_SUPPORT
  1666. static void FAST_FUNC
  1667. change_lc_all(const char *value)
  1668. {
  1669. if (value && *value != '\0')
  1670. setlocale(LC_ALL, value);
  1671. }
  1672. static void FAST_FUNC
  1673. change_lc_ctype(const char *value)
  1674. {
  1675. if (value && *value != '\0')
  1676. setlocale(LC_CTYPE, value);
  1677. }
  1678. #endif
  1679. #if ENABLE_ASH_MAIL
  1680. static void chkmail(void);
  1681. static void changemail(const char *var_value) FAST_FUNC;
  1682. #else
  1683. # define chkmail() ((void)0)
  1684. #endif
  1685. static void changepath(const char *) FAST_FUNC;
  1686. #if ENABLE_ASH_RANDOM_SUPPORT
  1687. static void change_random(const char *) FAST_FUNC;
  1688. #endif
  1689. static const struct {
  1690. int flags;
  1691. const char *var_text;
  1692. void (*var_func)(const char *) FAST_FUNC;
  1693. } varinit_data[] = {
  1694. /*
  1695. * Note: VEXPORT would not work correctly here for NOFORK applets:
  1696. * some environment strings may be constant.
  1697. */
  1698. { VSTRFIXED|VTEXTFIXED , defifsvar , NULL },
  1699. #if ENABLE_ASH_MAIL
  1700. { VSTRFIXED|VTEXTFIXED|VUNSET, "MAIL" , changemail },
  1701. { VSTRFIXED|VTEXTFIXED|VUNSET, "MAILPATH" , changemail },
  1702. #endif
  1703. { VSTRFIXED|VTEXTFIXED , bb_PATH_root_path, changepath },
  1704. { VSTRFIXED|VTEXTFIXED , "PS1=$ " , NULL },
  1705. { VSTRFIXED|VTEXTFIXED , "PS2=> " , NULL },
  1706. { VSTRFIXED|VTEXTFIXED , "PS4=+ " , NULL },
  1707. #if ENABLE_ASH_GETOPTS
  1708. { VSTRFIXED|VTEXTFIXED , "OPTIND=1" , getoptsreset },
  1709. #endif
  1710. #if ENABLE_ASH_RANDOM_SUPPORT
  1711. { VSTRFIXED|VTEXTFIXED|VUNSET|VDYNAMIC, "RANDOM", change_random },
  1712. #endif
  1713. #if ENABLE_LOCALE_SUPPORT
  1714. { VSTRFIXED|VTEXTFIXED|VUNSET, "LC_ALL" , change_lc_all },
  1715. { VSTRFIXED|VTEXTFIXED|VUNSET, "LC_CTYPE" , change_lc_ctype },
  1716. #endif
  1717. #if ENABLE_FEATURE_EDITING_SAVEHISTORY
  1718. { VSTRFIXED|VTEXTFIXED|VUNSET, "HISTFILE" , NULL },
  1719. #endif
  1720. };
  1721. struct redirtab;
  1722. struct globals_var {
  1723. struct shparam shellparam; /* $@ current positional parameters */
  1724. struct redirtab *redirlist;
  1725. int g_nullredirs;
  1726. int preverrout_fd; /* save fd2 before print debug if xflag is set. */
  1727. struct var *vartab[VTABSIZE];
  1728. struct var varinit[ARRAY_SIZE(varinit_data)];
  1729. };
  1730. extern struct globals_var *const ash_ptr_to_globals_var;
  1731. #define G_var (*ash_ptr_to_globals_var)
  1732. #define shellparam (G_var.shellparam )
  1733. //#define redirlist (G_var.redirlist )
  1734. #define g_nullredirs (G_var.g_nullredirs )
  1735. #define preverrout_fd (G_var.preverrout_fd)
  1736. #define vartab (G_var.vartab )
  1737. #define varinit (G_var.varinit )
  1738. #define INIT_G_var() do { \
  1739. unsigned i; \
  1740. (*(struct globals_var**)&ash_ptr_to_globals_var) = xzalloc(sizeof(G_var)); \
  1741. barrier(); \
  1742. for (i = 0; i < ARRAY_SIZE(varinit_data); i++) { \
  1743. varinit[i].flags = varinit_data[i].flags; \
  1744. varinit[i].var_text = varinit_data[i].var_text; \
  1745. varinit[i].var_func = varinit_data[i].var_func; \
  1746. } \
  1747. } while (0)
  1748. #define vifs varinit[0]
  1749. #if ENABLE_ASH_MAIL
  1750. # define vmail (&vifs)[1]
  1751. # define vmpath (&vmail)[1]
  1752. # define vpath (&vmpath)[1]
  1753. #else
  1754. # define vpath (&vifs)[1]
  1755. #endif
  1756. #define vps1 (&vpath)[1]
  1757. #define vps2 (&vps1)[1]
  1758. #define vps4 (&vps2)[1]
  1759. #if ENABLE_ASH_GETOPTS
  1760. # define voptind (&vps4)[1]
  1761. # if ENABLE_ASH_RANDOM_SUPPORT
  1762. # define vrandom (&voptind)[1]
  1763. # endif
  1764. #else
  1765. # if ENABLE_ASH_RANDOM_SUPPORT
  1766. # define vrandom (&vps4)[1]
  1767. # endif
  1768. #endif
  1769. /*
  1770. * The following macros access the values of the above variables.
  1771. * They have to skip over the name. They return the null string
  1772. * for unset variables.
  1773. */
  1774. #define ifsval() (vifs.var_text + 4)
  1775. #define ifsset() ((vifs.flags & VUNSET) == 0)
  1776. #if ENABLE_ASH_MAIL
  1777. # define mailval() (vmail.var_text + 5)
  1778. # define mpathval() (vmpath.var_text + 9)
  1779. # define mpathset() ((vmpath.flags & VUNSET) == 0)
  1780. #endif
  1781. #define pathval() (vpath.var_text + 5)
  1782. #define ps1val() (vps1.var_text + 4)
  1783. #define ps2val() (vps2.var_text + 4)
  1784. #define ps4val() (vps4.var_text + 4)
  1785. #if ENABLE_ASH_GETOPTS
  1786. # define optindval() (voptind.var_text + 7)
  1787. #endif
  1788. #if ENABLE_ASH_GETOPTS
  1789. static void FAST_FUNC
  1790. getoptsreset(const char *value)
  1791. {
  1792. shellparam.optind = number(value);
  1793. shellparam.optoff = -1;
  1794. }
  1795. #endif
  1796. /*
  1797. * Compares two strings up to the first = or '\0'. The first
  1798. * string must be terminated by '='; the second may be terminated by
  1799. * either '=' or '\0'.
  1800. */
  1801. static int
  1802. varcmp(const char *p, const char *q)
  1803. {
  1804. int c, d;
  1805. while ((c = *p) == (d = *q)) {
  1806. if (!c || c == '=')
  1807. goto out;
  1808. p++;
  1809. q++;
  1810. }
  1811. if (c == '=')
  1812. c = '\0';
  1813. if (d == '=')
  1814. d = '\0';
  1815. out:
  1816. return c - d;
  1817. }
  1818. /*
  1819. * Find the appropriate entry in the hash table from the name.
  1820. */
  1821. static struct var **
  1822. hashvar(const char *p)
  1823. {
  1824. unsigned hashval;
  1825. hashval = ((unsigned char) *p) << 4;
  1826. while (*p && *p != '=')
  1827. hashval += (unsigned char) *p++;
  1828. return &vartab[hashval % VTABSIZE];
  1829. }
  1830. static int
  1831. vpcmp(const void *a, const void *b)
  1832. {
  1833. return varcmp(*(const char **)a, *(const char **)b);
  1834. }
  1835. /*
  1836. * This routine initializes the builtin variables.
  1837. */
  1838. static void
  1839. initvar(void)
  1840. {
  1841. struct var *vp;
  1842. struct var *end;
  1843. struct var **vpp;
  1844. /*
  1845. * PS1 depends on uid
  1846. */
  1847. #if ENABLE_FEATURE_EDITING && ENABLE_FEATURE_EDITING_FANCY_PROMPT
  1848. vps1.var_text = "PS1=\\w \\$ ";
  1849. #else
  1850. if (!geteuid())
  1851. vps1.var_text = "PS1=# ";
  1852. #endif
  1853. vp = varinit;
  1854. end = vp + ARRAY_SIZE(varinit);
  1855. do {
  1856. vpp = hashvar(vp->var_text);
  1857. vp->next = *vpp;
  1858. *vpp = vp;
  1859. } while (++vp < end);
  1860. }
  1861. static struct var **
  1862. findvar(struct var **vpp, const char *name)
  1863. {
  1864. for (; *vpp; vpp = &(*vpp)->next) {
  1865. if (varcmp((*vpp)->var_text, name) == 0) {
  1866. break;
  1867. }
  1868. }
  1869. return vpp;
  1870. }
  1871. /*
  1872. * Find the value of a variable. Returns NULL if not set.
  1873. */
  1874. static const char* FAST_FUNC
  1875. lookupvar(const char *name)
  1876. {
  1877. struct var *v;
  1878. v = *findvar(hashvar(name), name);
  1879. if (v) {
  1880. #if ENABLE_ASH_RANDOM_SUPPORT
  1881. /*
  1882. * Dynamic variables are implemented roughly the same way they are
  1883. * in bash. Namely, they're "special" so long as they aren't unset.
  1884. * As soon as they're unset, they're no longer dynamic, and dynamic
  1885. * lookup will no longer happen at that point. -- PFM.
  1886. */
  1887. if (v->flags & VDYNAMIC)
  1888. v->var_func(NULL);
  1889. #endif
  1890. if (!(v->flags & VUNSET))
  1891. return var_end(v->var_text);
  1892. }
  1893. return NULL;
  1894. }
  1895. /*
  1896. * Search the environment of a builtin command.
  1897. */
  1898. static const char *
  1899. bltinlookup(const char *name)
  1900. {
  1901. struct strlist *sp;
  1902. for (sp = cmdenviron; sp; sp = sp->next) {
  1903. if (varcmp(sp->text, name) == 0)
  1904. return var_end(sp->text);
  1905. }
  1906. return lookupvar(name);
  1907. }
  1908. /*
  1909. * Same as setvar except that the variable and value are passed in
  1910. * the first argument as name=value. Since the first argument will
  1911. * be actually stored in the table, it should not be a string that
  1912. * will go away.
  1913. * Called with interrupts off.
  1914. */
  1915. static void
  1916. setvareq(char *s, int flags)
  1917. {
  1918. struct var *vp, **vpp;
  1919. vpp = hashvar(s);
  1920. flags |= (VEXPORT & (((unsigned) (1 - aflag)) - 1));
  1921. vp = *findvar(vpp, s);
  1922. if (vp) {
  1923. if ((vp->flags & (VREADONLY|VDYNAMIC)) == VREADONLY) {
  1924. const char *n;
  1925. if (flags & VNOSAVE)
  1926. free(s);
  1927. n = vp->var_text;
  1928. ash_msg_and_raise_error("%.*s: is read only", strchrnul(n, '=') - n, n);
  1929. }
  1930. if (flags & VNOSET)
  1931. return;
  1932. if (vp->var_func && !(flags & VNOFUNC))
  1933. vp->var_func(var_end(s));
  1934. if (!(vp->flags & (VTEXTFIXED|VSTACK)))
  1935. free((char*)vp->var_text);
  1936. flags |= vp->flags & ~(VTEXTFIXED|VSTACK|VNOSAVE|VUNSET);
  1937. } else {
  1938. /* variable s is not found */
  1939. if (flags & VNOSET)
  1940. return;
  1941. vp = ckzalloc(sizeof(*vp));
  1942. vp->next = *vpp;
  1943. /*vp->func = NULL; - ckzalloc did it */
  1944. *vpp = vp;
  1945. }
  1946. if (!(flags & (VTEXTFIXED|VSTACK|VNOSAVE)))
  1947. s = ckstrdup(s);
  1948. vp->var_text = s;
  1949. vp->flags = flags;
  1950. }
  1951. /*
  1952. * Set the value of a variable. The flags argument is ored with the
  1953. * flags of the variable. If val is NULL, the variable is unset.
  1954. */
  1955. static void
  1956. setvar(const char *name, const char *val, int flags)
  1957. {
  1958. const char *q;
  1959. char *p;
  1960. char *nameeq;
  1961. size_t namelen;
  1962. size_t vallen;
  1963. q = endofname(name);
  1964. p = strchrnul(q, '=');
  1965. namelen = p - name;
  1966. if (!namelen || p != q)
  1967. ash_msg_and_raise_error("%.*s: bad variable name", namelen, name);
  1968. vallen = 0;
  1969. if (val == NULL) {
  1970. flags |= VUNSET;
  1971. } else {
  1972. vallen = strlen(val);
  1973. }
  1974. INT_OFF;
  1975. nameeq = ckmalloc(namelen + vallen + 2);
  1976. p = memcpy(nameeq, name, namelen) + namelen;
  1977. if (val) {
  1978. *p++ = '=';
  1979. p = memcpy(p, val, vallen) + vallen;
  1980. }
  1981. *p = '\0';
  1982. setvareq(nameeq, flags | VNOSAVE);
  1983. INT_ON;
  1984. }
  1985. static void FAST_FUNC
  1986. setvar2(const char *name, const char *val)
  1987. {
  1988. setvar(name, val, 0);
  1989. }
  1990. #if ENABLE_ASH_GETOPTS
  1991. /*
  1992. * Safe version of setvar, returns 1 on success 0 on failure.
  1993. */
  1994. static int
  1995. setvarsafe(const char *name, const char *val, int flags)
  1996. {
  1997. int err;
  1998. volatile int saveint;
  1999. struct jmploc *volatile savehandler = exception_handler;
  2000. struct jmploc jmploc;
  2001. SAVE_INT(saveint);
  2002. if (setjmp(jmploc.loc))
  2003. err = 1;
  2004. else {
  2005. exception_handler = &jmploc;
  2006. setvar(name, val, flags);
  2007. err = 0;
  2008. }
  2009. exception_handler = savehandler;
  2010. RESTORE_INT(saveint);
  2011. return err;
  2012. }
  2013. #endif
  2014. /*
  2015. * Unset the specified variable.
  2016. */
  2017. static int
  2018. unsetvar(const char *s)
  2019. {
  2020. struct var **vpp;
  2021. struct var *vp;
  2022. int retval;
  2023. vpp = findvar(hashvar(s), s);
  2024. vp = *vpp;
  2025. retval = 2;
  2026. if (vp) {
  2027. int flags = vp->flags;
  2028. retval = 1;
  2029. if (flags & VREADONLY)
  2030. goto out;
  2031. #if ENABLE_ASH_RANDOM_SUPPORT
  2032. vp->flags &= ~VDYNAMIC;
  2033. #endif
  2034. if (flags & VUNSET)
  2035. goto ok;
  2036. if ((flags & VSTRFIXED) == 0) {
  2037. INT_OFF;
  2038. if ((flags & (VTEXTFIXED|VSTACK)) == 0)
  2039. free((char*)vp->var_text);
  2040. *vpp = vp->next;
  2041. free(vp);
  2042. INT_ON;
  2043. } else {
  2044. setvar2(s, 0);
  2045. vp->flags &= ~VEXPORT;
  2046. }
  2047. ok:
  2048. retval = 0;
  2049. }
  2050. out:
  2051. return retval;
  2052. }
  2053. /*
  2054. * Process a linked list of variable assignments.
  2055. */
  2056. static void
  2057. listsetvar(struct strlist *list_set_var, int flags)
  2058. {
  2059. struct strlist *lp = list_set_var;
  2060. if (!lp)
  2061. return;
  2062. INT_OFF;
  2063. do {
  2064. setvareq(lp->text, flags);
  2065. lp = lp->next;
  2066. } while (lp);
  2067. INT_ON;
  2068. }
  2069. /*
  2070. * Generate a list of variables satisfying the given conditions.
  2071. */
  2072. static char **
  2073. listvars(int on, int off, char ***end)
  2074. {
  2075. struct var **vpp;
  2076. struct var *vp;
  2077. char **ep;
  2078. int mask;
  2079. STARTSTACKSTR(ep);
  2080. vpp = vartab;
  2081. mask = on | off;
  2082. do {
  2083. for (vp = *vpp; vp; vp = vp->next) {
  2084. if ((vp->flags & mask) == on) {
  2085. if (ep == stackstrend())
  2086. ep = growstackstr();
  2087. *ep++ = (char*)vp->var_text;
  2088. }
  2089. }
  2090. } while (++vpp < vartab + VTABSIZE);
  2091. if (ep == stackstrend())
  2092. ep = growstackstr();
  2093. if (end)
  2094. *end = ep;
  2095. *ep++ = NULL;
  2096. return grabstackstr(ep);
  2097. }
  2098. /* ============ Path search helper
  2099. *
  2100. * The variable path (passed by reference) should be set to the start
  2101. * of the path before the first call; path_advance will update
  2102. * this value as it proceeds. Successive calls to path_advance will return
  2103. * the possible path expansions in sequence. If an option (indicated by
  2104. * a percent sign) appears in the path entry then the global variable
  2105. * pathopt will be set to point to it; otherwise pathopt will be set to
  2106. * NULL.
  2107. */
  2108. static const char *pathopt; /* set by path_advance */
  2109. static char *
  2110. path_advance(const char **path, const char *name)
  2111. {
  2112. const char *p;
  2113. char *q;
  2114. const char *start;
  2115. size_t len;
  2116. if (*path == NULL)
  2117. return NULL;
  2118. start = *path;
  2119. for (p = start; *p && *p != ':' && *p != '%'; p++)
  2120. continue;
  2121. len = p - start + strlen(name) + 2; /* "2" is for '/' and '\0' */
  2122. while (stackblocksize() < len)
  2123. growstackblock();
  2124. q = stackblock();
  2125. if (p != start) {
  2126. memcpy(q, start, p - start);
  2127. q += p - start;
  2128. *q++ = '/';
  2129. }
  2130. strcpy(q, name);
  2131. pathopt = NULL;
  2132. if (*p == '%') {
  2133. pathopt = ++p;
  2134. while (*p && *p != ':')
  2135. p++;
  2136. }
  2137. if (*p == ':')
  2138. *path = p + 1;
  2139. else
  2140. *path = NULL;
  2141. return stalloc(len);
  2142. }
  2143. /* ============ Prompt */
  2144. static smallint doprompt; /* if set, prompt the user */
  2145. static smallint needprompt; /* true if interactive and at start of line */
  2146. #if ENABLE_FEATURE_EDITING
  2147. static line_input_t *line_input_state;
  2148. static const char *cmdedit_prompt;
  2149. static void
  2150. putprompt(const char *s)
  2151. {
  2152. if (ENABLE_ASH_EXPAND_PRMT) {
  2153. free((char*)cmdedit_prompt);
  2154. cmdedit_prompt = ckstrdup(s);
  2155. return;
  2156. }
  2157. cmdedit_prompt = s;
  2158. }
  2159. #else
  2160. static void
  2161. putprompt(const char *s)
  2162. {
  2163. out2str(s);
  2164. }
  2165. #endif
  2166. #if ENABLE_ASH_EXPAND_PRMT
  2167. /* expandstr() needs parsing machinery, so it is far away ahead... */
  2168. static const char *expandstr(const char *ps);
  2169. #else
  2170. #define expandstr(s) s
  2171. #endif
  2172. static void
  2173. setprompt_if(smallint do_set, int whichprompt)
  2174. {
  2175. const char *prompt;
  2176. IF_ASH_EXPAND_PRMT(struct stackmark smark;)
  2177. if (!do_set)
  2178. return;
  2179. needprompt = 0;
  2180. switch (whichprompt) {
  2181. case 1:
  2182. prompt = ps1val();
  2183. break;
  2184. case 2:
  2185. prompt = ps2val();
  2186. break;
  2187. default: /* 0 */
  2188. prompt = nullstr;
  2189. }
  2190. #if ENABLE_ASH_EXPAND_PRMT
  2191. setstackmark(&smark);
  2192. stalloc(stackblocksize());
  2193. #endif
  2194. putprompt(expandstr(prompt));
  2195. #if ENABLE_ASH_EXPAND_PRMT
  2196. popstackmark(&smark);
  2197. #endif
  2198. }
  2199. /* ============ The cd and pwd commands */
  2200. #define CD_PHYSICAL 1
  2201. #define CD_PRINT 2
  2202. static int
  2203. cdopt(void)
  2204. {
  2205. int flags = 0;
  2206. int i, j;
  2207. j = 'L';
  2208. while ((i = nextopt("LP")) != '\0') {
  2209. if (i != j) {
  2210. flags ^= CD_PHYSICAL;
  2211. j = i;
  2212. }
  2213. }
  2214. return flags;
  2215. }
  2216. /*
  2217. * Update curdir (the name of the current directory) in response to a
  2218. * cd command.
  2219. */
  2220. static const char *
  2221. updatepwd(const char *dir)
  2222. {
  2223. char *new;
  2224. char *p;
  2225. char *cdcomppath;
  2226. const char *lim;
  2227. cdcomppath = ststrdup(dir);
  2228. STARTSTACKSTR(new);
  2229. if (*dir != '/') {
  2230. if (curdir == nullstr)
  2231. return 0;
  2232. new = stack_putstr(curdir, new);
  2233. }
  2234. new = makestrspace(strlen(dir) + 2, new);
  2235. lim = (char *)stackblock() + 1;
  2236. if (*dir != '/') {
  2237. if (new[-1] != '/')
  2238. USTPUTC('/', new);
  2239. if (new > lim && *lim == '/')
  2240. lim++;
  2241. } else {
  2242. USTPUTC('/', new);
  2243. cdcomppath++;
  2244. if (dir[1] == '/' && dir[2] != '/') {
  2245. USTPUTC('/', new);
  2246. cdcomppath++;
  2247. lim++;
  2248. }
  2249. }
  2250. p = strtok(cdcomppath, "/");
  2251. while (p) {
  2252. switch (*p) {
  2253. case '.':
  2254. if (p[1] == '.' && p[2] == '\0') {
  2255. while (new > lim) {
  2256. STUNPUTC(new);
  2257. if (new[-1] == '/')
  2258. break;
  2259. }
  2260. break;
  2261. }
  2262. if (p[1] == '\0')
  2263. break;
  2264. /* fall through */
  2265. default:
  2266. new = stack_putstr(p, new);
  2267. USTPUTC('/', new);
  2268. }
  2269. p = strtok(0, "/");
  2270. }
  2271. if (new > lim)
  2272. STUNPUTC(new);
  2273. *new = 0;
  2274. return stackblock();
  2275. }
  2276. /*
  2277. * Find out what the current directory is. If we already know the current
  2278. * directory, this routine returns immediately.
  2279. */
  2280. static char *
  2281. getpwd(void)
  2282. {
  2283. char *dir = getcwd(NULL, 0); /* huh, using glibc extension? */
  2284. return dir ? dir : nullstr;
  2285. }
  2286. static void
  2287. setpwd(const char *val, int setold)
  2288. {
  2289. char *oldcur, *dir;
  2290. oldcur = dir = curdir;
  2291. if (setold) {
  2292. setvar("OLDPWD", oldcur, VEXPORT);
  2293. }
  2294. INT_OFF;
  2295. if (physdir != nullstr) {
  2296. if (physdir != oldcur)
  2297. free(physdir);
  2298. physdir = nullstr;
  2299. }
  2300. if (oldcur == val || !val) {
  2301. char *s = getpwd();
  2302. physdir = s;
  2303. if (!val)
  2304. dir = s;
  2305. } else
  2306. dir = ckstrdup(val);
  2307. if (oldcur != dir && oldcur != nullstr) {
  2308. free(oldcur);
  2309. }
  2310. curdir = dir;
  2311. INT_ON;
  2312. setvar("PWD", dir, VEXPORT);
  2313. }
  2314. static void hashcd(void);
  2315. /*
  2316. * Actually do the chdir. We also call hashcd to let the routines in exec.c
  2317. * know that the current directory has changed.
  2318. */
  2319. static int
  2320. docd(const char *dest, int flags)
  2321. {
  2322. const char *dir = NULL;
  2323. int err;
  2324. TRACE(("docd(\"%s\", %d) called\n", dest, flags));
  2325. INT_OFF;
  2326. if (!(flags & CD_PHYSICAL)) {
  2327. dir = updatepwd(dest);
  2328. if (dir)
  2329. dest = dir;
  2330. }
  2331. err = chdir(dest);
  2332. if (err)
  2333. goto out;
  2334. setpwd(dir, 1);
  2335. hashcd();
  2336. out:
  2337. INT_ON;
  2338. return err;
  2339. }
  2340. static int FAST_FUNC
  2341. cdcmd(int argc UNUSED_PARAM, char **argv UNUSED_PARAM)
  2342. {
  2343. const char *dest;
  2344. const char *path;
  2345. const char *p;
  2346. char c;
  2347. struct stat statb;
  2348. int flags;
  2349. flags = cdopt();
  2350. dest = *argptr;
  2351. if (!dest)
  2352. dest = bltinlookup("HOME");
  2353. else if (LONE_DASH(dest)) {
  2354. dest = bltinlookup("OLDPWD");
  2355. flags |= CD_PRINT;
  2356. }
  2357. if (!dest)
  2358. dest = nullstr;
  2359. if (*dest == '/')
  2360. goto step7;
  2361. if (*dest == '.') {
  2362. c = dest[1];
  2363. dotdot:
  2364. switch (c) {
  2365. case '\0':
  2366. case '/':
  2367. goto step6;
  2368. case '.':
  2369. c = dest[2];
  2370. if (c != '.')
  2371. goto dotdot;
  2372. }
  2373. }
  2374. if (!*dest)
  2375. dest = ".";
  2376. path = bltinlookup("CDPATH");
  2377. if (!path) {
  2378. step6:
  2379. step7:
  2380. p = dest;
  2381. goto docd;
  2382. }
  2383. do {
  2384. c = *path;
  2385. p = path_advance(&path, dest);
  2386. if (stat(p, &statb) >= 0 && S_ISDIR(statb.st_mode)) {
  2387. if (c && c != ':')
  2388. flags |= CD_PRINT;
  2389. docd:
  2390. if (!docd(p, flags))
  2391. goto out;
  2392. break;
  2393. }
  2394. } while (path);
  2395. ash_msg_and_raise_error("can't cd to %s", dest);
  2396. /* NOTREACHED */
  2397. out:
  2398. if (flags & CD_PRINT)
  2399. out1fmt("%s\n", curdir);
  2400. return 0;
  2401. }
  2402. static int FAST_FUNC
  2403. pwdcmd(int argc UNUSED_PARAM, char **argv UNUSED_PARAM)
  2404. {
  2405. int flags;
  2406. const char *dir = curdir;
  2407. flags = cdopt();
  2408. if (flags) {
  2409. if (physdir == nullstr)
  2410. setpwd(dir, 0);
  2411. dir = physdir;
  2412. }
  2413. out1fmt("%s\n", dir);
  2414. return 0;
  2415. }
  2416. /* ============ ... */
  2417. #define IBUFSIZ (ENABLE_FEATURE_EDITING ? CONFIG_FEATURE_EDITING_MAX_LEN : 1024)
  2418. /* Syntax classes */
  2419. #define CWORD 0 /* character is nothing special */
  2420. #define CNL 1 /* newline character */
  2421. #define CBACK 2 /* a backslash character */
  2422. #define CSQUOTE 3 /* single quote */
  2423. #define CDQUOTE 4 /* double quote */
  2424. #define CENDQUOTE 5 /* a terminating quote */
  2425. #define CBQUOTE 6 /* backwards single quote */
  2426. #define CVAR 7 /* a dollar sign */
  2427. #define CENDVAR 8 /* a '}' character */
  2428. #define CLP 9 /* a left paren in arithmetic */
  2429. #define CRP 10 /* a right paren in arithmetic */
  2430. #define CENDFILE 11 /* end of file */
  2431. #define CCTL 12 /* like CWORD, except it must be escaped */
  2432. #define CSPCL 13 /* these terminate a word */
  2433. #define CIGN 14 /* character should be ignored */
  2434. #define PEOF 256
  2435. #if ENABLE_ASH_ALIAS
  2436. # define PEOA 257
  2437. #endif
  2438. #define USE_SIT_FUNCTION ENABLE_ASH_OPTIMIZE_FOR_SIZE
  2439. #if ENABLE_SH_MATH_SUPPORT
  2440. # define SIT_ITEM(a,b,c,d) (a | (b << 4) | (c << 8) | (d << 12))
  2441. #else
  2442. # define SIT_ITEM(a,b,c,d) (a | (b << 4) | (c << 8))
  2443. #endif
  2444. static const uint16_t S_I_T[] = {
  2445. #if ENABLE_ASH_ALIAS
  2446. SIT_ITEM(CSPCL , CIGN , CIGN , CIGN ), /* 0, PEOA */
  2447. #endif
  2448. SIT_ITEM(CSPCL , CWORD , CWORD, CWORD ), /* 1, ' ' */
  2449. SIT_ITEM(CNL , CNL , CNL , CNL ), /* 2, \n */
  2450. SIT_ITEM(CWORD , CCTL , CCTL , CWORD ), /* 3, !*-/:=?[]~ */
  2451. SIT_ITEM(CDQUOTE , CENDQUOTE, CWORD, CWORD ), /* 4, '"' */
  2452. SIT_ITEM(CVAR , CVAR , CWORD, CVAR ), /* 5, $ */
  2453. SIT_ITEM(CSQUOTE , CWORD , CENDQUOTE, CWORD), /* 6, "'" */
  2454. SIT_ITEM(CSPCL , CWORD , CWORD, CLP ), /* 7, ( */
  2455. SIT_ITEM(CSPCL , CWORD , CWORD, CRP ), /* 8, ) */
  2456. SIT_ITEM(CBACK , CBACK , CCTL , CBACK ), /* 9, \ */
  2457. SIT_ITEM(CBQUOTE , CBQUOTE , CWORD, CBQUOTE), /* 10, ` */
  2458. SIT_ITEM(CENDVAR , CENDVAR , CWORD, CENDVAR), /* 11, } */
  2459. #if !USE_SIT_FUNCTION
  2460. SIT_ITEM(CENDFILE, CENDFILE , CENDFILE, CENDFILE),/* 12, PEOF */
  2461. SIT_ITEM(CWORD , CWORD , CWORD, CWORD ), /* 13, 0-9A-Za-z */
  2462. SIT_ITEM(CCTL , CCTL , CCTL , CCTL ) /* 14, CTLESC ... */
  2463. #endif
  2464. #undef SIT_ITEM
  2465. };
  2466. /* Constants below must match table above */
  2467. enum {
  2468. #if ENABLE_ASH_ALIAS
  2469. CSPCL_CIGN_CIGN_CIGN , /* 0 */
  2470. #endif
  2471. CSPCL_CWORD_CWORD_CWORD , /* 1 */
  2472. CNL_CNL_CNL_CNL , /* 2 */
  2473. CWORD_CCTL_CCTL_CWORD , /* 3 */
  2474. CDQUOTE_CENDQUOTE_CWORD_CWORD , /* 4 */
  2475. CVAR_CVAR_CWORD_CVAR , /* 5 */
  2476. CSQUOTE_CWORD_CENDQUOTE_CWORD , /* 6 */
  2477. CSPCL_CWORD_CWORD_CLP , /* 7 */
  2478. CSPCL_CWORD_CWORD_CRP , /* 8 */
  2479. CBACK_CBACK_CCTL_CBACK , /* 9 */
  2480. CBQUOTE_CBQUOTE_CWORD_CBQUOTE , /* 10 */
  2481. CENDVAR_CENDVAR_CWORD_CENDVAR , /* 11 */
  2482. CENDFILE_CENDFILE_CENDFILE_CENDFILE, /* 12 */
  2483. CWORD_CWORD_CWORD_CWORD , /* 13 */
  2484. CCTL_CCTL_CCTL_CCTL , /* 14 */
  2485. };
  2486. /* c in SIT(c, syntax) must be an *unsigned char* or PEOA or PEOF,
  2487. * caller must ensure proper cast on it if c is *char_ptr!
  2488. */
  2489. /* Values for syntax param */
  2490. #define BASESYNTAX 0 /* not in quotes */
  2491. #define DQSYNTAX 1 /* in double quotes */
  2492. #define SQSYNTAX 2 /* in single quotes */
  2493. #define ARISYNTAX 3 /* in arithmetic */
  2494. #define PSSYNTAX 4 /* prompt. never passed to SIT() */
  2495. #if USE_SIT_FUNCTION
  2496. static int
  2497. SIT(int c, int syntax)
  2498. {
  2499. static const char spec_symbls[] ALIGN1 = "\t\n !\"$&'()*-/:;<=>?[\\]`|}~";
  2500. # if ENABLE_ASH_ALIAS
  2501. static const uint8_t syntax_index_table[] ALIGN1 = {
  2502. 1, 2, 1, 3, 4, 5, 1, 6, /* "\t\n !\"$&'" */
  2503. 7, 8, 3, 3, 3, 3, 1, 1, /* "()*-/:;<" */
  2504. 3, 1, 3, 3, 9, 3, 10, 1, /* "=>?[\\]`|" */
  2505. 11, 3 /* "}~" */
  2506. };
  2507. # else
  2508. static const uint8_t syntax_index_table[] ALIGN1 = {
  2509. 0, 1, 0, 2, 3, 4, 0, 5, /* "\t\n !\"$&'" */
  2510. 6, 7, 2, 2, 2, 2, 0, 0, /* "()*-/:;<" */
  2511. 2, 0, 2, 2, 8, 2, 9, 0, /* "=>?[\\]`|" */
  2512. 10, 2 /* "}~" */
  2513. };
  2514. # endif
  2515. const char *s;
  2516. int indx;
  2517. if (c == PEOF)
  2518. return CENDFILE;
  2519. # if ENABLE_ASH_ALIAS
  2520. if (c == PEOA)
  2521. indx = 0;
  2522. else
  2523. # endif
  2524. {
  2525. /* Cast is purely for paranoia here,
  2526. * just in case someone passed signed char to us */
  2527. if ((unsigned char)c >= CTL_FIRST
  2528. && (unsigned char)c <= CTL_LAST
  2529. ) {
  2530. return CCTL;
  2531. }
  2532. s = strchrnul(spec_symbls, c);
  2533. if (*s == '\0')
  2534. return CWORD;
  2535. indx = syntax_index_table[s - spec_symbls];
  2536. }
  2537. return (S_I_T[indx] >> (syntax*4)) & 0xf;
  2538. }
  2539. #else /* !USE_SIT_FUNCTION */
  2540. static const uint8_t syntax_index_table[] = {
  2541. /* BASESYNTAX_DQSYNTAX_SQSYNTAX_ARISYNTAX */
  2542. /* 0 */ CWORD_CWORD_CWORD_CWORD,
  2543. /* 1 */ CWORD_CWORD_CWORD_CWORD,
  2544. /* 2 */ CWORD_CWORD_CWORD_CWORD,
  2545. /* 3 */ CWORD_CWORD_CWORD_CWORD,
  2546. /* 4 */ CWORD_CWORD_CWORD_CWORD,
  2547. /* 5 */ CWORD_CWORD_CWORD_CWORD,
  2548. /* 6 */ CWORD_CWORD_CWORD_CWORD,
  2549. /* 7 */ CWORD_CWORD_CWORD_CWORD,
  2550. /* 8 */ CWORD_CWORD_CWORD_CWORD,
  2551. /* 9 "\t" */ CSPCL_CWORD_CWORD_CWORD,
  2552. /* 10 "\n" */ CNL_CNL_CNL_CNL,
  2553. /* 11 */ CWORD_CWORD_CWORD_CWORD,
  2554. /* 12 */ CWORD_CWORD_CWORD_CWORD,
  2555. /* 13 */ CWORD_CWORD_CWORD_CWORD,
  2556. /* 14 */ CWORD_CWORD_CWORD_CWORD,
  2557. /* 15 */ CWORD_CWORD_CWORD_CWORD,
  2558. /* 16 */ CWORD_CWORD_CWORD_CWORD,
  2559. /* 17 */ CWORD_CWORD_CWORD_CWORD,
  2560. /* 18 */ CWORD_CWORD_CWORD_CWORD,
  2561. /* 19 */ CWORD_CWORD_CWORD_CWORD,
  2562. /* 20 */ CWORD_CWORD_CWORD_CWORD,
  2563. /* 21 */ CWORD_CWORD_CWORD_CWORD,
  2564. /* 22 */ CWORD_CWORD_CWORD_CWORD,
  2565. /* 23 */ CWORD_CWORD_CWORD_CWORD,
  2566. /* 24 */ CWORD_CWORD_CWORD_CWORD,
  2567. /* 25 */ CWORD_CWORD_CWORD_CWORD,
  2568. /* 26 */ CWORD_CWORD_CWORD_CWORD,
  2569. /* 27 */ CWORD_CWORD_CWORD_CWORD,
  2570. /* 28 */ CWORD_CWORD_CWORD_CWORD,
  2571. /* 29 */ CWORD_CWORD_CWORD_CWORD,
  2572. /* 30 */ CWORD_CWORD_CWORD_CWORD,
  2573. /* 31 */ CWORD_CWORD_CWORD_CWORD,
  2574. /* 32 " " */ CSPCL_CWORD_CWORD_CWORD,
  2575. /* 33 "!" */ CWORD_CCTL_CCTL_CWORD,
  2576. /* 34 """ */ CDQUOTE_CENDQUOTE_CWORD_CWORD,
  2577. /* 35 "#" */ CWORD_CWORD_CWORD_CWORD,
  2578. /* 36 "$" */ CVAR_CVAR_CWORD_CVAR,
  2579. /* 37 "%" */ CWORD_CWORD_CWORD_CWORD,
  2580. /* 38 "&" */ CSPCL_CWORD_CWORD_CWORD,
  2581. /* 39 "'" */ CSQUOTE_CWORD_CENDQUOTE_CWORD,
  2582. /* 40 "(" */ CSPCL_CWORD_CWORD_CLP,
  2583. /* 41 ")" */ CSPCL_CWORD_CWORD_CRP,
  2584. /* 42 "*" */ CWORD_CCTL_CCTL_CWORD,
  2585. /* 43 "+" */ CWORD_CWORD_CWORD_CWORD,
  2586. /* 44 "," */ CWORD_CWORD_CWORD_CWORD,
  2587. /* 45 "-" */ CWORD_CCTL_CCTL_CWORD,
  2588. /* 46 "." */ CWORD_CWORD_CWORD_CWORD,
  2589. /* 47 "/" */ CWORD_CCTL_CCTL_CWORD,
  2590. /* 48 "0" */ CWORD_CWORD_CWORD_CWORD,
  2591. /* 49 "1" */ CWORD_CWORD_CWORD_CWORD,
  2592. /* 50 "2" */ CWORD_CWORD_CWORD_CWORD,
  2593. /* 51 "3" */ CWORD_CWORD_CWORD_CWORD,
  2594. /* 52 "4" */ CWORD_CWORD_CWORD_CWORD,
  2595. /* 53 "5" */ CWORD_CWORD_CWORD_CWORD,
  2596. /* 54 "6" */ CWORD_CWORD_CWORD_CWORD,
  2597. /* 55 "7" */ CWORD_CWORD_CWORD_CWORD,
  2598. /* 56 "8" */ CWORD_CWORD_CWORD_CWORD,
  2599. /* 57 "9" */ CWORD_CWORD_CWORD_CWORD,
  2600. /* 58 ":" */ CWORD_CCTL_CCTL_CWORD,
  2601. /* 59 ";" */ CSPCL_CWORD_CWORD_CWORD,
  2602. /* 60 "<" */ CSPCL_CWORD_CWORD_CWORD,
  2603. /* 61 "=" */ CWORD_CCTL_CCTL_CWORD,
  2604. /* 62 ">" */ CSPCL_CWORD_CWORD_CWORD,
  2605. /* 63 "?" */ CWORD_CCTL_CCTL_CWORD,
  2606. /* 64 "@" */ CWORD_CWORD_CWORD_CWORD,
  2607. /* 65 "A" */ CWORD_CWORD_CWORD_CWORD,
  2608. /* 66 "B" */ CWORD_CWORD_CWORD_CWORD,
  2609. /* 67 "C" */ CWORD_CWORD_CWORD_CWORD,
  2610. /* 68 "D" */ CWORD_CWORD_CWORD_CWORD,
  2611. /* 69 "E" */ CWORD_CWORD_CWORD_CWORD,
  2612. /* 70 "F" */ CWORD_CWORD_CWORD_CWORD,
  2613. /* 71 "G" */ CWORD_CWORD_CWORD_CWORD,
  2614. /* 72 "H" */ CWORD_CWORD_CWORD_CWORD,
  2615. /* 73 "I" */ CWORD_CWORD_CWORD_CWORD,
  2616. /* 74 "J" */ CWORD_CWORD_CWORD_CWORD,
  2617. /* 75 "K" */ CWORD_CWORD_CWORD_CWORD,
  2618. /* 76 "L" */ CWORD_CWORD_CWORD_CWORD,
  2619. /* 77 "M" */ CWORD_CWORD_CWORD_CWORD,
  2620. /* 78 "N" */ CWORD_CWORD_CWORD_CWORD,
  2621. /* 79 "O" */ CWORD_CWORD_CWORD_CWORD,
  2622. /* 80 "P" */ CWORD_CWORD_CWORD_CWORD,
  2623. /* 81 "Q" */ CWORD_CWORD_CWORD_CWORD,
  2624. /* 82 "R" */ CWORD_CWORD_CWORD_CWORD,
  2625. /* 83 "S" */ CWORD_CWORD_CWORD_CWORD,
  2626. /* 84 "T" */ CWORD_CWORD_CWORD_CWORD,
  2627. /* 85 "U" */ CWORD_CWORD_CWORD_CWORD,
  2628. /* 86 "V" */ CWORD_CWORD_CWORD_CWORD,
  2629. /* 87 "W" */ CWORD_CWORD_CWORD_CWORD,
  2630. /* 88 "X" */ CWORD_CWORD_CWORD_CWORD,
  2631. /* 89 "Y" */ CWORD_CWORD_CWORD_CWORD,
  2632. /* 90 "Z" */ CWORD_CWORD_CWORD_CWORD,
  2633. /* 91 "[" */ CWORD_CCTL_CCTL_CWORD,
  2634. /* 92 "\" */ CBACK_CBACK_CCTL_CBACK,
  2635. /* 93 "]" */ CWORD_CCTL_CCTL_CWORD,
  2636. /* 94 "^" */ CWORD_CWORD_CWORD_CWORD,
  2637. /* 95 "_" */ CWORD_CWORD_CWORD_CWORD,
  2638. /* 96 "`" */ CBQUOTE_CBQUOTE_CWORD_CBQUOTE,
  2639. /* 97 "a" */ CWORD_CWORD_CWORD_CWORD,
  2640. /* 98 "b" */ CWORD_CWORD_CWORD_CWORD,
  2641. /* 99 "c" */ CWORD_CWORD_CWORD_CWORD,
  2642. /* 100 "d" */ CWORD_CWORD_CWORD_CWORD,
  2643. /* 101 "e" */ CWORD_CWORD_CWORD_CWORD,
  2644. /* 102 "f" */ CWORD_CWORD_CWORD_CWORD,
  2645. /* 103 "g" */ CWORD_CWORD_CWORD_CWORD,
  2646. /* 104 "h" */ CWORD_CWORD_CWORD_CWORD,
  2647. /* 105 "i" */ CWORD_CWORD_CWORD_CWORD,
  2648. /* 106 "j" */ CWORD_CWORD_CWORD_CWORD,
  2649. /* 107 "k" */ CWORD_CWORD_CWORD_CWORD,
  2650. /* 108 "l" */ CWORD_CWORD_CWORD_CWORD,
  2651. /* 109 "m" */ CWORD_CWORD_CWORD_CWORD,
  2652. /* 110 "n" */ CWORD_CWORD_CWORD_CWORD,
  2653. /* 111 "o" */ CWORD_CWORD_CWORD_CWORD,
  2654. /* 112 "p" */ CWORD_CWORD_CWORD_CWORD,
  2655. /* 113 "q" */ CWORD_CWORD_CWORD_CWORD,
  2656. /* 114 "r" */ CWORD_CWORD_CWORD_CWORD,
  2657. /* 115 "s" */ CWORD_CWORD_CWORD_CWORD,
  2658. /* 116 "t" */ CWORD_CWORD_CWORD_CWORD,
  2659. /* 117 "u" */ CWORD_CWORD_CWORD_CWORD,
  2660. /* 118 "v" */ CWORD_CWORD_CWORD_CWORD,
  2661. /* 119 "w" */ CWORD_CWORD_CWORD_CWORD,
  2662. /* 120 "x" */ CWORD_CWORD_CWORD_CWORD,
  2663. /* 121 "y" */ CWORD_CWORD_CWORD_CWORD,
  2664. /* 122 "z" */ CWORD_CWORD_CWORD_CWORD,
  2665. /* 123 "{" */ CWORD_CWORD_CWORD_CWORD,
  2666. /* 124 "|" */ CSPCL_CWORD_CWORD_CWORD,
  2667. /* 125 "}" */ CENDVAR_CENDVAR_CWORD_CENDVAR,
  2668. /* 126 "~" */ CWORD_CCTL_CCTL_CWORD,
  2669. /* 127 del */ CWORD_CWORD_CWORD_CWORD,
  2670. /* 128 0x80 */ CWORD_CWORD_CWORD_CWORD,
  2671. /* 129 CTLESC */ CCTL_CCTL_CCTL_CCTL,
  2672. /* 130 CTLVAR */ CCTL_CCTL_CCTL_CCTL,
  2673. /* 131 CTLENDVAR */ CCTL_CCTL_CCTL_CCTL,
  2674. /* 132 CTLBACKQ */ CCTL_CCTL_CCTL_CCTL,
  2675. /* 133 CTLQUOTE */ CCTL_CCTL_CCTL_CCTL,
  2676. /* 134 CTLARI */ CCTL_CCTL_CCTL_CCTL,
  2677. /* 135 CTLENDARI */ CCTL_CCTL_CCTL_CCTL,
  2678. /* 136 CTLQUOTEMARK */ CCTL_CCTL_CCTL_CCTL,
  2679. /* 137 */ CWORD_CWORD_CWORD_CWORD,
  2680. /* 138 */ CWORD_CWORD_CWORD_CWORD,
  2681. /* 139 */ CWORD_CWORD_CWORD_CWORD,
  2682. /* 140 */ CWORD_CWORD_CWORD_CWORD,
  2683. /* 141 */ CWORD_CWORD_CWORD_CWORD,
  2684. /* 142 */ CWORD_CWORD_CWORD_CWORD,
  2685. /* 143 */ CWORD_CWORD_CWORD_CWORD,
  2686. /* 144 */ CWORD_CWORD_CWORD_CWORD,
  2687. /* 145 */ CWORD_CWORD_CWORD_CWORD,
  2688. /* 146 */ CWORD_CWORD_CWORD_CWORD,
  2689. /* 147 */ CWORD_CWORD_CWORD_CWORD,
  2690. /* 148 */ CWORD_CWORD_CWORD_CWORD,
  2691. /* 149 */ CWORD_CWORD_CWORD_CWORD,
  2692. /* 150 */ CWORD_CWORD_CWORD_CWORD,
  2693. /* 151 */ CWORD_CWORD_CWORD_CWORD,
  2694. /* 152 */ CWORD_CWORD_CWORD_CWORD,
  2695. /* 153 */ CWORD_CWORD_CWORD_CWORD,
  2696. /* 154 */ CWORD_CWORD_CWORD_CWORD,
  2697. /* 155 */ CWORD_CWORD_CWORD_CWORD,
  2698. /* 156 */ CWORD_CWORD_CWORD_CWORD,
  2699. /* 157 */ CWORD_CWORD_CWORD_CWORD,
  2700. /* 158 */ CWORD_CWORD_CWORD_CWORD,
  2701. /* 159 */ CWORD_CWORD_CWORD_CWORD,
  2702. /* 160 */ CWORD_CWORD_CWORD_CWORD,
  2703. /* 161 */ CWORD_CWORD_CWORD_CWORD,
  2704. /* 162 */ CWORD_CWORD_CWORD_CWORD,
  2705. /* 163 */ CWORD_CWORD_CWORD_CWORD,
  2706. /* 164 */ CWORD_CWORD_CWORD_CWORD,
  2707. /* 165 */ CWORD_CWORD_CWORD_CWORD,
  2708. /* 166 */ CWORD_CWORD_CWORD_CWORD,
  2709. /* 167 */ CWORD_CWORD_CWORD_CWORD,
  2710. /* 168 */ CWORD_CWORD_CWORD_CWORD,
  2711. /* 169 */ CWORD_CWORD_CWORD_CWORD,
  2712. /* 170 */ CWORD_CWORD_CWORD_CWORD,
  2713. /* 171 */ CWORD_CWORD_CWORD_CWORD,
  2714. /* 172 */ CWORD_CWORD_CWORD_CWORD,
  2715. /* 173 */ CWORD_CWORD_CWORD_CWORD,
  2716. /* 174 */ CWORD_CWORD_CWORD_CWORD,
  2717. /* 175 */ CWORD_CWORD_CWORD_CWORD,
  2718. /* 176 */ CWORD_CWORD_CWORD_CWORD,
  2719. /* 177 */ CWORD_CWORD_CWORD_CWORD,
  2720. /* 178 */ CWORD_CWORD_CWORD_CWORD,
  2721. /* 179 */ CWORD_CWORD_CWORD_CWORD,
  2722. /* 180 */ CWORD_CWORD_CWORD_CWORD,
  2723. /* 181 */ CWORD_CWORD_CWORD_CWORD,
  2724. /* 182 */ CWORD_CWORD_CWORD_CWORD,
  2725. /* 183 */ CWORD_CWORD_CWORD_CWORD,
  2726. /* 184 */ CWORD_CWORD_CWORD_CWORD,
  2727. /* 185 */ CWORD_CWORD_CWORD_CWORD,
  2728. /* 186 */ CWORD_CWORD_CWORD_CWORD,
  2729. /* 187 */ CWORD_CWORD_CWORD_CWORD,
  2730. /* 188 */ CWORD_CWORD_CWORD_CWORD,
  2731. /* 189 */ CWORD_CWORD_CWORD_CWORD,
  2732. /* 190 */ CWORD_CWORD_CWORD_CWORD,
  2733. /* 191 */ CWORD_CWORD_CWORD_CWORD,
  2734. /* 192 */ CWORD_CWORD_CWORD_CWORD,
  2735. /* 193 */ CWORD_CWORD_CWORD_CWORD,
  2736. /* 194 */ CWORD_CWORD_CWORD_CWORD,
  2737. /* 195 */ CWORD_CWORD_CWORD_CWORD,
  2738. /* 196 */ CWORD_CWORD_CWORD_CWORD,
  2739. /* 197 */ CWORD_CWORD_CWORD_CWORD,
  2740. /* 198 */ CWORD_CWORD_CWORD_CWORD,
  2741. /* 199 */ CWORD_CWORD_CWORD_CWORD,
  2742. /* 200 */ CWORD_CWORD_CWORD_CWORD,
  2743. /* 201 */ CWORD_CWORD_CWORD_CWORD,
  2744. /* 202 */ CWORD_CWORD_CWORD_CWORD,
  2745. /* 203 */ CWORD_CWORD_CWORD_CWORD,
  2746. /* 204 */ CWORD_CWORD_CWORD_CWORD,
  2747. /* 205 */ CWORD_CWORD_CWORD_CWORD,
  2748. /* 206 */ CWORD_CWORD_CWORD_CWORD,
  2749. /* 207 */ CWORD_CWORD_CWORD_CWORD,
  2750. /* 208 */ CWORD_CWORD_CWORD_CWORD,
  2751. /* 209 */ CWORD_CWORD_CWORD_CWORD,
  2752. /* 210 */ CWORD_CWORD_CWORD_CWORD,
  2753. /* 211 */ CWORD_CWORD_CWORD_CWORD,
  2754. /* 212 */ CWORD_CWORD_CWORD_CWORD,
  2755. /* 213 */ CWORD_CWORD_CWORD_CWORD,
  2756. /* 214 */ CWORD_CWORD_CWORD_CWORD,
  2757. /* 215 */ CWORD_CWORD_CWORD_CWORD,
  2758. /* 216 */ CWORD_CWORD_CWORD_CWORD,
  2759. /* 217 */ CWORD_CWORD_CWORD_CWORD,
  2760. /* 218 */ CWORD_CWORD_CWORD_CWORD,
  2761. /* 219 */ CWORD_CWORD_CWORD_CWORD,
  2762. /* 220 */ CWORD_CWORD_CWORD_CWORD,
  2763. /* 221 */ CWORD_CWORD_CWORD_CWORD,
  2764. /* 222 */ CWORD_CWORD_CWORD_CWORD,
  2765. /* 223 */ CWORD_CWORD_CWORD_CWORD,
  2766. /* 224 */ CWORD_CWORD_CWORD_CWORD,
  2767. /* 225 */ CWORD_CWORD_CWORD_CWORD,
  2768. /* 226 */ CWORD_CWORD_CWORD_CWORD,
  2769. /* 227 */ CWORD_CWORD_CWORD_CWORD,
  2770. /* 228 */ CWORD_CWORD_CWORD_CWORD,
  2771. /* 229 */ CWORD_CWORD_CWORD_CWORD,
  2772. /* 230 */ CWORD_CWORD_CWORD_CWORD,
  2773. /* 231 */ CWORD_CWORD_CWORD_CWORD,
  2774. /* 232 */ CWORD_CWORD_CWORD_CWORD,
  2775. /* 233 */ CWORD_CWORD_CWORD_CWORD,
  2776. /* 234 */ CWORD_CWORD_CWORD_CWORD,
  2777. /* 235 */ CWORD_CWORD_CWORD_CWORD,
  2778. /* 236 */ CWORD_CWORD_CWORD_CWORD,
  2779. /* 237 */ CWORD_CWORD_CWORD_CWORD,
  2780. /* 238 */ CWORD_CWORD_CWORD_CWORD,
  2781. /* 239 */ CWORD_CWORD_CWORD_CWORD,
  2782. /* 230 */ CWORD_CWORD_CWORD_CWORD,
  2783. /* 241 */ CWORD_CWORD_CWORD_CWORD,
  2784. /* 242 */ CWORD_CWORD_CWORD_CWORD,
  2785. /* 243 */ CWORD_CWORD_CWORD_CWORD,
  2786. /* 244 */ CWORD_CWORD_CWORD_CWORD,
  2787. /* 245 */ CWORD_CWORD_CWORD_CWORD,
  2788. /* 246 */ CWORD_CWORD_CWORD_CWORD,
  2789. /* 247 */ CWORD_CWORD_CWORD_CWORD,
  2790. /* 248 */ CWORD_CWORD_CWORD_CWORD,
  2791. /* 249 */ CWORD_CWORD_CWORD_CWORD,
  2792. /* 250 */ CWORD_CWORD_CWORD_CWORD,
  2793. /* 251 */ CWORD_CWORD_CWORD_CWORD,
  2794. /* 252 */ CWORD_CWORD_CWORD_CWORD,
  2795. /* 253 */ CWORD_CWORD_CWORD_CWORD,
  2796. /* 254 */ CWORD_CWORD_CWORD_CWORD,
  2797. /* 255 */ CWORD_CWORD_CWORD_CWORD,
  2798. /* PEOF */ CENDFILE_CENDFILE_CENDFILE_CENDFILE,
  2799. # if ENABLE_ASH_ALIAS
  2800. /* PEOA */ CSPCL_CIGN_CIGN_CIGN,
  2801. # endif
  2802. };
  2803. # define SIT(c, syntax) ((S_I_T[syntax_index_table[c]] >> ((syntax)*4)) & 0xf)
  2804. #endif /* !USE_SIT_FUNCTION */
  2805. /* ============ Alias handling */
  2806. #if ENABLE_ASH_ALIAS
  2807. #define ALIASINUSE 1
  2808. #define ALIASDEAD 2
  2809. struct alias {
  2810. struct alias *next;
  2811. char *name;
  2812. char *val;
  2813. int flag;
  2814. };
  2815. static struct alias **atab; // [ATABSIZE];
  2816. #define INIT_G_alias() do { \
  2817. atab = xzalloc(ATABSIZE * sizeof(atab[0])); \
  2818. } while (0)
  2819. static struct alias **
  2820. __lookupalias(const char *name) {
  2821. unsigned int hashval;
  2822. struct alias **app;
  2823. const char *p;
  2824. unsigned int ch;
  2825. p = name;
  2826. ch = (unsigned char)*p;
  2827. hashval = ch << 4;
  2828. while (ch) {
  2829. hashval += ch;
  2830. ch = (unsigned char)*++p;
  2831. }
  2832. app = &atab[hashval % ATABSIZE];
  2833. for (; *app; app = &(*app)->next) {
  2834. if (strcmp(name, (*app)->name) == 0) {
  2835. break;
  2836. }
  2837. }
  2838. return app;
  2839. }
  2840. static struct alias *
  2841. lookupalias(const char *name, int check)
  2842. {
  2843. struct alias *ap = *__lookupalias(name);
  2844. if (check && ap && (ap->flag & ALIASINUSE))
  2845. return NULL;
  2846. return ap;
  2847. }
  2848. static struct alias *
  2849. freealias(struct alias *ap)
  2850. {
  2851. struct alias *next;
  2852. if (ap->flag & ALIASINUSE) {
  2853. ap->flag |= ALIASDEAD;
  2854. return ap;
  2855. }
  2856. next = ap->next;
  2857. free(ap->name);
  2858. free(ap->val);
  2859. free(ap);
  2860. return next;
  2861. }
  2862. static void
  2863. setalias(const char *name, const char *val)
  2864. {
  2865. struct alias *ap, **app;
  2866. app = __lookupalias(name);
  2867. ap = *app;
  2868. INT_OFF;
  2869. if (ap) {
  2870. if (!(ap->flag & ALIASINUSE)) {
  2871. free(ap->val);
  2872. }
  2873. ap->val = ckstrdup(val);
  2874. ap->flag &= ~ALIASDEAD;
  2875. } else {
  2876. /* not found */
  2877. ap = ckzalloc(sizeof(struct alias));
  2878. ap->name = ckstrdup(name);
  2879. ap->val = ckstrdup(val);
  2880. /*ap->flag = 0; - ckzalloc did it */
  2881. /*ap->next = NULL;*/
  2882. *app = ap;
  2883. }
  2884. INT_ON;
  2885. }
  2886. static int
  2887. unalias(const char *name)
  2888. {
  2889. struct alias **app;
  2890. app = __lookupalias(name);
  2891. if (*app) {
  2892. INT_OFF;
  2893. *app = freealias(*app);
  2894. INT_ON;
  2895. return 0;
  2896. }
  2897. return 1;
  2898. }
  2899. static void
  2900. rmaliases(void)
  2901. {
  2902. struct alias *ap, **app;
  2903. int i;
  2904. INT_OFF;
  2905. for (i = 0; i < ATABSIZE; i++) {
  2906. app = &atab[i];
  2907. for (ap = *app; ap; ap = *app) {
  2908. *app = freealias(*app);
  2909. if (ap == *app) {
  2910. app = &ap->next;
  2911. }
  2912. }
  2913. }
  2914. INT_ON;
  2915. }
  2916. static void
  2917. printalias(const struct alias *ap)
  2918. {
  2919. out1fmt("%s=%s\n", ap->name, single_quote(ap->val));
  2920. }
  2921. /*
  2922. * TODO - sort output
  2923. */
  2924. static int FAST_FUNC
  2925. aliascmd(int argc UNUSED_PARAM, char **argv)
  2926. {
  2927. char *n, *v;
  2928. int ret = 0;
  2929. struct alias *ap;
  2930. if (!argv[1]) {
  2931. int i;
  2932. for (i = 0; i < ATABSIZE; i++) {
  2933. for (ap = atab[i]; ap; ap = ap->next) {
  2934. printalias(ap);
  2935. }
  2936. }
  2937. return 0;
  2938. }
  2939. while ((n = *++argv) != NULL) {
  2940. v = strchr(n+1, '=');
  2941. if (v == NULL) { /* n+1: funny ksh stuff */
  2942. ap = *__lookupalias(n);
  2943. if (ap == NULL) {
  2944. fprintf(stderr, "%s: %s not found\n", "alias", n);
  2945. ret = 1;
  2946. } else
  2947. printalias(ap);
  2948. } else {
  2949. *v++ = '\0';
  2950. setalias(n, v);
  2951. }
  2952. }
  2953. return ret;
  2954. }
  2955. static int FAST_FUNC
  2956. unaliascmd(int argc UNUSED_PARAM, char **argv UNUSED_PARAM)
  2957. {
  2958. int i;
  2959. while ((i = nextopt("a")) != '\0') {
  2960. if (i == 'a') {
  2961. rmaliases();
  2962. return 0;
  2963. }
  2964. }
  2965. for (i = 0; *argptr; argptr++) {
  2966. if (unalias(*argptr)) {
  2967. fprintf(stderr, "%s: %s not found\n", "unalias", *argptr);
  2968. i = 1;
  2969. }
  2970. }
  2971. return i;
  2972. }
  2973. #endif /* ASH_ALIAS */
  2974. /* ============ jobs.c */
  2975. /* Mode argument to forkshell. Don't change FORK_FG or FORK_BG. */
  2976. #define FORK_FG 0
  2977. #define FORK_BG 1
  2978. #define FORK_NOJOB 2
  2979. /* mode flags for showjob(s) */
  2980. #define SHOW_ONLY_PGID 0x01 /* show only pgid (jobs -p) */
  2981. #define SHOW_PIDS 0x02 /* show individual pids, not just one line per job */
  2982. #define SHOW_CHANGED 0x04 /* only jobs whose state has changed */
  2983. /*
  2984. * A job structure contains information about a job. A job is either a
  2985. * single process or a set of processes contained in a pipeline. In the
  2986. * latter case, pidlist will be non-NULL, and will point to a -1 terminated
  2987. * array of pids.
  2988. */
  2989. struct procstat {
  2990. pid_t ps_pid; /* process id */
  2991. int ps_status; /* last process status from wait() */
  2992. char *ps_cmd; /* text of command being run */
  2993. };
  2994. struct job {
  2995. struct procstat ps0; /* status of process */
  2996. struct procstat *ps; /* status or processes when more than one */
  2997. #if JOBS
  2998. int stopstatus; /* status of a stopped job */
  2999. #endif
  3000. uint32_t
  3001. nprocs: 16, /* number of processes */
  3002. state: 8,
  3003. #define JOBRUNNING 0 /* at least one proc running */
  3004. #define JOBSTOPPED 1 /* all procs are stopped */
  3005. #define JOBDONE 2 /* all procs are completed */
  3006. #if JOBS
  3007. sigint: 1, /* job was killed by SIGINT */
  3008. jobctl: 1, /* job running under job control */
  3009. #endif
  3010. waited: 1, /* true if this entry has been waited for */
  3011. used: 1, /* true if this entry is in used */
  3012. changed: 1; /* true if status has changed */
  3013. struct job *prev_job; /* previous job */
  3014. };
  3015. static struct job *makejob(/*union node *,*/ int);
  3016. static int forkshell(struct job *, union node *, int);
  3017. static int waitforjob(struct job *);
  3018. #if !JOBS
  3019. enum { doing_jobctl = 0 };
  3020. #define setjobctl(on) do {} while (0)
  3021. #else
  3022. static smallint doing_jobctl; //references:8
  3023. static void setjobctl(int);
  3024. #endif
  3025. /*
  3026. * Ignore a signal.
  3027. */
  3028. static void
  3029. ignoresig(int signo)
  3030. {
  3031. /* Avoid unnecessary system calls. Is it already SIG_IGNed? */
  3032. if (sigmode[signo - 1] != S_IGN && sigmode[signo - 1] != S_HARD_IGN) {
  3033. /* No, need to do it */
  3034. signal(signo, SIG_IGN);
  3035. }
  3036. sigmode[signo - 1] = S_HARD_IGN;
  3037. }
  3038. /*
  3039. * Only one usage site - in setsignal()
  3040. */
  3041. static void
  3042. signal_handler(int signo)
  3043. {
  3044. gotsig[signo - 1] = 1;
  3045. if (signo == SIGINT && !trap[SIGINT]) {
  3046. if (!suppress_int) {
  3047. pending_sig = 0;
  3048. raise_interrupt(); /* does not return */
  3049. }
  3050. pending_int = 1;
  3051. } else {
  3052. pending_sig = signo;
  3053. }
  3054. }
  3055. /*
  3056. * Set the signal handler for the specified signal. The routine figures
  3057. * out what it should be set to.
  3058. */
  3059. static void
  3060. setsignal(int signo)
  3061. {
  3062. char *t;
  3063. char cur_act, new_act;
  3064. struct sigaction act;
  3065. t = trap[signo];
  3066. new_act = S_DFL;
  3067. if (t != NULL) { /* trap for this sig is set */
  3068. new_act = S_CATCH;
  3069. if (t[0] == '\0') /* trap is "": ignore this sig */
  3070. new_act = S_IGN;
  3071. }
  3072. if (rootshell && new_act == S_DFL) {
  3073. switch (signo) {
  3074. case SIGINT:
  3075. if (iflag || minusc || sflag == 0)
  3076. new_act = S_CATCH;
  3077. break;
  3078. case SIGQUIT:
  3079. #if DEBUG
  3080. if (debug)
  3081. break;
  3082. #endif
  3083. /* man bash:
  3084. * "In all cases, bash ignores SIGQUIT. Non-builtin
  3085. * commands run by bash have signal handlers
  3086. * set to the values inherited by the shell
  3087. * from its parent". */
  3088. new_act = S_IGN;
  3089. break;
  3090. case SIGTERM:
  3091. if (iflag)
  3092. new_act = S_IGN;
  3093. break;
  3094. #if JOBS
  3095. case SIGTSTP:
  3096. case SIGTTOU:
  3097. if (mflag)
  3098. new_act = S_IGN;
  3099. break;
  3100. #endif
  3101. }
  3102. }
  3103. //TODO: if !rootshell, we reset SIGQUIT to DFL,
  3104. //whereas we have to restore it to what shell got on entry
  3105. //from the parent. See comment above
  3106. t = &sigmode[signo - 1];
  3107. cur_act = *t;
  3108. if (cur_act == 0) {
  3109. /* current setting is not yet known */
  3110. if (sigaction(signo, NULL, &act)) {
  3111. /* pretend it worked; maybe we should give a warning,
  3112. * but other shells don't. We don't alter sigmode,
  3113. * so we retry every time.
  3114. * btw, in Linux it never fails. --vda */
  3115. return;
  3116. }
  3117. if (act.sa_handler == SIG_IGN) {
  3118. cur_act = S_HARD_IGN;
  3119. if (mflag
  3120. && (signo == SIGTSTP || signo == SIGTTIN || signo == SIGTTOU)
  3121. ) {
  3122. cur_act = S_IGN; /* don't hard ignore these */
  3123. }
  3124. }
  3125. }
  3126. if (cur_act == S_HARD_IGN || cur_act == new_act)
  3127. return;
  3128. act.sa_handler = SIG_DFL;
  3129. switch (new_act) {
  3130. case S_CATCH:
  3131. act.sa_handler = signal_handler;
  3132. break;
  3133. case S_IGN:
  3134. act.sa_handler = SIG_IGN;
  3135. break;
  3136. }
  3137. /* flags and mask matter only if !DFL and !IGN, but we do it
  3138. * for all cases for more deterministic behavior:
  3139. */
  3140. act.sa_flags = 0;
  3141. sigfillset(&act.sa_mask);
  3142. sigaction_set(signo, &act);
  3143. *t = new_act;
  3144. }
  3145. /* mode flags for set_curjob */
  3146. #define CUR_DELETE 2
  3147. #define CUR_RUNNING 1
  3148. #define CUR_STOPPED 0
  3149. /* mode flags for dowait */
  3150. #define DOWAIT_NONBLOCK WNOHANG
  3151. #define DOWAIT_BLOCK 0
  3152. #if JOBS
  3153. /* pgrp of shell on invocation */
  3154. static int initialpgrp; //references:2
  3155. static int ttyfd = -1; //5
  3156. #endif
  3157. /* array of jobs */
  3158. static struct job *jobtab; //5
  3159. /* size of array */
  3160. static unsigned njobs; //4
  3161. /* current job */
  3162. static struct job *curjob; //lots
  3163. /* number of presumed living untracked jobs */
  3164. static int jobless; //4
  3165. static void
  3166. set_curjob(struct job *jp, unsigned mode)
  3167. {
  3168. struct job *jp1;
  3169. struct job **jpp, **curp;
  3170. /* first remove from list */
  3171. jpp = curp = &curjob;
  3172. while (1) {
  3173. jp1 = *jpp;
  3174. if (jp1 == jp)
  3175. break;
  3176. jpp = &jp1->prev_job;
  3177. }
  3178. *jpp = jp1->prev_job;
  3179. /* Then re-insert in correct position */
  3180. jpp = curp;
  3181. switch (mode) {
  3182. default:
  3183. #if DEBUG
  3184. abort();
  3185. #endif
  3186. case CUR_DELETE:
  3187. /* job being deleted */
  3188. break;
  3189. case CUR_RUNNING:
  3190. /* newly created job or backgrounded job,
  3191. * put after all stopped jobs.
  3192. */
  3193. while (1) {
  3194. jp1 = *jpp;
  3195. #if JOBS
  3196. if (!jp1 || jp1->state != JOBSTOPPED)
  3197. #endif
  3198. break;
  3199. jpp = &jp1->prev_job;
  3200. }
  3201. /* FALLTHROUGH */
  3202. #if JOBS
  3203. case CUR_STOPPED:
  3204. #endif
  3205. /* newly stopped job - becomes curjob */
  3206. jp->prev_job = *jpp;
  3207. *jpp = jp;
  3208. break;
  3209. }
  3210. }
  3211. #if JOBS || DEBUG
  3212. static int
  3213. jobno(const struct job *jp)
  3214. {
  3215. return jp - jobtab + 1;
  3216. }
  3217. #endif
  3218. /*
  3219. * Convert a job name to a job structure.
  3220. */
  3221. #if !JOBS
  3222. #define getjob(name, getctl) getjob(name)
  3223. #endif
  3224. static struct job *
  3225. getjob(const char *name, int getctl)
  3226. {
  3227. struct job *jp;
  3228. struct job *found;
  3229. const char *err_msg = "%s: no such job";
  3230. unsigned num;
  3231. int c;
  3232. const char *p;
  3233. char *(*match)(const char *, const char *);
  3234. jp = curjob;
  3235. p = name;
  3236. if (!p)
  3237. goto currentjob;
  3238. if (*p != '%')
  3239. goto err;
  3240. c = *++p;
  3241. if (!c)
  3242. goto currentjob;
  3243. if (!p[1]) {
  3244. if (c == '+' || c == '%') {
  3245. currentjob:
  3246. err_msg = "No current job";
  3247. goto check;
  3248. }
  3249. if (c == '-') {
  3250. if (jp)
  3251. jp = jp->prev_job;
  3252. err_msg = "No previous job";
  3253. check:
  3254. if (!jp)
  3255. goto err;
  3256. goto gotit;
  3257. }
  3258. }
  3259. if (is_number(p)) {
  3260. num = atoi(p);
  3261. if (num < njobs) {
  3262. jp = jobtab + num - 1;
  3263. if (jp->used)
  3264. goto gotit;
  3265. goto err;
  3266. }
  3267. }
  3268. match = prefix;
  3269. if (*p == '?') {
  3270. match = strstr;
  3271. p++;
  3272. }
  3273. found = NULL;
  3274. while (jp) {
  3275. if (match(jp->ps[0].ps_cmd, p)) {
  3276. if (found)
  3277. goto err;
  3278. found = jp;
  3279. err_msg = "%s: ambiguous";
  3280. }
  3281. jp = jp->prev_job;
  3282. }
  3283. if (!found)
  3284. goto err;
  3285. jp = found;
  3286. gotit:
  3287. #if JOBS
  3288. err_msg = "job %s not created under job control";
  3289. if (getctl && jp->jobctl == 0)
  3290. goto err;
  3291. #endif
  3292. return jp;
  3293. err:
  3294. ash_msg_and_raise_error(err_msg, name);
  3295. }
  3296. /*
  3297. * Mark a job structure as unused.
  3298. */
  3299. static void
  3300. freejob(struct job *jp)
  3301. {
  3302. struct procstat *ps;
  3303. int i;
  3304. INT_OFF;
  3305. for (i = jp->nprocs, ps = jp->ps; --i >= 0; ps++) {
  3306. if (ps->ps_cmd != nullstr)
  3307. free(ps->ps_cmd);
  3308. }
  3309. if (jp->ps != &jp->ps0)
  3310. free(jp->ps);
  3311. jp->used = 0;
  3312. set_curjob(jp, CUR_DELETE);
  3313. INT_ON;
  3314. }
  3315. #if JOBS
  3316. static void
  3317. xtcsetpgrp(int fd, pid_t pgrp)
  3318. {
  3319. if (tcsetpgrp(fd, pgrp))
  3320. ash_msg_and_raise_error("can't set tty process group (%m)");
  3321. }
  3322. /*
  3323. * Turn job control on and off.
  3324. *
  3325. * Note: This code assumes that the third arg to ioctl is a character
  3326. * pointer, which is true on Berkeley systems but not System V. Since
  3327. * System V doesn't have job control yet, this isn't a problem now.
  3328. *
  3329. * Called with interrupts off.
  3330. */
  3331. static void
  3332. setjobctl(int on)
  3333. {
  3334. int fd;
  3335. int pgrp;
  3336. if (on == doing_jobctl || rootshell == 0)
  3337. return;
  3338. if (on) {
  3339. int ofd;
  3340. ofd = fd = open(_PATH_TTY, O_RDWR);
  3341. if (fd < 0) {
  3342. /* BTW, bash will try to open(ttyname(0)) if open("/dev/tty") fails.
  3343. * That sometimes helps to acquire controlling tty.
  3344. * Obviously, a workaround for bugs when someone
  3345. * failed to provide a controlling tty to bash! :) */
  3346. fd = 2;
  3347. while (!isatty(fd))
  3348. if (--fd < 0)
  3349. goto out;
  3350. }
  3351. fd = fcntl(fd, F_DUPFD, 10);
  3352. if (ofd >= 0)
  3353. close(ofd);
  3354. if (fd < 0)
  3355. goto out;
  3356. /* fd is a tty at this point */
  3357. close_on_exec_on(fd);
  3358. while (1) { /* while we are in the background */
  3359. pgrp = tcgetpgrp(fd);
  3360. if (pgrp < 0) {
  3361. out:
  3362. ash_msg("can't access tty; job control turned off");
  3363. mflag = on = 0;
  3364. goto close;
  3365. }
  3366. if (pgrp == getpgrp())
  3367. break;
  3368. killpg(0, SIGTTIN);
  3369. }
  3370. initialpgrp = pgrp;
  3371. setsignal(SIGTSTP);
  3372. setsignal(SIGTTOU);
  3373. setsignal(SIGTTIN);
  3374. pgrp = rootpid;
  3375. setpgid(0, pgrp);
  3376. xtcsetpgrp(fd, pgrp);
  3377. } else {
  3378. /* turning job control off */
  3379. fd = ttyfd;
  3380. pgrp = initialpgrp;
  3381. /* was xtcsetpgrp, but this can make exiting ash
  3382. * loop forever if pty is already deleted */
  3383. tcsetpgrp(fd, pgrp);
  3384. setpgid(0, pgrp);
  3385. setsignal(SIGTSTP);
  3386. setsignal(SIGTTOU);
  3387. setsignal(SIGTTIN);
  3388. close:
  3389. if (fd >= 0)
  3390. close(fd);
  3391. fd = -1;
  3392. }
  3393. ttyfd = fd;
  3394. doing_jobctl = on;
  3395. }
  3396. static int FAST_FUNC
  3397. killcmd(int argc, char **argv)
  3398. {
  3399. if (argv[1] && strcmp(argv[1], "-l") != 0) {
  3400. int i = 1;
  3401. do {
  3402. if (argv[i][0] == '%') {
  3403. /*
  3404. * "kill %N" - job kill
  3405. * Converting to pgrp / pid kill
  3406. */
  3407. struct job *jp;
  3408. char *dst;
  3409. int j, n;
  3410. jp = getjob(argv[i], 0);
  3411. /*
  3412. * In jobs started under job control, we signal
  3413. * entire process group by kill -PGRP_ID.
  3414. * This happens, f.e., in interactive shell.
  3415. *
  3416. * Otherwise, we signal each child via
  3417. * kill PID1 PID2 PID3.
  3418. * Testcases:
  3419. * sh -c 'sleep 1|sleep 1 & kill %1'
  3420. * sh -c 'true|sleep 2 & sleep 1; kill %1'
  3421. * sh -c 'true|sleep 1 & sleep 2; kill %1'
  3422. */
  3423. n = jp->nprocs; /* can't be 0 (I hope) */
  3424. if (jp->jobctl)
  3425. n = 1;
  3426. dst = alloca(n * sizeof(int)*4);
  3427. argv[i] = dst;
  3428. for (j = 0; j < n; j++) {
  3429. struct procstat *ps = &jp->ps[j];
  3430. /* Skip non-running and not-stopped members
  3431. * (i.e. dead members) of the job
  3432. */
  3433. if (ps->ps_status != -1 && !WIFSTOPPED(ps->ps_status))
  3434. continue;
  3435. /*
  3436. * kill_main has matching code to expect
  3437. * leading space. Needed to not confuse
  3438. * negative pids with "kill -SIGNAL_NO" syntax
  3439. */
  3440. dst += sprintf(dst, jp->jobctl ? " -%u" : " %u", (int)ps->ps_pid);
  3441. }
  3442. *dst = '\0';
  3443. }
  3444. } while (argv[++i]);
  3445. }
  3446. return kill_main(argc, argv);
  3447. }
  3448. static void
  3449. showpipe(struct job *jp /*, FILE *out*/)
  3450. {
  3451. struct procstat *ps;
  3452. struct procstat *psend;
  3453. psend = jp->ps + jp->nprocs;
  3454. for (ps = jp->ps + 1; ps < psend; ps++)
  3455. printf(" | %s", ps->ps_cmd);
  3456. outcslow('\n', stdout);
  3457. flush_stdout_stderr();
  3458. }
  3459. static int
  3460. restartjob(struct job *jp, int mode)
  3461. {
  3462. struct procstat *ps;
  3463. int i;
  3464. int status;
  3465. pid_t pgid;
  3466. INT_OFF;
  3467. if (jp->state == JOBDONE)
  3468. goto out;
  3469. jp->state = JOBRUNNING;
  3470. pgid = jp->ps[0].ps_pid;
  3471. if (mode == FORK_FG)
  3472. xtcsetpgrp(ttyfd, pgid);
  3473. killpg(pgid, SIGCONT);
  3474. ps = jp->ps;
  3475. i = jp->nprocs;
  3476. do {
  3477. if (WIFSTOPPED(ps->ps_status)) {
  3478. ps->ps_status = -1;
  3479. }
  3480. ps++;
  3481. } while (--i);
  3482. out:
  3483. status = (mode == FORK_FG) ? waitforjob(jp) : 0;
  3484. INT_ON;
  3485. return status;
  3486. }
  3487. static int FAST_FUNC
  3488. fg_bgcmd(int argc UNUSED_PARAM, char **argv)
  3489. {
  3490. struct job *jp;
  3491. int mode;
  3492. int retval;
  3493. mode = (**argv == 'f') ? FORK_FG : FORK_BG;
  3494. nextopt(nullstr);
  3495. argv = argptr;
  3496. do {
  3497. jp = getjob(*argv, 1);
  3498. if (mode == FORK_BG) {
  3499. set_curjob(jp, CUR_RUNNING);
  3500. printf("[%d] ", jobno(jp));
  3501. }
  3502. out1str(jp->ps[0].ps_cmd);
  3503. showpipe(jp /*, stdout*/);
  3504. retval = restartjob(jp, mode);
  3505. } while (*argv && *++argv);
  3506. return retval;
  3507. }
  3508. #endif
  3509. static int
  3510. sprint_status(char *s, int status, int sigonly)
  3511. {
  3512. int col;
  3513. int st;
  3514. col = 0;
  3515. if (!WIFEXITED(status)) {
  3516. #if JOBS
  3517. if (WIFSTOPPED(status))
  3518. st = WSTOPSIG(status);
  3519. else
  3520. #endif
  3521. st = WTERMSIG(status);
  3522. if (sigonly) {
  3523. if (st == SIGINT || st == SIGPIPE)
  3524. goto out;
  3525. #if JOBS
  3526. if (WIFSTOPPED(status))
  3527. goto out;
  3528. #endif
  3529. }
  3530. st &= 0x7f;
  3531. //TODO: use bbox's get_signame? strsignal adds ~600 bytes to text+rodata
  3532. col = fmtstr(s, 32, strsignal(st));
  3533. if (WCOREDUMP(status)) {
  3534. col += fmtstr(s + col, 16, " (core dumped)");
  3535. }
  3536. } else if (!sigonly) {
  3537. st = WEXITSTATUS(status);
  3538. if (st)
  3539. col = fmtstr(s, 16, "Done(%d)", st);
  3540. else
  3541. col = fmtstr(s, 16, "Done");
  3542. }
  3543. out:
  3544. return col;
  3545. }
  3546. static int
  3547. dowait(int wait_flags, struct job *job)
  3548. {
  3549. int pid;
  3550. int status;
  3551. struct job *jp;
  3552. struct job *thisjob;
  3553. int state;
  3554. TRACE(("dowait(0x%x) called\n", wait_flags));
  3555. /* Do a wait system call. If job control is compiled in, we accept
  3556. * stopped processes. wait_flags may have WNOHANG, preventing blocking.
  3557. * NB: _not_ safe_waitpid, we need to detect EINTR */
  3558. if (doing_jobctl)
  3559. wait_flags |= WUNTRACED;
  3560. pid = waitpid(-1, &status, wait_flags);
  3561. TRACE(("wait returns pid=%d, status=0x%x, errno=%d(%s)\n",
  3562. pid, status, errno, strerror(errno)));
  3563. if (pid <= 0)
  3564. return pid;
  3565. INT_OFF;
  3566. thisjob = NULL;
  3567. for (jp = curjob; jp; jp = jp->prev_job) {
  3568. struct procstat *ps;
  3569. struct procstat *psend;
  3570. if (jp->state == JOBDONE)
  3571. continue;
  3572. state = JOBDONE;
  3573. ps = jp->ps;
  3574. psend = ps + jp->nprocs;
  3575. do {
  3576. if (ps->ps_pid == pid) {
  3577. TRACE(("Job %d: changing status of proc %d "
  3578. "from 0x%x to 0x%x\n",
  3579. jobno(jp), pid, ps->ps_status, status));
  3580. ps->ps_status = status;
  3581. thisjob = jp;
  3582. }
  3583. if (ps->ps_status == -1)
  3584. state = JOBRUNNING;
  3585. #if JOBS
  3586. if (state == JOBRUNNING)
  3587. continue;
  3588. if (WIFSTOPPED(ps->ps_status)) {
  3589. jp->stopstatus = ps->ps_status;
  3590. state = JOBSTOPPED;
  3591. }
  3592. #endif
  3593. } while (++ps < psend);
  3594. if (thisjob)
  3595. goto gotjob;
  3596. }
  3597. #if JOBS
  3598. if (!WIFSTOPPED(status))
  3599. #endif
  3600. jobless--;
  3601. goto out;
  3602. gotjob:
  3603. if (state != JOBRUNNING) {
  3604. thisjob->changed = 1;
  3605. if (thisjob->state != state) {
  3606. TRACE(("Job %d: changing state from %d to %d\n",
  3607. jobno(thisjob), thisjob->state, state));
  3608. thisjob->state = state;
  3609. #if JOBS
  3610. if (state == JOBSTOPPED) {
  3611. set_curjob(thisjob, CUR_STOPPED);
  3612. }
  3613. #endif
  3614. }
  3615. }
  3616. out:
  3617. INT_ON;
  3618. if (thisjob && thisjob == job) {
  3619. char s[48 + 1];
  3620. int len;
  3621. len = sprint_status(s, status, 1);
  3622. if (len) {
  3623. s[len] = '\n';
  3624. s[len + 1] = '\0';
  3625. out2str(s);
  3626. }
  3627. }
  3628. return pid;
  3629. }
  3630. static int
  3631. blocking_wait_with_raise_on_sig(void)
  3632. {
  3633. pid_t pid = dowait(DOWAIT_BLOCK, NULL);
  3634. if (pid <= 0 && pending_sig)
  3635. raise_exception(EXSIG);
  3636. return pid;
  3637. }
  3638. #if JOBS
  3639. static void
  3640. showjob(FILE *out, struct job *jp, int mode)
  3641. {
  3642. struct procstat *ps;
  3643. struct procstat *psend;
  3644. int col;
  3645. int indent_col;
  3646. char s[80];
  3647. ps = jp->ps;
  3648. if (mode & SHOW_ONLY_PGID) { /* jobs -p */
  3649. /* just output process (group) id of pipeline */
  3650. fprintf(out, "%d\n", ps->ps_pid);
  3651. return;
  3652. }
  3653. col = fmtstr(s, 16, "[%d] ", jobno(jp));
  3654. indent_col = col;
  3655. if (jp == curjob)
  3656. s[col - 3] = '+';
  3657. else if (curjob && jp == curjob->prev_job)
  3658. s[col - 3] = '-';
  3659. if (mode & SHOW_PIDS)
  3660. col += fmtstr(s + col, 16, "%d ", ps->ps_pid);
  3661. psend = ps + jp->nprocs;
  3662. if (jp->state == JOBRUNNING) {
  3663. strcpy(s + col, "Running");
  3664. col += sizeof("Running") - 1;
  3665. } else {
  3666. int status = psend[-1].ps_status;
  3667. if (jp->state == JOBSTOPPED)
  3668. status = jp->stopstatus;
  3669. col += sprint_status(s + col, status, 0);
  3670. }
  3671. /* By now, "[JOBID]* [maybe PID] STATUS" is printed */
  3672. /* This loop either prints "<cmd1> | <cmd2> | <cmd3>" line
  3673. * or prints several "PID | <cmdN>" lines,
  3674. * depending on SHOW_PIDS bit.
  3675. * We do not print status of individual processes
  3676. * between PID and <cmdN>. bash does it, but not very well:
  3677. * first line shows overall job status, not process status,
  3678. * making it impossible to know 1st process status.
  3679. */
  3680. goto start;
  3681. do {
  3682. /* for each process */
  3683. s[0] = '\0';
  3684. col = 33;
  3685. if (mode & SHOW_PIDS)
  3686. col = fmtstr(s, 48, "\n%*c%d ", indent_col, ' ', ps->ps_pid) - 1;
  3687. start:
  3688. fprintf(out, "%s%*c%s%s",
  3689. s,
  3690. 33 - col >= 0 ? 33 - col : 0, ' ',
  3691. ps == jp->ps ? "" : "| ",
  3692. ps->ps_cmd
  3693. );
  3694. } while (++ps != psend);
  3695. outcslow('\n', out);
  3696. jp->changed = 0;
  3697. if (jp->state == JOBDONE) {
  3698. TRACE(("showjob: freeing job %d\n", jobno(jp)));
  3699. freejob(jp);
  3700. }
  3701. }
  3702. /*
  3703. * Print a list of jobs. If "change" is nonzero, only print jobs whose
  3704. * statuses have changed since the last call to showjobs.
  3705. */
  3706. static void
  3707. showjobs(FILE *out, int mode)
  3708. {
  3709. struct job *jp;
  3710. TRACE(("showjobs(0x%x) called\n", mode));
  3711. /* Handle all finished jobs */
  3712. while (dowait(DOWAIT_NONBLOCK, NULL) > 0)
  3713. continue;
  3714. for (jp = curjob; jp; jp = jp->prev_job) {
  3715. if (!(mode & SHOW_CHANGED) || jp->changed) {
  3716. showjob(out, jp, mode);
  3717. }
  3718. }
  3719. }
  3720. static int FAST_FUNC
  3721. jobscmd(int argc UNUSED_PARAM, char **argv)
  3722. {
  3723. int mode, m;
  3724. mode = 0;
  3725. while ((m = nextopt("lp")) != '\0') {
  3726. if (m == 'l')
  3727. mode |= SHOW_PIDS;
  3728. else
  3729. mode |= SHOW_ONLY_PGID;
  3730. }
  3731. argv = argptr;
  3732. if (*argv) {
  3733. do
  3734. showjob(stdout, getjob(*argv, 0), mode);
  3735. while (*++argv);
  3736. } else {
  3737. showjobs(stdout, mode);
  3738. }
  3739. return 0;
  3740. }
  3741. #endif /* JOBS */
  3742. /* Called only on finished or stopped jobs (no members are running) */
  3743. static int
  3744. getstatus(struct job *job)
  3745. {
  3746. int status;
  3747. int retval;
  3748. struct procstat *ps;
  3749. /* Fetch last member's status */
  3750. ps = job->ps + job->nprocs - 1;
  3751. status = ps->ps_status;
  3752. if (pipefail) {
  3753. /* "set -o pipefail" mode: use last _nonzero_ status */
  3754. while (status == 0 && --ps >= job->ps)
  3755. status = ps->ps_status;
  3756. }
  3757. retval = WEXITSTATUS(status);
  3758. if (!WIFEXITED(status)) {
  3759. #if JOBS
  3760. retval = WSTOPSIG(status);
  3761. if (!WIFSTOPPED(status))
  3762. #endif
  3763. {
  3764. /* XXX: limits number of signals */
  3765. retval = WTERMSIG(status);
  3766. #if JOBS
  3767. if (retval == SIGINT)
  3768. job->sigint = 1;
  3769. #endif
  3770. }
  3771. retval += 128;
  3772. }
  3773. TRACE(("getstatus: job %d, nproc %d, status 0x%x, retval 0x%x\n",
  3774. jobno(job), job->nprocs, status, retval));
  3775. return retval;
  3776. }
  3777. static int FAST_FUNC
  3778. waitcmd(int argc UNUSED_PARAM, char **argv)
  3779. {
  3780. struct job *job;
  3781. int retval;
  3782. struct job *jp;
  3783. if (pending_sig)
  3784. raise_exception(EXSIG);
  3785. nextopt(nullstr);
  3786. retval = 0;
  3787. argv = argptr;
  3788. if (!*argv) {
  3789. /* wait for all jobs */
  3790. for (;;) {
  3791. jp = curjob;
  3792. while (1) {
  3793. if (!jp) /* no running procs */
  3794. goto ret;
  3795. if (jp->state == JOBRUNNING)
  3796. break;
  3797. jp->waited = 1;
  3798. jp = jp->prev_job;
  3799. }
  3800. blocking_wait_with_raise_on_sig();
  3801. /* man bash:
  3802. * "When bash is waiting for an asynchronous command via
  3803. * the wait builtin, the reception of a signal for which a trap
  3804. * has been set will cause the wait builtin to return immediately
  3805. * with an exit status greater than 128, immediately after which
  3806. * the trap is executed."
  3807. *
  3808. * blocking_wait_with_raise_on_sig raises signal handlers
  3809. * if it gets no pid (pid < 0). However,
  3810. * if child sends us a signal *and immediately exits*,
  3811. * blocking_wait_with_raise_on_sig gets pid > 0
  3812. * and does not handle pending_sig. Check this case: */
  3813. if (pending_sig)
  3814. raise_exception(EXSIG);
  3815. }
  3816. }
  3817. retval = 127;
  3818. do {
  3819. if (**argv != '%') {
  3820. pid_t pid = number(*argv);
  3821. job = curjob;
  3822. while (1) {
  3823. if (!job)
  3824. goto repeat;
  3825. if (job->ps[job->nprocs - 1].ps_pid == pid)
  3826. break;
  3827. job = job->prev_job;
  3828. }
  3829. } else {
  3830. job = getjob(*argv, 0);
  3831. }
  3832. /* loop until process terminated or stopped */
  3833. while (job->state == JOBRUNNING)
  3834. blocking_wait_with_raise_on_sig();
  3835. job->waited = 1;
  3836. retval = getstatus(job);
  3837. repeat: ;
  3838. } while (*++argv);
  3839. ret:
  3840. return retval;
  3841. }
  3842. static struct job *
  3843. growjobtab(void)
  3844. {
  3845. size_t len;
  3846. ptrdiff_t offset;
  3847. struct job *jp, *jq;
  3848. len = njobs * sizeof(*jp);
  3849. jq = jobtab;
  3850. jp = ckrealloc(jq, len + 4 * sizeof(*jp));
  3851. offset = (char *)jp - (char *)jq;
  3852. if (offset) {
  3853. /* Relocate pointers */
  3854. size_t l = len;
  3855. jq = (struct job *)((char *)jq + l);
  3856. while (l) {
  3857. l -= sizeof(*jp);
  3858. jq--;
  3859. #define joff(p) ((struct job *)((char *)(p) + l))
  3860. #define jmove(p) (p) = (void *)((char *)(p) + offset)
  3861. if (joff(jp)->ps == &jq->ps0)
  3862. jmove(joff(jp)->ps);
  3863. if (joff(jp)->prev_job)
  3864. jmove(joff(jp)->prev_job);
  3865. }
  3866. if (curjob)
  3867. jmove(curjob);
  3868. #undef joff
  3869. #undef jmove
  3870. }
  3871. njobs += 4;
  3872. jobtab = jp;
  3873. jp = (struct job *)((char *)jp + len);
  3874. jq = jp + 3;
  3875. do {
  3876. jq->used = 0;
  3877. } while (--jq >= jp);
  3878. return jp;
  3879. }
  3880. /*
  3881. * Return a new job structure.
  3882. * Called with interrupts off.
  3883. */
  3884. static struct job *
  3885. makejob(/*union node *node,*/ int nprocs)
  3886. {
  3887. int i;
  3888. struct job *jp;
  3889. for (i = njobs, jp = jobtab; ; jp++) {
  3890. if (--i < 0) {
  3891. jp = growjobtab();
  3892. break;
  3893. }
  3894. if (jp->used == 0)
  3895. break;
  3896. if (jp->state != JOBDONE || !jp->waited)
  3897. continue;
  3898. #if JOBS
  3899. if (doing_jobctl)
  3900. continue;
  3901. #endif
  3902. freejob(jp);
  3903. break;
  3904. }
  3905. memset(jp, 0, sizeof(*jp));
  3906. #if JOBS
  3907. /* jp->jobctl is a bitfield.
  3908. * "jp->jobctl |= jobctl" likely to give awful code */
  3909. if (doing_jobctl)
  3910. jp->jobctl = 1;
  3911. #endif
  3912. jp->prev_job = curjob;
  3913. curjob = jp;
  3914. jp->used = 1;
  3915. jp->ps = &jp->ps0;
  3916. if (nprocs > 1) {
  3917. jp->ps = ckmalloc(nprocs * sizeof(struct procstat));
  3918. }
  3919. TRACE(("makejob(%d) returns %%%d\n", nprocs,
  3920. jobno(jp)));
  3921. return jp;
  3922. }
  3923. #if JOBS
  3924. /*
  3925. * Return a string identifying a command (to be printed by the
  3926. * jobs command).
  3927. */
  3928. static char *cmdnextc;
  3929. static void
  3930. cmdputs(const char *s)
  3931. {
  3932. static const char vstype[VSTYPE + 1][3] = {
  3933. "", "}", "-", "+", "?", "=",
  3934. "%", "%%", "#", "##"
  3935. IF_ASH_BASH_COMPAT(, ":", "/", "//")
  3936. };
  3937. const char *p, *str;
  3938. char cc[2];
  3939. char *nextc;
  3940. unsigned char c;
  3941. unsigned char subtype = 0;
  3942. int quoted = 0;
  3943. cc[1] = '\0';
  3944. nextc = makestrspace((strlen(s) + 1) * 8, cmdnextc);
  3945. p = s;
  3946. while ((c = *p++) != '\0') {
  3947. str = NULL;
  3948. switch (c) {
  3949. case CTLESC:
  3950. c = *p++;
  3951. break;
  3952. case CTLVAR:
  3953. subtype = *p++;
  3954. if ((subtype & VSTYPE) == VSLENGTH)
  3955. str = "${#";
  3956. else
  3957. str = "${";
  3958. if (!(subtype & VSQUOTE) == !(quoted & 1))
  3959. goto dostr;
  3960. quoted ^= 1;
  3961. c = '"';
  3962. break;
  3963. case CTLENDVAR:
  3964. str = "\"}" + !(quoted & 1);
  3965. quoted >>= 1;
  3966. subtype = 0;
  3967. goto dostr;
  3968. case CTLBACKQ:
  3969. str = "$(...)";
  3970. goto dostr;
  3971. case CTLBACKQ+CTLQUOTE:
  3972. str = "\"$(...)\"";
  3973. goto dostr;
  3974. #if ENABLE_SH_MATH_SUPPORT
  3975. case CTLARI:
  3976. str = "$((";
  3977. goto dostr;
  3978. case CTLENDARI:
  3979. str = "))";
  3980. goto dostr;
  3981. #endif
  3982. case CTLQUOTEMARK:
  3983. quoted ^= 1;
  3984. c = '"';
  3985. break;
  3986. case '=':
  3987. if (subtype == 0)
  3988. break;
  3989. if ((subtype & VSTYPE) != VSNORMAL)
  3990. quoted <<= 1;
  3991. str = vstype[subtype & VSTYPE];
  3992. if (subtype & VSNUL)
  3993. c = ':';
  3994. else
  3995. goto checkstr;
  3996. break;
  3997. case '\'':
  3998. case '\\':
  3999. case '"':
  4000. case '$':
  4001. /* These can only happen inside quotes */
  4002. cc[0] = c;
  4003. str = cc;
  4004. c = '\\';
  4005. break;
  4006. default:
  4007. break;
  4008. }
  4009. USTPUTC(c, nextc);
  4010. checkstr:
  4011. if (!str)
  4012. continue;
  4013. dostr:
  4014. while ((c = *str++) != '\0') {
  4015. USTPUTC(c, nextc);
  4016. }
  4017. } /* while *p++ not NUL */
  4018. if (quoted & 1) {
  4019. USTPUTC('"', nextc);
  4020. }
  4021. *nextc = 0;
  4022. cmdnextc = nextc;
  4023. }
  4024. /* cmdtxt() and cmdlist() call each other */
  4025. static void cmdtxt(union node *n);
  4026. static void
  4027. cmdlist(union node *np, int sep)
  4028. {
  4029. for (; np; np = np->narg.next) {
  4030. if (!sep)
  4031. cmdputs(" ");
  4032. cmdtxt(np);
  4033. if (sep && np->narg.next)
  4034. cmdputs(" ");
  4035. }
  4036. }
  4037. static void
  4038. cmdtxt(union node *n)
  4039. {
  4040. union node *np;
  4041. struct nodelist *lp;
  4042. const char *p;
  4043. if (!n)
  4044. return;
  4045. switch (n->type) {
  4046. default:
  4047. #if DEBUG
  4048. abort();
  4049. #endif
  4050. case NPIPE:
  4051. lp = n->npipe.cmdlist;
  4052. for (;;) {
  4053. cmdtxt(lp->n);
  4054. lp = lp->next;
  4055. if (!lp)
  4056. break;
  4057. cmdputs(" | ");
  4058. }
  4059. break;
  4060. case NSEMI:
  4061. p = "; ";
  4062. goto binop;
  4063. case NAND:
  4064. p = " && ";
  4065. goto binop;
  4066. case NOR:
  4067. p = " || ";
  4068. binop:
  4069. cmdtxt(n->nbinary.ch1);
  4070. cmdputs(p);
  4071. n = n->nbinary.ch2;
  4072. goto donode;
  4073. case NREDIR:
  4074. case NBACKGND:
  4075. n = n->nredir.n;
  4076. goto donode;
  4077. case NNOT:
  4078. cmdputs("!");
  4079. n = n->nnot.com;
  4080. donode:
  4081. cmdtxt(n);
  4082. break;
  4083. case NIF:
  4084. cmdputs("if ");
  4085. cmdtxt(n->nif.test);
  4086. cmdputs("; then ");
  4087. if (n->nif.elsepart) {
  4088. cmdtxt(n->nif.ifpart);
  4089. cmdputs("; else ");
  4090. n = n->nif.elsepart;
  4091. } else {
  4092. n = n->nif.ifpart;
  4093. }
  4094. p = "; fi";
  4095. goto dotail;
  4096. case NSUBSHELL:
  4097. cmdputs("(");
  4098. n = n->nredir.n;
  4099. p = ")";
  4100. goto dotail;
  4101. case NWHILE:
  4102. p = "while ";
  4103. goto until;
  4104. case NUNTIL:
  4105. p = "until ";
  4106. until:
  4107. cmdputs(p);
  4108. cmdtxt(n->nbinary.ch1);
  4109. n = n->nbinary.ch2;
  4110. p = "; done";
  4111. dodo:
  4112. cmdputs("; do ");
  4113. dotail:
  4114. cmdtxt(n);
  4115. goto dotail2;
  4116. case NFOR:
  4117. cmdputs("for ");
  4118. cmdputs(n->nfor.var);
  4119. cmdputs(" in ");
  4120. cmdlist(n->nfor.args, 1);
  4121. n = n->nfor.body;
  4122. p = "; done";
  4123. goto dodo;
  4124. case NDEFUN:
  4125. cmdputs(n->narg.text);
  4126. p = "() { ... }";
  4127. goto dotail2;
  4128. case NCMD:
  4129. cmdlist(n->ncmd.args, 1);
  4130. cmdlist(n->ncmd.redirect, 0);
  4131. break;
  4132. case NARG:
  4133. p = n->narg.text;
  4134. dotail2:
  4135. cmdputs(p);
  4136. break;
  4137. case NHERE:
  4138. case NXHERE:
  4139. p = "<<...";
  4140. goto dotail2;
  4141. case NCASE:
  4142. cmdputs("case ");
  4143. cmdputs(n->ncase.expr->narg.text);
  4144. cmdputs(" in ");
  4145. for (np = n->ncase.cases; np; np = np->nclist.next) {
  4146. cmdtxt(np->nclist.pattern);
  4147. cmdputs(") ");
  4148. cmdtxt(np->nclist.body);
  4149. cmdputs(";; ");
  4150. }
  4151. p = "esac";
  4152. goto dotail2;
  4153. case NTO:
  4154. p = ">";
  4155. goto redir;
  4156. case NCLOBBER:
  4157. p = ">|";
  4158. goto redir;
  4159. case NAPPEND:
  4160. p = ">>";
  4161. goto redir;
  4162. #if ENABLE_ASH_BASH_COMPAT
  4163. case NTO2:
  4164. #endif
  4165. case NTOFD:
  4166. p = ">&";
  4167. goto redir;
  4168. case NFROM:
  4169. p = "<";
  4170. goto redir;
  4171. case NFROMFD:
  4172. p = "<&";
  4173. goto redir;
  4174. case NFROMTO:
  4175. p = "<>";
  4176. redir:
  4177. cmdputs(utoa(n->nfile.fd));
  4178. cmdputs(p);
  4179. if (n->type == NTOFD || n->type == NFROMFD) {
  4180. cmdputs(utoa(n->ndup.dupfd));
  4181. break;
  4182. }
  4183. n = n->nfile.fname;
  4184. goto donode;
  4185. }
  4186. }
  4187. static char *
  4188. commandtext(union node *n)
  4189. {
  4190. char *name;
  4191. STARTSTACKSTR(cmdnextc);
  4192. cmdtxt(n);
  4193. name = stackblock();
  4194. TRACE(("commandtext: name %p, end %p\n\t\"%s\"\n",
  4195. name, cmdnextc, cmdnextc));
  4196. return ckstrdup(name);
  4197. }
  4198. #endif /* JOBS */
  4199. /*
  4200. * Fork off a subshell. If we are doing job control, give the subshell its
  4201. * own process group. Jp is a job structure that the job is to be added to.
  4202. * N is the command that will be evaluated by the child. Both jp and n may
  4203. * be NULL. The mode parameter can be one of the following:
  4204. * FORK_FG - Fork off a foreground process.
  4205. * FORK_BG - Fork off a background process.
  4206. * FORK_NOJOB - Like FORK_FG, but don't give the process its own
  4207. * process group even if job control is on.
  4208. *
  4209. * When job control is turned off, background processes have their standard
  4210. * input redirected to /dev/null (except for the second and later processes
  4211. * in a pipeline).
  4212. *
  4213. * Called with interrupts off.
  4214. */
  4215. /*
  4216. * Clear traps on a fork.
  4217. */
  4218. static void
  4219. clear_traps(void)
  4220. {
  4221. char **tp;
  4222. for (tp = trap; tp < &trap[NSIG]; tp++) {
  4223. if (*tp && **tp) { /* trap not NULL or "" (SIG_IGN) */
  4224. INT_OFF;
  4225. if (trap_ptr == trap)
  4226. free(*tp);
  4227. /* else: it "belongs" to trap_ptr vector, don't free */
  4228. *tp = NULL;
  4229. if ((tp - trap) != 0)
  4230. setsignal(tp - trap);
  4231. INT_ON;
  4232. }
  4233. }
  4234. may_have_traps = 0;
  4235. }
  4236. /* Lives far away from here, needed for forkchild */
  4237. static void closescript(void);
  4238. /* Called after fork(), in child */
  4239. static NOINLINE void
  4240. forkchild(struct job *jp, union node *n, int mode)
  4241. {
  4242. int oldlvl;
  4243. TRACE(("Child shell %d\n", getpid()));
  4244. oldlvl = shlvl;
  4245. shlvl++;
  4246. /* man bash: "Non-builtin commands run by bash have signal handlers
  4247. * set to the values inherited by the shell from its parent".
  4248. * Do we do it correctly? */
  4249. closescript();
  4250. if (mode == FORK_NOJOB /* is it `xxx` ? */
  4251. && n && n->type == NCMD /* is it single cmd? */
  4252. /* && n->ncmd.args->type == NARG - always true? */
  4253. && n->ncmd.args && strcmp(n->ncmd.args->narg.text, "trap") == 0
  4254. && n->ncmd.args->narg.next == NULL /* "trap" with no arguments */
  4255. /* && n->ncmd.args->narg.backquote == NULL - do we need to check this? */
  4256. ) {
  4257. TRACE(("Trap hack\n"));
  4258. /* Awful hack for `trap` or $(trap).
  4259. *
  4260. * http://www.opengroup.org/onlinepubs/009695399/utilities/trap.html
  4261. * contains an example where "trap" is executed in a subshell:
  4262. *
  4263. * save_traps=$(trap)
  4264. * ...
  4265. * eval "$save_traps"
  4266. *
  4267. * Standard does not say that "trap" in subshell shall print
  4268. * parent shell's traps. It only says that its output
  4269. * must have suitable form, but then, in the above example
  4270. * (which is not supposed to be normative), it implies that.
  4271. *
  4272. * bash (and probably other shell) does implement it
  4273. * (traps are reset to defaults, but "trap" still shows them),
  4274. * but as a result, "trap" logic is hopelessly messed up:
  4275. *
  4276. * # trap
  4277. * trap -- 'echo Ho' SIGWINCH <--- we have a handler
  4278. * # (trap) <--- trap is in subshell - no output (correct, traps are reset)
  4279. * # true | trap <--- trap is in subshell - no output (ditto)
  4280. * # echo `true | trap` <--- in subshell - output (but traps are reset!)
  4281. * trap -- 'echo Ho' SIGWINCH
  4282. * # echo `(trap)` <--- in subshell in subshell - output
  4283. * trap -- 'echo Ho' SIGWINCH
  4284. * # echo `true | (trap)` <--- in subshell in subshell in subshell - output!
  4285. * trap -- 'echo Ho' SIGWINCH
  4286. *
  4287. * The rules when to forget and when to not forget traps
  4288. * get really complex and nonsensical.
  4289. *
  4290. * Our solution: ONLY bare $(trap) or `trap` is special.
  4291. */
  4292. /* Save trap handler strings for trap builtin to print */
  4293. trap_ptr = memcpy(xmalloc(sizeof(trap)), trap, sizeof(trap));
  4294. /* Fall through into clearing traps */
  4295. }
  4296. clear_traps();
  4297. #if JOBS
  4298. /* do job control only in root shell */
  4299. doing_jobctl = 0;
  4300. if (mode != FORK_NOJOB && jp->jobctl && oldlvl == 0) {
  4301. pid_t pgrp;
  4302. if (jp->nprocs == 0)
  4303. pgrp = getpid();
  4304. else
  4305. pgrp = jp->ps[0].ps_pid;
  4306. /* this can fail because we are doing it in the parent also */
  4307. setpgid(0, pgrp);
  4308. if (mode == FORK_FG)
  4309. xtcsetpgrp(ttyfd, pgrp);
  4310. setsignal(SIGTSTP);
  4311. setsignal(SIGTTOU);
  4312. } else
  4313. #endif
  4314. if (mode == FORK_BG) {
  4315. /* man bash: "When job control is not in effect,
  4316. * asynchronous commands ignore SIGINT and SIGQUIT" */
  4317. ignoresig(SIGINT);
  4318. ignoresig(SIGQUIT);
  4319. if (jp->nprocs == 0) {
  4320. close(0);
  4321. if (open(bb_dev_null, O_RDONLY) != 0)
  4322. ash_msg_and_raise_error("can't open '%s'", bb_dev_null);
  4323. }
  4324. }
  4325. if (oldlvl == 0) {
  4326. if (iflag) { /* why if iflag only? */
  4327. setsignal(SIGINT);
  4328. setsignal(SIGTERM);
  4329. }
  4330. /* man bash:
  4331. * "In all cases, bash ignores SIGQUIT. Non-builtin
  4332. * commands run by bash have signal handlers
  4333. * set to the values inherited by the shell
  4334. * from its parent".
  4335. * Take care of the second rule: */
  4336. setsignal(SIGQUIT);
  4337. }
  4338. #if JOBS
  4339. if (n && n->type == NCMD
  4340. && n->ncmd.args && strcmp(n->ncmd.args->narg.text, "jobs") == 0
  4341. ) {
  4342. TRACE(("Job hack\n"));
  4343. /* "jobs": we do not want to clear job list for it,
  4344. * instead we remove only _its_ own_ job from job list.
  4345. * This makes "jobs .... | cat" more useful.
  4346. */
  4347. freejob(curjob);
  4348. return;
  4349. }
  4350. #endif
  4351. for (jp = curjob; jp; jp = jp->prev_job)
  4352. freejob(jp);
  4353. jobless = 0;
  4354. }
  4355. /* Called after fork(), in parent */
  4356. #if !JOBS
  4357. #define forkparent(jp, n, mode, pid) forkparent(jp, mode, pid)
  4358. #endif
  4359. static void
  4360. forkparent(struct job *jp, union node *n, int mode, pid_t pid)
  4361. {
  4362. TRACE(("In parent shell: child = %d\n", pid));
  4363. if (!jp) {
  4364. while (jobless && dowait(DOWAIT_NONBLOCK, NULL) > 0)
  4365. continue;
  4366. jobless++;
  4367. return;
  4368. }
  4369. #if JOBS
  4370. if (mode != FORK_NOJOB && jp->jobctl) {
  4371. int pgrp;
  4372. if (jp->nprocs == 0)
  4373. pgrp = pid;
  4374. else
  4375. pgrp = jp->ps[0].ps_pid;
  4376. /* This can fail because we are doing it in the child also */
  4377. setpgid(pid, pgrp);
  4378. }
  4379. #endif
  4380. if (mode == FORK_BG) {
  4381. backgndpid = pid; /* set $! */
  4382. set_curjob(jp, CUR_RUNNING);
  4383. }
  4384. if (jp) {
  4385. struct procstat *ps = &jp->ps[jp->nprocs++];
  4386. ps->ps_pid = pid;
  4387. ps->ps_status = -1;
  4388. ps->ps_cmd = nullstr;
  4389. #if JOBS
  4390. if (doing_jobctl && n)
  4391. ps->ps_cmd = commandtext(n);
  4392. #endif
  4393. }
  4394. }
  4395. static int
  4396. forkshell(struct job *jp, union node *n, int mode)
  4397. {
  4398. int pid;
  4399. TRACE(("forkshell(%%%d, %p, %d) called\n", jobno(jp), n, mode));
  4400. pid = fork();
  4401. if (pid < 0) {
  4402. TRACE(("Fork failed, errno=%d", errno));
  4403. if (jp)
  4404. freejob(jp);
  4405. ash_msg_and_raise_error("can't fork");
  4406. }
  4407. if (pid == 0) {
  4408. CLEAR_RANDOM_T(&random_gen); /* or else $RANDOM repeats in child */
  4409. forkchild(jp, n, mode);
  4410. } else {
  4411. forkparent(jp, n, mode, pid);
  4412. }
  4413. return pid;
  4414. }
  4415. /*
  4416. * Wait for job to finish.
  4417. *
  4418. * Under job control we have the problem that while a child process
  4419. * is running interrupts generated by the user are sent to the child
  4420. * but not to the shell. This means that an infinite loop started by
  4421. * an interactive user may be hard to kill. With job control turned off,
  4422. * an interactive user may place an interactive program inside a loop.
  4423. * If the interactive program catches interrupts, the user doesn't want
  4424. * these interrupts to also abort the loop. The approach we take here
  4425. * is to have the shell ignore interrupt signals while waiting for a
  4426. * foreground process to terminate, and then send itself an interrupt
  4427. * signal if the child process was terminated by an interrupt signal.
  4428. * Unfortunately, some programs want to do a bit of cleanup and then
  4429. * exit on interrupt; unless these processes terminate themselves by
  4430. * sending a signal to themselves (instead of calling exit) they will
  4431. * confuse this approach.
  4432. *
  4433. * Called with interrupts off.
  4434. */
  4435. static int
  4436. waitforjob(struct job *jp)
  4437. {
  4438. int st;
  4439. TRACE(("waitforjob(%%%d) called\n", jobno(jp)));
  4440. INT_OFF;
  4441. while (jp->state == JOBRUNNING) {
  4442. /* In non-interactive shells, we _can_ get
  4443. * a keyboard signal here and be EINTRed,
  4444. * but we just loop back, waiting for command to complete.
  4445. *
  4446. * man bash:
  4447. * "If bash is waiting for a command to complete and receives
  4448. * a signal for which a trap has been set, the trap
  4449. * will not be executed until the command completes."
  4450. *
  4451. * Reality is that even if trap is not set, bash
  4452. * will not act on the signal until command completes.
  4453. * Try this. sleep5intoff.c:
  4454. * #include <signal.h>
  4455. * #include <unistd.h>
  4456. * int main() {
  4457. * sigset_t set;
  4458. * sigemptyset(&set);
  4459. * sigaddset(&set, SIGINT);
  4460. * sigaddset(&set, SIGQUIT);
  4461. * sigprocmask(SIG_BLOCK, &set, NULL);
  4462. * sleep(5);
  4463. * return 0;
  4464. * }
  4465. * $ bash -c './sleep5intoff; echo hi'
  4466. * ^C^C^C^C <--- pressing ^C once a second
  4467. * $ _
  4468. * $ bash -c './sleep5intoff; echo hi'
  4469. * ^\^\^\^\hi <--- pressing ^\ (SIGQUIT)
  4470. * $ _
  4471. */
  4472. dowait(DOWAIT_BLOCK, jp);
  4473. }
  4474. INT_ON;
  4475. st = getstatus(jp);
  4476. #if JOBS
  4477. if (jp->jobctl) {
  4478. xtcsetpgrp(ttyfd, rootpid);
  4479. /*
  4480. * This is truly gross.
  4481. * If we're doing job control, then we did a TIOCSPGRP which
  4482. * caused us (the shell) to no longer be in the controlling
  4483. * session -- so we wouldn't have seen any ^C/SIGINT. So, we
  4484. * intuit from the subprocess exit status whether a SIGINT
  4485. * occurred, and if so interrupt ourselves. Yuck. - mycroft
  4486. */
  4487. if (jp->sigint) /* TODO: do the same with all signals */
  4488. raise(SIGINT); /* ... by raise(jp->sig) instead? */
  4489. }
  4490. if (jp->state == JOBDONE)
  4491. #endif
  4492. freejob(jp);
  4493. return st;
  4494. }
  4495. /*
  4496. * return 1 if there are stopped jobs, otherwise 0
  4497. */
  4498. static int
  4499. stoppedjobs(void)
  4500. {
  4501. struct job *jp;
  4502. int retval;
  4503. retval = 0;
  4504. if (job_warning)
  4505. goto out;
  4506. jp = curjob;
  4507. if (jp && jp->state == JOBSTOPPED) {
  4508. out2str("You have stopped jobs.\n");
  4509. job_warning = 2;
  4510. retval++;
  4511. }
  4512. out:
  4513. return retval;
  4514. }
  4515. /* ============ redir.c
  4516. *
  4517. * Code for dealing with input/output redirection.
  4518. */
  4519. #undef EMPTY
  4520. #undef CLOSED
  4521. #define EMPTY -2 /* marks an unused slot in redirtab */
  4522. #define CLOSED -3 /* marks a slot of previously-closed fd */
  4523. /*
  4524. * Open a file in noclobber mode.
  4525. * The code was copied from bash.
  4526. */
  4527. static int
  4528. noclobberopen(const char *fname)
  4529. {
  4530. int r, fd;
  4531. struct stat finfo, finfo2;
  4532. /*
  4533. * If the file exists and is a regular file, return an error
  4534. * immediately.
  4535. */
  4536. r = stat(fname, &finfo);
  4537. if (r == 0 && S_ISREG(finfo.st_mode)) {
  4538. errno = EEXIST;
  4539. return -1;
  4540. }
  4541. /*
  4542. * If the file was not present (r != 0), make sure we open it
  4543. * exclusively so that if it is created before we open it, our open
  4544. * will fail. Make sure that we do not truncate an existing file.
  4545. * Note that we don't turn on O_EXCL unless the stat failed -- if the
  4546. * file was not a regular file, we leave O_EXCL off.
  4547. */
  4548. if (r != 0)
  4549. return open(fname, O_WRONLY|O_CREAT|O_EXCL, 0666);
  4550. fd = open(fname, O_WRONLY|O_CREAT, 0666);
  4551. /* If the open failed, return the file descriptor right away. */
  4552. if (fd < 0)
  4553. return fd;
  4554. /*
  4555. * OK, the open succeeded, but the file may have been changed from a
  4556. * non-regular file to a regular file between the stat and the open.
  4557. * We are assuming that the O_EXCL open handles the case where FILENAME
  4558. * did not exist and is symlinked to an existing file between the stat
  4559. * and open.
  4560. */
  4561. /*
  4562. * If we can open it and fstat the file descriptor, and neither check
  4563. * revealed that it was a regular file, and the file has not been
  4564. * replaced, return the file descriptor.
  4565. */
  4566. if (fstat(fd, &finfo2) == 0
  4567. && !S_ISREG(finfo2.st_mode)
  4568. && finfo.st_dev == finfo2.st_dev
  4569. && finfo.st_ino == finfo2.st_ino
  4570. ) {
  4571. return fd;
  4572. }
  4573. /* The file has been replaced. badness. */
  4574. close(fd);
  4575. errno = EEXIST;
  4576. return -1;
  4577. }
  4578. /*
  4579. * Handle here documents. Normally we fork off a process to write the
  4580. * data to a pipe. If the document is short, we can stuff the data in
  4581. * the pipe without forking.
  4582. */
  4583. /* openhere needs this forward reference */
  4584. static void expandhere(union node *arg, int fd);
  4585. static int
  4586. openhere(union node *redir)
  4587. {
  4588. int pip[2];
  4589. size_t len = 0;
  4590. if (pipe(pip) < 0)
  4591. ash_msg_and_raise_error("pipe call failed");
  4592. if (redir->type == NHERE) {
  4593. len = strlen(redir->nhere.doc->narg.text);
  4594. if (len <= PIPE_BUF) {
  4595. full_write(pip[1], redir->nhere.doc->narg.text, len);
  4596. goto out;
  4597. }
  4598. }
  4599. if (forkshell((struct job *)NULL, (union node *)NULL, FORK_NOJOB) == 0) {
  4600. /* child */
  4601. close(pip[0]);
  4602. ignoresig(SIGINT); //signal(SIGINT, SIG_IGN);
  4603. ignoresig(SIGQUIT); //signal(SIGQUIT, SIG_IGN);
  4604. ignoresig(SIGHUP); //signal(SIGHUP, SIG_IGN);
  4605. ignoresig(SIGTSTP); //signal(SIGTSTP, SIG_IGN);
  4606. signal(SIGPIPE, SIG_DFL);
  4607. if (redir->type == NHERE)
  4608. full_write(pip[1], redir->nhere.doc->narg.text, len);
  4609. else /* NXHERE */
  4610. expandhere(redir->nhere.doc, pip[1]);
  4611. _exit(EXIT_SUCCESS);
  4612. }
  4613. out:
  4614. close(pip[1]);
  4615. return pip[0];
  4616. }
  4617. static int
  4618. openredirect(union node *redir)
  4619. {
  4620. char *fname;
  4621. int f;
  4622. fname = redir->nfile.expfname;
  4623. switch (redir->nfile.type) {
  4624. case NFROM:
  4625. f = open(fname, O_RDONLY);
  4626. if (f < 0)
  4627. goto eopen;
  4628. break;
  4629. case NFROMTO:
  4630. f = open(fname, O_RDWR|O_CREAT, 0666);
  4631. if (f < 0)
  4632. goto ecreate;
  4633. break;
  4634. case NTO:
  4635. #if ENABLE_ASH_BASH_COMPAT
  4636. case NTO2:
  4637. #endif
  4638. /* Take care of noclobber mode. */
  4639. if (Cflag) {
  4640. f = noclobberopen(fname);
  4641. if (f < 0)
  4642. goto ecreate;
  4643. break;
  4644. }
  4645. /* FALLTHROUGH */
  4646. case NCLOBBER:
  4647. f = open(fname, O_WRONLY|O_CREAT|O_TRUNC, 0666);
  4648. if (f < 0)
  4649. goto ecreate;
  4650. break;
  4651. case NAPPEND:
  4652. f = open(fname, O_WRONLY|O_CREAT|O_APPEND, 0666);
  4653. if (f < 0)
  4654. goto ecreate;
  4655. break;
  4656. default:
  4657. #if DEBUG
  4658. abort();
  4659. #endif
  4660. /* Fall through to eliminate warning. */
  4661. /* Our single caller does this itself */
  4662. // case NTOFD:
  4663. // case NFROMFD:
  4664. // f = -1;
  4665. // break;
  4666. case NHERE:
  4667. case NXHERE:
  4668. f = openhere(redir);
  4669. break;
  4670. }
  4671. return f;
  4672. ecreate:
  4673. ash_msg_and_raise_error("can't create %s: %s", fname, errmsg(errno, "nonexistent directory"));
  4674. eopen:
  4675. ash_msg_and_raise_error("can't open %s: %s", fname, errmsg(errno, "no such file"));
  4676. }
  4677. /*
  4678. * Copy a file descriptor to be >= to. Returns -1
  4679. * if the source file descriptor is closed, EMPTY if there are no unused
  4680. * file descriptors left.
  4681. */
  4682. /* 0x800..00: bit to set in "to" to request dup2 instead of fcntl(F_DUPFD).
  4683. * old code was doing close(to) prior to copyfd() to achieve the same */
  4684. enum {
  4685. COPYFD_EXACT = (int)~(INT_MAX),
  4686. COPYFD_RESTORE = (int)((unsigned)COPYFD_EXACT >> 1),
  4687. };
  4688. static int
  4689. copyfd(int from, int to)
  4690. {
  4691. int newfd;
  4692. if (to & COPYFD_EXACT) {
  4693. to &= ~COPYFD_EXACT;
  4694. /*if (from != to)*/
  4695. newfd = dup2(from, to);
  4696. } else {
  4697. newfd = fcntl(from, F_DUPFD, to);
  4698. }
  4699. if (newfd < 0) {
  4700. if (errno == EMFILE)
  4701. return EMPTY;
  4702. /* Happens when source fd is not open: try "echo >&99" */
  4703. ash_msg_and_raise_error("%d: %m", from);
  4704. }
  4705. return newfd;
  4706. }
  4707. /* Struct def and variable are moved down to the first usage site */
  4708. struct two_fd_t {
  4709. int orig, copy;
  4710. };
  4711. struct redirtab {
  4712. struct redirtab *next;
  4713. int nullredirs;
  4714. int pair_count;
  4715. struct two_fd_t two_fd[];
  4716. };
  4717. #define redirlist (G_var.redirlist)
  4718. static int need_to_remember(struct redirtab *rp, int fd)
  4719. {
  4720. int i;
  4721. if (!rp) /* remembering was not requested */
  4722. return 0;
  4723. for (i = 0; i < rp->pair_count; i++) {
  4724. if (rp->two_fd[i].orig == fd) {
  4725. /* already remembered */
  4726. return 0;
  4727. }
  4728. }
  4729. return 1;
  4730. }
  4731. /* "hidden" fd is a fd used to read scripts, or a copy of such */
  4732. static int is_hidden_fd(struct redirtab *rp, int fd)
  4733. {
  4734. int i;
  4735. struct parsefile *pf;
  4736. if (fd == -1)
  4737. return 0;
  4738. /* Check open scripts' fds */
  4739. pf = g_parsefile;
  4740. while (pf) {
  4741. /* We skip pf_fd == 0 case because of the following case:
  4742. * $ ash # running ash interactively
  4743. * $ . ./script.sh
  4744. * and in script.sh: "exec 9>&0".
  4745. * Even though top-level pf_fd _is_ 0,
  4746. * it's still ok to use it: "read" builtin uses it,
  4747. * why should we cripple "exec" builtin?
  4748. */
  4749. if (pf->pf_fd > 0 && fd == pf->pf_fd) {
  4750. return 1;
  4751. }
  4752. pf = pf->prev;
  4753. }
  4754. if (!rp)
  4755. return 0;
  4756. /* Check saved fds of redirects */
  4757. fd |= COPYFD_RESTORE;
  4758. for (i = 0; i < rp->pair_count; i++) {
  4759. if (rp->two_fd[i].copy == fd) {
  4760. return 1;
  4761. }
  4762. }
  4763. return 0;
  4764. }
  4765. /*
  4766. * Process a list of redirection commands. If the REDIR_PUSH flag is set,
  4767. * old file descriptors are stashed away so that the redirection can be
  4768. * undone by calling popredir.
  4769. */
  4770. /* flags passed to redirect */
  4771. #define REDIR_PUSH 01 /* save previous values of file descriptors */
  4772. #define REDIR_SAVEFD2 03 /* set preverrout */
  4773. static void
  4774. redirect(union node *redir, int flags)
  4775. {
  4776. struct redirtab *sv;
  4777. int sv_pos;
  4778. int i;
  4779. int fd;
  4780. int newfd;
  4781. int copied_fd2 = -1;
  4782. g_nullredirs++;
  4783. if (!redir) {
  4784. return;
  4785. }
  4786. sv = NULL;
  4787. sv_pos = 0;
  4788. INT_OFF;
  4789. if (flags & REDIR_PUSH) {
  4790. union node *tmp = redir;
  4791. do {
  4792. sv_pos++;
  4793. #if ENABLE_ASH_BASH_COMPAT
  4794. if (tmp->nfile.type == NTO2)
  4795. sv_pos++;
  4796. #endif
  4797. tmp = tmp->nfile.next;
  4798. } while (tmp);
  4799. sv = ckmalloc(sizeof(*sv) + sv_pos * sizeof(sv->two_fd[0]));
  4800. sv->next = redirlist;
  4801. sv->pair_count = sv_pos;
  4802. redirlist = sv;
  4803. sv->nullredirs = g_nullredirs - 1;
  4804. g_nullredirs = 0;
  4805. while (sv_pos > 0) {
  4806. sv_pos--;
  4807. sv->two_fd[sv_pos].orig = sv->two_fd[sv_pos].copy = EMPTY;
  4808. }
  4809. }
  4810. do {
  4811. int right_fd = -1;
  4812. fd = redir->nfile.fd;
  4813. if (redir->nfile.type == NTOFD || redir->nfile.type == NFROMFD) {
  4814. right_fd = redir->ndup.dupfd;
  4815. //bb_error_msg("doing %d > %d", fd, right_fd);
  4816. /* redirect from/to same file descriptor? */
  4817. if (right_fd == fd)
  4818. continue;
  4819. /* "echo >&10" and 10 is a fd opened to a sh script? */
  4820. if (is_hidden_fd(sv, right_fd)) {
  4821. errno = EBADF; /* as if it is closed */
  4822. ash_msg_and_raise_error("%d: %m", right_fd);
  4823. }
  4824. newfd = -1;
  4825. } else {
  4826. newfd = openredirect(redir); /* always >= 0 */
  4827. if (fd == newfd) {
  4828. /* Descriptor wasn't open before redirect.
  4829. * Mark it for close in the future */
  4830. if (need_to_remember(sv, fd)) {
  4831. goto remember_to_close;
  4832. }
  4833. continue;
  4834. }
  4835. }
  4836. #if ENABLE_ASH_BASH_COMPAT
  4837. redirect_more:
  4838. #endif
  4839. if (need_to_remember(sv, fd)) {
  4840. /* Copy old descriptor */
  4841. /* Careful to not accidentally "save"
  4842. * to the same fd as right side fd in N>&M */
  4843. int minfd = right_fd < 10 ? 10 : right_fd + 1;
  4844. i = fcntl(fd, F_DUPFD, minfd);
  4845. /* You'd expect copy to be CLOEXECed. Currently these extra "saved" fds
  4846. * are closed in popredir() in the child, preventing them from leaking
  4847. * into child. (popredir() also cleans up the mess in case of failures)
  4848. */
  4849. if (i == -1) {
  4850. i = errno;
  4851. if (i != EBADF) {
  4852. /* Strange error (e.g. "too many files" EMFILE?) */
  4853. if (newfd >= 0)
  4854. close(newfd);
  4855. errno = i;
  4856. ash_msg_and_raise_error("%d: %m", fd);
  4857. /* NOTREACHED */
  4858. }
  4859. /* EBADF: it is not open - good, remember to close it */
  4860. remember_to_close:
  4861. i = CLOSED;
  4862. } else { /* fd is open, save its copy */
  4863. /* "exec fd>&-" should not close fds
  4864. * which point to script file(s).
  4865. * Force them to be restored afterwards */
  4866. if (is_hidden_fd(sv, fd))
  4867. i |= COPYFD_RESTORE;
  4868. }
  4869. if (fd == 2)
  4870. copied_fd2 = i;
  4871. sv->two_fd[sv_pos].orig = fd;
  4872. sv->two_fd[sv_pos].copy = i;
  4873. sv_pos++;
  4874. }
  4875. if (newfd < 0) {
  4876. /* NTOFD/NFROMFD: copy redir->ndup.dupfd to fd */
  4877. if (redir->ndup.dupfd < 0) { /* "fd>&-" */
  4878. /* Don't want to trigger debugging */
  4879. if (fd != -1)
  4880. close(fd);
  4881. } else {
  4882. copyfd(redir->ndup.dupfd, fd | COPYFD_EXACT);
  4883. }
  4884. } else if (fd != newfd) { /* move newfd to fd */
  4885. copyfd(newfd, fd | COPYFD_EXACT);
  4886. #if ENABLE_ASH_BASH_COMPAT
  4887. if (!(redir->nfile.type == NTO2 && fd == 2))
  4888. #endif
  4889. close(newfd);
  4890. }
  4891. #if ENABLE_ASH_BASH_COMPAT
  4892. if (redir->nfile.type == NTO2 && fd == 1) {
  4893. /* We already redirected it to fd 1, now copy it to 2 */
  4894. newfd = 1;
  4895. fd = 2;
  4896. goto redirect_more;
  4897. }
  4898. #endif
  4899. } while ((redir = redir->nfile.next) != NULL);
  4900. INT_ON;
  4901. if ((flags & REDIR_SAVEFD2) && copied_fd2 >= 0)
  4902. preverrout_fd = copied_fd2;
  4903. }
  4904. /*
  4905. * Undo the effects of the last redirection.
  4906. */
  4907. static void
  4908. popredir(int drop, int restore)
  4909. {
  4910. struct redirtab *rp;
  4911. int i;
  4912. if (--g_nullredirs >= 0)
  4913. return;
  4914. INT_OFF;
  4915. rp = redirlist;
  4916. for (i = 0; i < rp->pair_count; i++) {
  4917. int fd = rp->two_fd[i].orig;
  4918. int copy = rp->two_fd[i].copy;
  4919. if (copy == CLOSED) {
  4920. if (!drop)
  4921. close(fd);
  4922. continue;
  4923. }
  4924. if (copy != EMPTY) {
  4925. if (!drop || (restore && (copy & COPYFD_RESTORE))) {
  4926. copy &= ~COPYFD_RESTORE;
  4927. /*close(fd);*/
  4928. copyfd(copy, fd | COPYFD_EXACT);
  4929. }
  4930. close(copy & ~COPYFD_RESTORE);
  4931. }
  4932. }
  4933. redirlist = rp->next;
  4934. g_nullredirs = rp->nullredirs;
  4935. free(rp);
  4936. INT_ON;
  4937. }
  4938. /*
  4939. * Undo all redirections. Called on error or interrupt.
  4940. */
  4941. /*
  4942. * Discard all saved file descriptors.
  4943. */
  4944. static void
  4945. clearredir(int drop)
  4946. {
  4947. for (;;) {
  4948. g_nullredirs = 0;
  4949. if (!redirlist)
  4950. break;
  4951. popredir(drop, /*restore:*/ 0);
  4952. }
  4953. }
  4954. static int
  4955. redirectsafe(union node *redir, int flags)
  4956. {
  4957. int err;
  4958. volatile int saveint;
  4959. struct jmploc *volatile savehandler = exception_handler;
  4960. struct jmploc jmploc;
  4961. SAVE_INT(saveint);
  4962. /* "echo 9>/dev/null; echo >&9; echo result: $?" - result should be 1, not 2! */
  4963. err = setjmp(jmploc.loc); // huh?? was = setjmp(jmploc.loc) * 2;
  4964. if (!err) {
  4965. exception_handler = &jmploc;
  4966. redirect(redir, flags);
  4967. }
  4968. exception_handler = savehandler;
  4969. if (err && exception_type != EXERROR)
  4970. longjmp(exception_handler->loc, 1);
  4971. RESTORE_INT(saveint);
  4972. return err;
  4973. }
  4974. /* ============ Routines to expand arguments to commands
  4975. *
  4976. * We have to deal with backquotes, shell variables, and file metacharacters.
  4977. */
  4978. #if ENABLE_SH_MATH_SUPPORT
  4979. static arith_t
  4980. ash_arith(const char *s)
  4981. {
  4982. arith_state_t math_state;
  4983. arith_t result;
  4984. math_state.lookupvar = lookupvar;
  4985. math_state.setvar = setvar2;
  4986. //math_state.endofname = endofname;
  4987. INT_OFF;
  4988. result = arith(&math_state, s);
  4989. if (math_state.errmsg)
  4990. ash_msg_and_raise_error(math_state.errmsg);
  4991. INT_ON;
  4992. return result;
  4993. }
  4994. #endif
  4995. /*
  4996. * expandarg flags
  4997. */
  4998. #define EXP_FULL 0x1 /* perform word splitting & file globbing */
  4999. #define EXP_TILDE 0x2 /* do normal tilde expansion */
  5000. #define EXP_VARTILDE 0x4 /* expand tildes in an assignment */
  5001. #define EXP_REDIR 0x8 /* file glob for a redirection (1 match only) */
  5002. #define EXP_CASE 0x10 /* keeps quotes around for CASE pattern */
  5003. #define EXP_RECORD 0x20 /* need to record arguments for ifs breakup */
  5004. #define EXP_VARTILDE2 0x40 /* expand tildes after colons only */
  5005. #define EXP_WORD 0x80 /* expand word in parameter expansion */
  5006. #define EXP_QWORD 0x100 /* expand word in quoted parameter expansion */
  5007. /*
  5008. * rmescape() flags
  5009. */
  5010. #define RMESCAPE_ALLOC 0x1 /* Allocate a new string */
  5011. #define RMESCAPE_GLOB 0x2 /* Add backslashes for glob */
  5012. #define RMESCAPE_QUOTED 0x4 /* Remove CTLESC unless in quotes */
  5013. #define RMESCAPE_GROW 0x8 /* Grow strings instead of stalloc */
  5014. #define RMESCAPE_HEAP 0x10 /* Malloc strings instead of stalloc */
  5015. /*
  5016. * Structure specifying which parts of the string should be searched
  5017. * for IFS characters.
  5018. */
  5019. struct ifsregion {
  5020. struct ifsregion *next; /* next region in list */
  5021. int begoff; /* offset of start of region */
  5022. int endoff; /* offset of end of region */
  5023. int nulonly; /* search for nul bytes only */
  5024. };
  5025. struct arglist {
  5026. struct strlist *list;
  5027. struct strlist **lastp;
  5028. };
  5029. /* output of current string */
  5030. static char *expdest;
  5031. /* list of back quote expressions */
  5032. static struct nodelist *argbackq;
  5033. /* first struct in list of ifs regions */
  5034. static struct ifsregion ifsfirst;
  5035. /* last struct in list */
  5036. static struct ifsregion *ifslastp;
  5037. /* holds expanded arg list */
  5038. static struct arglist exparg;
  5039. /*
  5040. * Our own itoa().
  5041. */
  5042. #if !ENABLE_SH_MATH_SUPPORT
  5043. /* cvtnum() is used even if math support is off (to prepare $? values and such) */
  5044. typedef long arith_t;
  5045. # define ARITH_FMT "%ld"
  5046. #endif
  5047. static int
  5048. cvtnum(arith_t num)
  5049. {
  5050. int len;
  5051. expdest = makestrspace(32, expdest);
  5052. len = fmtstr(expdest, 32, ARITH_FMT, num);
  5053. STADJUST(len, expdest);
  5054. return len;
  5055. }
  5056. static size_t
  5057. esclen(const char *start, const char *p)
  5058. {
  5059. size_t esc = 0;
  5060. while (p > start && (unsigned char)*--p == CTLESC) {
  5061. esc++;
  5062. }
  5063. return esc;
  5064. }
  5065. /*
  5066. * Remove any CTLESC characters from a string.
  5067. */
  5068. static char *
  5069. rmescapes(char *str, int flag)
  5070. {
  5071. static const char qchars[] ALIGN1 = { CTLESC, CTLQUOTEMARK, '\0' };
  5072. char *p, *q, *r;
  5073. unsigned inquotes;
  5074. unsigned protect_against_glob;
  5075. unsigned globbing;
  5076. p = strpbrk(str, qchars);
  5077. if (!p)
  5078. return str;
  5079. q = p;
  5080. r = str;
  5081. if (flag & RMESCAPE_ALLOC) {
  5082. size_t len = p - str;
  5083. size_t fulllen = len + strlen(p) + 1;
  5084. if (flag & RMESCAPE_GROW) {
  5085. int strloc = str - (char *)stackblock();
  5086. r = makestrspace(fulllen, expdest);
  5087. /* p and str may be invalidated by makestrspace */
  5088. str = (char *)stackblock() + strloc;
  5089. p = str + len;
  5090. } else if (flag & RMESCAPE_HEAP) {
  5091. r = ckmalloc(fulllen);
  5092. } else {
  5093. r = stalloc(fulllen);
  5094. }
  5095. q = r;
  5096. if (len > 0) {
  5097. q = (char *)memcpy(q, str, len) + len;
  5098. }
  5099. }
  5100. inquotes = (flag & RMESCAPE_QUOTED) ^ RMESCAPE_QUOTED;
  5101. globbing = flag & RMESCAPE_GLOB;
  5102. protect_against_glob = globbing;
  5103. while (*p) {
  5104. if ((unsigned char)*p == CTLQUOTEMARK) {
  5105. // TODO: if no RMESCAPE_QUOTED in flags, inquotes never becomes 0
  5106. // (alternates between RMESCAPE_QUOTED and ~RMESCAPE_QUOTED). Is it ok?
  5107. // Note: both inquotes and protect_against_glob only affect whether
  5108. // CTLESC,<ch> gets converted to <ch> or to \<ch>
  5109. inquotes = ~inquotes;
  5110. p++;
  5111. protect_against_glob = globbing;
  5112. continue;
  5113. }
  5114. if (*p == '\\') {
  5115. /* naked back slash */
  5116. protect_against_glob = 0;
  5117. goto copy;
  5118. }
  5119. if ((unsigned char)*p == CTLESC) {
  5120. p++;
  5121. if (protect_against_glob && inquotes && *p != '/') {
  5122. *q++ = '\\';
  5123. }
  5124. }
  5125. protect_against_glob = globbing;
  5126. copy:
  5127. *q++ = *p++;
  5128. }
  5129. *q = '\0';
  5130. if (flag & RMESCAPE_GROW) {
  5131. expdest = r;
  5132. STADJUST(q - r + 1, expdest);
  5133. }
  5134. return r;
  5135. }
  5136. #define pmatch(a, b) !fnmatch((a), (b), 0)
  5137. /*
  5138. * Prepare a pattern for a expmeta (internal glob(3)) call.
  5139. *
  5140. * Returns an stalloced string.
  5141. */
  5142. static char *
  5143. preglob(const char *pattern, int quoted, int flag)
  5144. {
  5145. flag |= RMESCAPE_GLOB;
  5146. if (quoted) {
  5147. flag |= RMESCAPE_QUOTED;
  5148. }
  5149. return rmescapes((char *)pattern, flag);
  5150. }
  5151. /*
  5152. * Put a string on the stack.
  5153. */
  5154. static void
  5155. memtodest(const char *p, size_t len, int syntax, int quotes)
  5156. {
  5157. char *q = expdest;
  5158. q = makestrspace(quotes ? len * 2 : len, q);
  5159. while (len--) {
  5160. unsigned char c = *p++;
  5161. if (c == '\0')
  5162. continue;
  5163. if (quotes) {
  5164. int n = SIT(c, syntax);
  5165. if (n == CCTL || n == CBACK)
  5166. USTPUTC(CTLESC, q);
  5167. }
  5168. USTPUTC(c, q);
  5169. }
  5170. expdest = q;
  5171. }
  5172. static void
  5173. strtodest(const char *p, int syntax, int quotes)
  5174. {
  5175. memtodest(p, strlen(p), syntax, quotes);
  5176. }
  5177. /*
  5178. * Record the fact that we have to scan this region of the
  5179. * string for IFS characters.
  5180. */
  5181. static void
  5182. recordregion(int start, int end, int nulonly)
  5183. {
  5184. struct ifsregion *ifsp;
  5185. if (ifslastp == NULL) {
  5186. ifsp = &ifsfirst;
  5187. } else {
  5188. INT_OFF;
  5189. ifsp = ckzalloc(sizeof(*ifsp));
  5190. /*ifsp->next = NULL; - ckzalloc did it */
  5191. ifslastp->next = ifsp;
  5192. INT_ON;
  5193. }
  5194. ifslastp = ifsp;
  5195. ifslastp->begoff = start;
  5196. ifslastp->endoff = end;
  5197. ifslastp->nulonly = nulonly;
  5198. }
  5199. static void
  5200. removerecordregions(int endoff)
  5201. {
  5202. if (ifslastp == NULL)
  5203. return;
  5204. if (ifsfirst.endoff > endoff) {
  5205. while (ifsfirst.next) {
  5206. struct ifsregion *ifsp;
  5207. INT_OFF;
  5208. ifsp = ifsfirst.next->next;
  5209. free(ifsfirst.next);
  5210. ifsfirst.next = ifsp;
  5211. INT_ON;
  5212. }
  5213. if (ifsfirst.begoff > endoff) {
  5214. ifslastp = NULL;
  5215. } else {
  5216. ifslastp = &ifsfirst;
  5217. ifsfirst.endoff = endoff;
  5218. }
  5219. return;
  5220. }
  5221. ifslastp = &ifsfirst;
  5222. while (ifslastp->next && ifslastp->next->begoff < endoff)
  5223. ifslastp = ifslastp->next;
  5224. while (ifslastp->next) {
  5225. struct ifsregion *ifsp;
  5226. INT_OFF;
  5227. ifsp = ifslastp->next->next;
  5228. free(ifslastp->next);
  5229. ifslastp->next = ifsp;
  5230. INT_ON;
  5231. }
  5232. if (ifslastp->endoff > endoff)
  5233. ifslastp->endoff = endoff;
  5234. }
  5235. static char *
  5236. exptilde(char *startp, char *p, int flags)
  5237. {
  5238. unsigned char c;
  5239. char *name;
  5240. struct passwd *pw;
  5241. const char *home;
  5242. int quotes = flags & (EXP_FULL | EXP_CASE | EXP_REDIR);
  5243. int startloc;
  5244. name = p + 1;
  5245. while ((c = *++p) != '\0') {
  5246. switch (c) {
  5247. case CTLESC:
  5248. return startp;
  5249. case CTLQUOTEMARK:
  5250. return startp;
  5251. case ':':
  5252. if (flags & EXP_VARTILDE)
  5253. goto done;
  5254. break;
  5255. case '/':
  5256. case CTLENDVAR:
  5257. goto done;
  5258. }
  5259. }
  5260. done:
  5261. *p = '\0';
  5262. if (*name == '\0') {
  5263. home = lookupvar("HOME");
  5264. } else {
  5265. pw = getpwnam(name);
  5266. if (pw == NULL)
  5267. goto lose;
  5268. home = pw->pw_dir;
  5269. }
  5270. if (!home || !*home)
  5271. goto lose;
  5272. *p = c;
  5273. startloc = expdest - (char *)stackblock();
  5274. strtodest(home, SQSYNTAX, quotes);
  5275. recordregion(startloc, expdest - (char *)stackblock(), 0);
  5276. return p;
  5277. lose:
  5278. *p = c;
  5279. return startp;
  5280. }
  5281. /*
  5282. * Execute a command inside back quotes. If it's a builtin command, we
  5283. * want to save its output in a block obtained from malloc. Otherwise
  5284. * we fork off a subprocess and get the output of the command via a pipe.
  5285. * Should be called with interrupts off.
  5286. */
  5287. struct backcmd { /* result of evalbackcmd */
  5288. int fd; /* file descriptor to read from */
  5289. int nleft; /* number of chars in buffer */
  5290. char *buf; /* buffer */
  5291. struct job *jp; /* job structure for command */
  5292. };
  5293. /* These forward decls are needed to use "eval" code for backticks handling: */
  5294. static uint8_t back_exitstatus; /* exit status of backquoted command */
  5295. #define EV_EXIT 01 /* exit after evaluating tree */
  5296. static void evaltree(union node *, int);
  5297. static void FAST_FUNC
  5298. evalbackcmd(union node *n, struct backcmd *result)
  5299. {
  5300. int saveherefd;
  5301. result->fd = -1;
  5302. result->buf = NULL;
  5303. result->nleft = 0;
  5304. result->jp = NULL;
  5305. if (n == NULL)
  5306. goto out;
  5307. saveherefd = herefd;
  5308. herefd = -1;
  5309. {
  5310. int pip[2];
  5311. struct job *jp;
  5312. if (pipe(pip) < 0)
  5313. ash_msg_and_raise_error("pipe call failed");
  5314. jp = makejob(/*n,*/ 1);
  5315. if (forkshell(jp, n, FORK_NOJOB) == 0) {
  5316. FORCE_INT_ON;
  5317. close(pip[0]);
  5318. if (pip[1] != 1) {
  5319. /*close(1);*/
  5320. copyfd(pip[1], 1 | COPYFD_EXACT);
  5321. close(pip[1]);
  5322. }
  5323. eflag = 0;
  5324. evaltree(n, EV_EXIT); /* actually evaltreenr... */
  5325. /* NOTREACHED */
  5326. }
  5327. close(pip[1]);
  5328. result->fd = pip[0];
  5329. result->jp = jp;
  5330. }
  5331. herefd = saveherefd;
  5332. out:
  5333. TRACE(("evalbackcmd done: fd=%d buf=0x%x nleft=%d jp=0x%x\n",
  5334. result->fd, result->buf, result->nleft, result->jp));
  5335. }
  5336. /*
  5337. * Expand stuff in backwards quotes.
  5338. */
  5339. static void
  5340. expbackq(union node *cmd, int quoted, int quotes)
  5341. {
  5342. struct backcmd in;
  5343. int i;
  5344. char buf[128];
  5345. char *p;
  5346. char *dest;
  5347. int startloc;
  5348. int syntax = quoted ? DQSYNTAX : BASESYNTAX;
  5349. struct stackmark smark;
  5350. INT_OFF;
  5351. setstackmark(&smark);
  5352. dest = expdest;
  5353. startloc = dest - (char *)stackblock();
  5354. grabstackstr(dest);
  5355. evalbackcmd(cmd, &in);
  5356. popstackmark(&smark);
  5357. p = in.buf;
  5358. i = in.nleft;
  5359. if (i == 0)
  5360. goto read;
  5361. for (;;) {
  5362. memtodest(p, i, syntax, quotes);
  5363. read:
  5364. if (in.fd < 0)
  5365. break;
  5366. i = nonblock_immune_read(in.fd, buf, sizeof(buf), /*loop_on_EINTR:*/ 1);
  5367. TRACE(("expbackq: read returns %d\n", i));
  5368. if (i <= 0)
  5369. break;
  5370. p = buf;
  5371. }
  5372. free(in.buf);
  5373. if (in.fd >= 0) {
  5374. close(in.fd);
  5375. back_exitstatus = waitforjob(in.jp);
  5376. }
  5377. INT_ON;
  5378. /* Eat all trailing newlines */
  5379. dest = expdest;
  5380. for (; dest > (char *)stackblock() && dest[-1] == '\n';)
  5381. STUNPUTC(dest);
  5382. expdest = dest;
  5383. if (quoted == 0)
  5384. recordregion(startloc, dest - (char *)stackblock(), 0);
  5385. TRACE(("evalbackq: size:%d:'%.*s'\n",
  5386. (int)((dest - (char *)stackblock()) - startloc),
  5387. (int)((dest - (char *)stackblock()) - startloc),
  5388. stackblock() + startloc));
  5389. }
  5390. #if ENABLE_SH_MATH_SUPPORT
  5391. /*
  5392. * Expand arithmetic expression. Backup to start of expression,
  5393. * evaluate, place result in (backed up) result, adjust string position.
  5394. */
  5395. static void
  5396. expari(int quotes)
  5397. {
  5398. char *p, *start;
  5399. int begoff;
  5400. int flag;
  5401. int len;
  5402. /* ifsfree(); */
  5403. /*
  5404. * This routine is slightly over-complicated for
  5405. * efficiency. Next we scan backwards looking for the
  5406. * start of arithmetic.
  5407. */
  5408. start = stackblock();
  5409. p = expdest - 1;
  5410. *p = '\0';
  5411. p--;
  5412. while (1) {
  5413. int esc;
  5414. while ((unsigned char)*p != CTLARI) {
  5415. p--;
  5416. #if DEBUG
  5417. if (p < start) {
  5418. ash_msg_and_raise_error("missing CTLARI (shouldn't happen)");
  5419. }
  5420. #endif
  5421. }
  5422. esc = esclen(start, p);
  5423. if (!(esc % 2)) {
  5424. break;
  5425. }
  5426. p -= esc + 1;
  5427. }
  5428. begoff = p - start;
  5429. removerecordregions(begoff);
  5430. flag = p[1];
  5431. expdest = p;
  5432. if (quotes)
  5433. rmescapes(p + 2, 0);
  5434. len = cvtnum(ash_arith(p + 2));
  5435. if (flag != '"')
  5436. recordregion(begoff, begoff + len, 0);
  5437. }
  5438. #endif
  5439. /* argstr needs it */
  5440. static char *evalvar(char *p, int flags, struct strlist *var_str_list);
  5441. /*
  5442. * Perform variable and command substitution. If EXP_FULL is set, output CTLESC
  5443. * characters to allow for further processing. Otherwise treat
  5444. * $@ like $* since no splitting will be performed.
  5445. *
  5446. * var_str_list (can be NULL) is a list of "VAR=val" strings which take precedence
  5447. * over shell varables. Needed for "A=a B=$A; echo $B" case - we use it
  5448. * for correct expansion of "B=$A" word.
  5449. */
  5450. static void
  5451. argstr(char *p, int flags, struct strlist *var_str_list)
  5452. {
  5453. static const char spclchars[] ALIGN1 = {
  5454. '=',
  5455. ':',
  5456. CTLQUOTEMARK,
  5457. CTLENDVAR,
  5458. CTLESC,
  5459. CTLVAR,
  5460. CTLBACKQ,
  5461. CTLBACKQ | CTLQUOTE,
  5462. #if ENABLE_SH_MATH_SUPPORT
  5463. CTLENDARI,
  5464. #endif
  5465. '\0'
  5466. };
  5467. const char *reject = spclchars;
  5468. int quotes = flags & (EXP_FULL | EXP_CASE | EXP_REDIR); /* do CTLESC */
  5469. int breakall = flags & EXP_WORD;
  5470. int inquotes;
  5471. size_t length;
  5472. int startloc;
  5473. if (!(flags & EXP_VARTILDE)) {
  5474. reject += 2;
  5475. } else if (flags & EXP_VARTILDE2) {
  5476. reject++;
  5477. }
  5478. inquotes = 0;
  5479. length = 0;
  5480. if (flags & EXP_TILDE) {
  5481. char *q;
  5482. flags &= ~EXP_TILDE;
  5483. tilde:
  5484. q = p;
  5485. if ((unsigned char)*q == CTLESC && (flags & EXP_QWORD))
  5486. q++;
  5487. if (*q == '~')
  5488. p = exptilde(p, q, flags);
  5489. }
  5490. start:
  5491. startloc = expdest - (char *)stackblock();
  5492. for (;;) {
  5493. unsigned char c;
  5494. length += strcspn(p + length, reject);
  5495. c = p[length];
  5496. if (c) {
  5497. if (!(c & 0x80)
  5498. IF_SH_MATH_SUPPORT(|| c == CTLENDARI)
  5499. ) {
  5500. /* c == '=' || c == ':' || c == CTLENDARI */
  5501. length++;
  5502. }
  5503. }
  5504. if (length > 0) {
  5505. int newloc;
  5506. expdest = stack_nputstr(p, length, expdest);
  5507. newloc = expdest - (char *)stackblock();
  5508. if (breakall && !inquotes && newloc > startloc) {
  5509. recordregion(startloc, newloc, 0);
  5510. }
  5511. startloc = newloc;
  5512. }
  5513. p += length + 1;
  5514. length = 0;
  5515. switch (c) {
  5516. case '\0':
  5517. goto breakloop;
  5518. case '=':
  5519. if (flags & EXP_VARTILDE2) {
  5520. p--;
  5521. continue;
  5522. }
  5523. flags |= EXP_VARTILDE2;
  5524. reject++;
  5525. /* fall through */
  5526. case ':':
  5527. /*
  5528. * sort of a hack - expand tildes in variable
  5529. * assignments (after the first '=' and after ':'s).
  5530. */
  5531. if (*--p == '~') {
  5532. goto tilde;
  5533. }
  5534. continue;
  5535. }
  5536. switch (c) {
  5537. case CTLENDVAR: /* ??? */
  5538. goto breakloop;
  5539. case CTLQUOTEMARK:
  5540. /* "$@" syntax adherence hack */
  5541. if (!inquotes
  5542. && memcmp(p, dolatstr, 4) == 0
  5543. && ( p[4] == (char)CTLQUOTEMARK
  5544. || (p[4] == (char)CTLENDVAR && p[5] == (char)CTLQUOTEMARK)
  5545. )
  5546. ) {
  5547. p = evalvar(p + 1, flags, /* var_str_list: */ NULL) + 1;
  5548. goto start;
  5549. }
  5550. inquotes = !inquotes;
  5551. addquote:
  5552. if (quotes) {
  5553. p--;
  5554. length++;
  5555. startloc++;
  5556. }
  5557. break;
  5558. case CTLESC:
  5559. startloc++;
  5560. length++;
  5561. goto addquote;
  5562. case CTLVAR:
  5563. TRACE(("argstr: evalvar('%s')\n", p));
  5564. p = evalvar(p, flags, var_str_list);
  5565. TRACE(("argstr: evalvar:'%s'\n", (char *)stackblock()));
  5566. goto start;
  5567. case CTLBACKQ:
  5568. c = '\0';
  5569. case CTLBACKQ|CTLQUOTE:
  5570. expbackq(argbackq->n, c, quotes);
  5571. argbackq = argbackq->next;
  5572. goto start;
  5573. #if ENABLE_SH_MATH_SUPPORT
  5574. case CTLENDARI:
  5575. p--;
  5576. expari(quotes);
  5577. goto start;
  5578. #endif
  5579. }
  5580. }
  5581. breakloop: ;
  5582. }
  5583. static char *
  5584. scanleft(char *startp, char *rmesc, char *rmescend UNUSED_PARAM,
  5585. char *pattern, int quotes, int zero)
  5586. {
  5587. char *loc, *loc2;
  5588. char c;
  5589. loc = startp;
  5590. loc2 = rmesc;
  5591. do {
  5592. int match;
  5593. const char *s = loc2;
  5594. c = *loc2;
  5595. if (zero) {
  5596. *loc2 = '\0';
  5597. s = rmesc;
  5598. }
  5599. match = pmatch(pattern, s);
  5600. *loc2 = c;
  5601. if (match)
  5602. return loc;
  5603. if (quotes && (unsigned char)*loc == CTLESC)
  5604. loc++;
  5605. loc++;
  5606. loc2++;
  5607. } while (c);
  5608. return NULL;
  5609. }
  5610. static char *
  5611. scanright(char *startp, char *rmesc, char *rmescend,
  5612. char *pattern, int quotes, int match_at_start)
  5613. {
  5614. #if !ENABLE_ASH_OPTIMIZE_FOR_SIZE
  5615. int try2optimize = match_at_start;
  5616. #endif
  5617. int esc = 0;
  5618. char *loc;
  5619. char *loc2;
  5620. /* If we called by "${v/pattern/repl}" or "${v//pattern/repl}":
  5621. * startp="escaped_value_of_v" rmesc="raw_value_of_v"
  5622. * rmescend=""(ptr to NUL in rmesc) pattern="pattern" quotes=match_at_start=1
  5623. * Logic:
  5624. * loc starts at NUL at the end of startp, loc2 starts at the end of rmesc,
  5625. * and on each iteration they go back two/one char until they reach the beginning.
  5626. * We try to find a match in "raw_value_of_v", "raw_value_of_", "raw_value_of" etc.
  5627. */
  5628. /* TODO: document in what other circumstances we are called. */
  5629. for (loc = pattern - 1, loc2 = rmescend; loc >= startp; loc2--) {
  5630. int match;
  5631. char c = *loc2;
  5632. const char *s = loc2;
  5633. if (match_at_start) {
  5634. *loc2 = '\0';
  5635. s = rmesc;
  5636. }
  5637. match = pmatch(pattern, s);
  5638. //bb_error_msg("pmatch(pattern:'%s',s:'%s'):%d", pattern, s, match);
  5639. *loc2 = c;
  5640. if (match)
  5641. return loc;
  5642. #if !ENABLE_ASH_OPTIMIZE_FOR_SIZE
  5643. if (try2optimize) {
  5644. /* Maybe we can optimize this:
  5645. * if pattern ends with unescaped *, we can avoid checking
  5646. * shorter strings: if "foo*" doesnt match "raw_value_of_v",
  5647. * it wont match truncated "raw_value_of_" strings too.
  5648. */
  5649. unsigned plen = strlen(pattern);
  5650. /* Does it end with "*"? */
  5651. if (plen != 0 && pattern[--plen] == '*') {
  5652. /* "xxxx*" is not escaped */
  5653. /* "xxx\*" is escaped */
  5654. /* "xx\\*" is not escaped */
  5655. /* "x\\\*" is escaped */
  5656. int slashes = 0;
  5657. while (plen != 0 && pattern[--plen] == '\\')
  5658. slashes++;
  5659. if (!(slashes & 1))
  5660. break; /* ends with unescaped "*" */
  5661. }
  5662. try2optimize = 0;
  5663. }
  5664. #endif
  5665. loc--;
  5666. if (quotes) {
  5667. if (--esc < 0) {
  5668. esc = esclen(startp, loc);
  5669. }
  5670. if (esc % 2) {
  5671. esc--;
  5672. loc--;
  5673. }
  5674. }
  5675. }
  5676. return NULL;
  5677. }
  5678. static void varunset(const char *, const char *, const char *, int) NORETURN;
  5679. static void
  5680. varunset(const char *end, const char *var, const char *umsg, int varflags)
  5681. {
  5682. const char *msg;
  5683. const char *tail;
  5684. tail = nullstr;
  5685. msg = "parameter not set";
  5686. if (umsg) {
  5687. if ((unsigned char)*end == CTLENDVAR) {
  5688. if (varflags & VSNUL)
  5689. tail = " or null";
  5690. } else {
  5691. msg = umsg;
  5692. }
  5693. }
  5694. ash_msg_and_raise_error("%.*s: %s%s", (int)(end - var - 1), var, msg, tail);
  5695. }
  5696. #if ENABLE_ASH_BASH_COMPAT
  5697. static char *
  5698. parse_sub_pattern(char *arg, int varflags)
  5699. {
  5700. char *idx, *repl = NULL;
  5701. unsigned char c;
  5702. //char *org_arg = arg;
  5703. //bb_error_msg("arg:'%s' varflags:%x", arg, varflags);
  5704. idx = arg;
  5705. while (1) {
  5706. c = *arg;
  5707. if (!c)
  5708. break;
  5709. if (c == '/') {
  5710. /* Only the first '/' seen is our separator */
  5711. if (!repl) {
  5712. repl = idx + 1;
  5713. c = '\0';
  5714. }
  5715. }
  5716. *idx++ = c;
  5717. arg++;
  5718. /*
  5719. * Example: v='ab\c'; echo ${v/\\b/_\\_\z_}
  5720. * The result is a_\_z_c (not a\_\_z_c)!
  5721. *
  5722. * Enable debug prints in this function and you'll see:
  5723. * ash: arg:'\\b/_\\_z_' varflags:d
  5724. * ash: pattern:'\\b' repl:'_\_z_'
  5725. * That is, \\b is interpreted as \\b, but \\_ as \_!
  5726. * IOW: search pattern and replace string treat backslashes
  5727. * differently! That is the reason why we check repl below:
  5728. */
  5729. if (c == '\\' && *arg == '\\' && repl && !(varflags & VSQUOTE))
  5730. arg++; /* skip both '\', not just first one */
  5731. }
  5732. *idx = c; /* NUL */
  5733. //bb_error_msg("pattern:'%s' repl:'%s'", org_arg, repl);
  5734. return repl;
  5735. }
  5736. #endif /* ENABLE_ASH_BASH_COMPAT */
  5737. static const char *
  5738. subevalvar(char *p, char *varname, int strloc, int subtype,
  5739. int startloc, int varflags, int quotes, struct strlist *var_str_list)
  5740. {
  5741. struct nodelist *saveargbackq = argbackq;
  5742. char *startp;
  5743. char *loc;
  5744. char *rmesc, *rmescend;
  5745. char *str;
  5746. IF_ASH_BASH_COMPAT(const char *repl = NULL;)
  5747. IF_ASH_BASH_COMPAT(int pos, len, orig_len;)
  5748. int saveherefd = herefd;
  5749. int amount, resetloc;
  5750. IF_ASH_BASH_COMPAT(int workloc;)
  5751. int zero;
  5752. char *(*scan)(char*, char*, char*, char*, int, int);
  5753. //bb_error_msg("subevalvar(p:'%s',varname:'%s',strloc:%d,subtype:%d,startloc:%d,varflags:%x,quotes:%d)",
  5754. // p, varname, strloc, subtype, startloc, varflags, quotes);
  5755. herefd = -1;
  5756. argstr(p, (subtype != VSASSIGN && subtype != VSQUESTION) ? EXP_CASE : 0,
  5757. var_str_list);
  5758. STPUTC('\0', expdest);
  5759. herefd = saveherefd;
  5760. argbackq = saveargbackq;
  5761. startp = (char *)stackblock() + startloc;
  5762. switch (subtype) {
  5763. case VSASSIGN:
  5764. setvar2(varname, startp);
  5765. amount = startp - expdest;
  5766. STADJUST(amount, expdest);
  5767. return startp;
  5768. case VSQUESTION:
  5769. varunset(p, varname, startp, varflags);
  5770. /* NOTREACHED */
  5771. #if ENABLE_ASH_BASH_COMPAT
  5772. case VSSUBSTR:
  5773. loc = str = stackblock() + strloc;
  5774. /* Read POS in ${var:POS:LEN} */
  5775. pos = atoi(loc); /* number(loc) errors out on "1:4" */
  5776. len = str - startp - 1;
  5777. /* *loc != '\0', guaranteed by parser */
  5778. if (quotes) {
  5779. char *ptr;
  5780. /* Adjust the length by the number of escapes */
  5781. for (ptr = startp; ptr < (str - 1); ptr++) {
  5782. if ((unsigned char)*ptr == CTLESC) {
  5783. len--;
  5784. ptr++;
  5785. }
  5786. }
  5787. }
  5788. orig_len = len;
  5789. if (*loc++ == ':') {
  5790. /* ${var::LEN} */
  5791. len = number(loc);
  5792. } else {
  5793. /* Skip POS in ${var:POS:LEN} */
  5794. len = orig_len;
  5795. while (*loc && *loc != ':') {
  5796. /* TODO?
  5797. * bash complains on: var=qwe; echo ${var:1a:123}
  5798. if (!isdigit(*loc))
  5799. ash_msg_and_raise_error(msg_illnum, str);
  5800. */
  5801. loc++;
  5802. }
  5803. if (*loc++ == ':') {
  5804. len = number(loc);
  5805. }
  5806. }
  5807. if (pos >= orig_len) {
  5808. pos = 0;
  5809. len = 0;
  5810. }
  5811. if (len > (orig_len - pos))
  5812. len = orig_len - pos;
  5813. for (str = startp; pos; str++, pos--) {
  5814. if (quotes && (unsigned char)*str == CTLESC)
  5815. str++;
  5816. }
  5817. for (loc = startp; len; len--) {
  5818. if (quotes && (unsigned char)*str == CTLESC)
  5819. *loc++ = *str++;
  5820. *loc++ = *str++;
  5821. }
  5822. *loc = '\0';
  5823. amount = loc - expdest;
  5824. STADJUST(amount, expdest);
  5825. return loc;
  5826. #endif
  5827. }
  5828. resetloc = expdest - (char *)stackblock();
  5829. /* We'll comeback here if we grow the stack while handling
  5830. * a VSREPLACE or VSREPLACEALL, since our pointers into the
  5831. * stack will need rebasing, and we'll need to remove our work
  5832. * areas each time
  5833. */
  5834. IF_ASH_BASH_COMPAT(restart:)
  5835. amount = expdest - ((char *)stackblock() + resetloc);
  5836. STADJUST(-amount, expdest);
  5837. startp = (char *)stackblock() + startloc;
  5838. rmesc = startp;
  5839. rmescend = (char *)stackblock() + strloc;
  5840. if (quotes) {
  5841. rmesc = rmescapes(startp, RMESCAPE_ALLOC | RMESCAPE_GROW);
  5842. if (rmesc != startp) {
  5843. rmescend = expdest;
  5844. startp = (char *)stackblock() + startloc;
  5845. }
  5846. }
  5847. rmescend--;
  5848. str = (char *)stackblock() + strloc;
  5849. preglob(str, varflags & VSQUOTE, 0);
  5850. #if ENABLE_ASH_BASH_COMPAT
  5851. workloc = expdest - (char *)stackblock();
  5852. if (subtype == VSREPLACE || subtype == VSREPLACEALL) {
  5853. char *idx, *end;
  5854. if (!repl) {
  5855. repl = parse_sub_pattern(str, varflags);
  5856. //bb_error_msg("repl:'%s'", repl);
  5857. if (!repl)
  5858. repl = nullstr;
  5859. }
  5860. /* If there's no pattern to match, return the expansion unmolested */
  5861. if (str[0] == '\0')
  5862. return NULL;
  5863. len = 0;
  5864. idx = startp;
  5865. end = str - 1;
  5866. while (idx < end) {
  5867. try_to_match:
  5868. loc = scanright(idx, rmesc, rmescend, str, quotes, 1);
  5869. //bb_error_msg("scanright('%s'):'%s'", str, loc);
  5870. if (!loc) {
  5871. /* No match, advance */
  5872. char *restart_detect = stackblock();
  5873. skip_matching:
  5874. STPUTC(*idx, expdest);
  5875. if (quotes && (unsigned char)*idx == CTLESC) {
  5876. idx++;
  5877. len++;
  5878. STPUTC(*idx, expdest);
  5879. }
  5880. if (stackblock() != restart_detect)
  5881. goto restart;
  5882. idx++;
  5883. len++;
  5884. rmesc++;
  5885. /* continue; - prone to quadratic behavior, smarter code: */
  5886. if (idx >= end)
  5887. break;
  5888. if (str[0] == '*') {
  5889. /* Pattern is "*foo". If "*foo" does not match "long_string",
  5890. * it would never match "ong_string" etc, no point in trying.
  5891. */
  5892. goto skip_matching;
  5893. }
  5894. goto try_to_match;
  5895. }
  5896. if (subtype == VSREPLACEALL) {
  5897. while (idx < loc) {
  5898. if (quotes && (unsigned char)*idx == CTLESC)
  5899. idx++;
  5900. idx++;
  5901. rmesc++;
  5902. }
  5903. } else {
  5904. idx = loc;
  5905. }
  5906. //bb_error_msg("repl:'%s'", repl);
  5907. for (loc = (char*)repl; *loc; loc++) {
  5908. char *restart_detect = stackblock();
  5909. if (quotes && *loc == '\\') {
  5910. STPUTC(CTLESC, expdest);
  5911. len++;
  5912. }
  5913. STPUTC(*loc, expdest);
  5914. if (stackblock() != restart_detect)
  5915. goto restart;
  5916. len++;
  5917. }
  5918. if (subtype == VSREPLACE) {
  5919. //bb_error_msg("tail:'%s', quotes:%x", idx, quotes);
  5920. while (*idx) {
  5921. char *restart_detect = stackblock();
  5922. STPUTC(*idx, expdest);
  5923. if (stackblock() != restart_detect)
  5924. goto restart;
  5925. len++;
  5926. idx++;
  5927. }
  5928. break;
  5929. }
  5930. }
  5931. /* We've put the replaced text into a buffer at workloc, now
  5932. * move it to the right place and adjust the stack.
  5933. */
  5934. STPUTC('\0', expdest);
  5935. startp = (char *)stackblock() + startloc;
  5936. memmove(startp, (char *)stackblock() + workloc, len + 1);
  5937. //bb_error_msg("startp:'%s'", startp);
  5938. amount = expdest - (startp + len);
  5939. STADJUST(-amount, expdest);
  5940. return startp;
  5941. }
  5942. #endif /* ENABLE_ASH_BASH_COMPAT */
  5943. subtype -= VSTRIMRIGHT;
  5944. #if DEBUG
  5945. if (subtype < 0 || subtype > 7)
  5946. abort();
  5947. #endif
  5948. /* zero = (subtype == VSTRIMLEFT || subtype == VSTRIMLEFTMAX) */
  5949. zero = subtype >> 1;
  5950. /* VSTRIMLEFT/VSTRIMRIGHTMAX -> scanleft */
  5951. scan = (subtype & 1) ^ zero ? scanleft : scanright;
  5952. loc = scan(startp, rmesc, rmescend, str, quotes, zero);
  5953. if (loc) {
  5954. if (zero) {
  5955. memmove(startp, loc, str - loc);
  5956. loc = startp + (str - loc) - 1;
  5957. }
  5958. *loc = '\0';
  5959. amount = loc - expdest;
  5960. STADJUST(amount, expdest);
  5961. }
  5962. return loc;
  5963. }
  5964. /*
  5965. * Add the value of a specialized variable to the stack string.
  5966. * name parameter (examples):
  5967. * ash -c 'echo $1' name:'1='
  5968. * ash -c 'echo $qwe' name:'qwe='
  5969. * ash -c 'echo $$' name:'$='
  5970. * ash -c 'echo ${$}' name:'$='
  5971. * ash -c 'echo ${$##q}' name:'$=q'
  5972. * ash -c 'echo ${#$}' name:'$='
  5973. * note: examples with bad shell syntax:
  5974. * ash -c 'echo ${#$1}' name:'$=1'
  5975. * ash -c 'echo ${#1#}' name:'1=#'
  5976. */
  5977. static NOINLINE ssize_t
  5978. varvalue(char *name, int varflags, int flags, struct strlist *var_str_list)
  5979. {
  5980. const char *p;
  5981. int num;
  5982. int i;
  5983. int sepq = 0;
  5984. ssize_t len = 0;
  5985. int subtype = varflags & VSTYPE;
  5986. int quotes = flags & (EXP_FULL | EXP_CASE | EXP_REDIR);
  5987. int quoted = varflags & VSQUOTE;
  5988. int syntax = quoted ? DQSYNTAX : BASESYNTAX;
  5989. switch (*name) {
  5990. case '$':
  5991. num = rootpid;
  5992. goto numvar;
  5993. case '?':
  5994. num = exitstatus;
  5995. goto numvar;
  5996. case '#':
  5997. num = shellparam.nparam;
  5998. goto numvar;
  5999. case '!':
  6000. num = backgndpid;
  6001. if (num == 0)
  6002. return -1;
  6003. numvar:
  6004. len = cvtnum(num);
  6005. goto check_1char_name;
  6006. case '-':
  6007. expdest = makestrspace(NOPTS, expdest);
  6008. for (i = NOPTS - 1; i >= 0; i--) {
  6009. if (optlist[i]) {
  6010. USTPUTC(optletters(i), expdest);
  6011. len++;
  6012. }
  6013. }
  6014. check_1char_name:
  6015. #if 0
  6016. /* handles cases similar to ${#$1} */
  6017. if (name[2] != '\0')
  6018. raise_error_syntax("bad substitution");
  6019. #endif
  6020. break;
  6021. case '@': {
  6022. char **ap;
  6023. int sep;
  6024. if (quoted && (flags & EXP_FULL)) {
  6025. /* note: this is not meant as PEOF value */
  6026. sep = 1 << CHAR_BIT;
  6027. goto param;
  6028. }
  6029. /* fall through */
  6030. case '*':
  6031. sep = ifsset() ? (unsigned char)(ifsval()[0]) : ' ';
  6032. i = SIT(sep, syntax);
  6033. if (quotes && (i == CCTL || i == CBACK))
  6034. sepq = 1;
  6035. param:
  6036. ap = shellparam.p;
  6037. if (!ap)
  6038. return -1;
  6039. while ((p = *ap++) != NULL) {
  6040. size_t partlen;
  6041. partlen = strlen(p);
  6042. len += partlen;
  6043. if (!(subtype == VSPLUS || subtype == VSLENGTH))
  6044. memtodest(p, partlen, syntax, quotes);
  6045. if (*ap && sep) {
  6046. char *q;
  6047. len++;
  6048. if (subtype == VSPLUS || subtype == VSLENGTH) {
  6049. continue;
  6050. }
  6051. q = expdest;
  6052. if (sepq)
  6053. STPUTC(CTLESC, q);
  6054. /* note: may put NUL despite sep != 0
  6055. * (see sep = 1 << CHAR_BIT above) */
  6056. STPUTC(sep, q);
  6057. expdest = q;
  6058. }
  6059. }
  6060. return len;
  6061. } /* case '@' and '*' */
  6062. case '0':
  6063. case '1':
  6064. case '2':
  6065. case '3':
  6066. case '4':
  6067. case '5':
  6068. case '6':
  6069. case '7':
  6070. case '8':
  6071. case '9':
  6072. num = atoi(name); /* number(name) fails on ${N#str} etc */
  6073. if (num < 0 || num > shellparam.nparam)
  6074. return -1;
  6075. p = num ? shellparam.p[num - 1] : arg0;
  6076. goto value;
  6077. default:
  6078. /* NB: name has form "VAR=..." */
  6079. /* "A=a B=$A" case: var_str_list is a list of "A=a" strings
  6080. * which should be considered before we check variables. */
  6081. if (var_str_list) {
  6082. unsigned name_len = (strchrnul(name, '=') - name) + 1;
  6083. p = NULL;
  6084. do {
  6085. char *str, *eq;
  6086. str = var_str_list->text;
  6087. eq = strchr(str, '=');
  6088. if (!eq) /* stop at first non-assignment */
  6089. break;
  6090. eq++;
  6091. if (name_len == (unsigned)(eq - str)
  6092. && strncmp(str, name, name_len) == 0
  6093. ) {
  6094. p = eq;
  6095. /* goto value; - WRONG! */
  6096. /* think "A=1 A=2 B=$A" */
  6097. }
  6098. var_str_list = var_str_list->next;
  6099. } while (var_str_list);
  6100. if (p)
  6101. goto value;
  6102. }
  6103. p = lookupvar(name);
  6104. value:
  6105. if (!p)
  6106. return -1;
  6107. len = strlen(p);
  6108. if (!(subtype == VSPLUS || subtype == VSLENGTH))
  6109. memtodest(p, len, syntax, quotes);
  6110. return len;
  6111. }
  6112. if (subtype == VSPLUS || subtype == VSLENGTH)
  6113. STADJUST(-len, expdest);
  6114. return len;
  6115. }
  6116. /*
  6117. * Expand a variable, and return a pointer to the next character in the
  6118. * input string.
  6119. */
  6120. static char *
  6121. evalvar(char *p, int flags, struct strlist *var_str_list)
  6122. {
  6123. char varflags;
  6124. char subtype;
  6125. char quoted;
  6126. char easy;
  6127. char *var;
  6128. int patloc;
  6129. int startloc;
  6130. ssize_t varlen;
  6131. varflags = (unsigned char) *p++;
  6132. subtype = varflags & VSTYPE;
  6133. quoted = varflags & VSQUOTE;
  6134. var = p;
  6135. easy = (!quoted || (*var == '@' && shellparam.nparam));
  6136. startloc = expdest - (char *)stackblock();
  6137. p = strchr(p, '=') + 1; //TODO: use var_end(p)?
  6138. again:
  6139. varlen = varvalue(var, varflags, flags, var_str_list);
  6140. if (varflags & VSNUL)
  6141. varlen--;
  6142. if (subtype == VSPLUS) {
  6143. varlen = -1 - varlen;
  6144. goto vsplus;
  6145. }
  6146. if (subtype == VSMINUS) {
  6147. vsplus:
  6148. if (varlen < 0) {
  6149. argstr(
  6150. p,
  6151. flags | (quoted ? EXP_TILDE|EXP_QWORD : EXP_TILDE|EXP_WORD),
  6152. var_str_list
  6153. );
  6154. goto end;
  6155. }
  6156. if (easy)
  6157. goto record;
  6158. goto end;
  6159. }
  6160. if (subtype == VSASSIGN || subtype == VSQUESTION) {
  6161. if (varlen < 0) {
  6162. if (subevalvar(p, var, /* strloc: */ 0,
  6163. subtype, startloc, varflags,
  6164. /* quotes: */ 0,
  6165. var_str_list)
  6166. ) {
  6167. varflags &= ~VSNUL;
  6168. /*
  6169. * Remove any recorded regions beyond
  6170. * start of variable
  6171. */
  6172. removerecordregions(startloc);
  6173. goto again;
  6174. }
  6175. goto end;
  6176. }
  6177. if (easy)
  6178. goto record;
  6179. goto end;
  6180. }
  6181. if (varlen < 0 && uflag)
  6182. varunset(p, var, 0, 0);
  6183. if (subtype == VSLENGTH) {
  6184. cvtnum(varlen > 0 ? varlen : 0);
  6185. goto record;
  6186. }
  6187. if (subtype == VSNORMAL) {
  6188. if (easy)
  6189. goto record;
  6190. goto end;
  6191. }
  6192. #if DEBUG
  6193. switch (subtype) {
  6194. case VSTRIMLEFT:
  6195. case VSTRIMLEFTMAX:
  6196. case VSTRIMRIGHT:
  6197. case VSTRIMRIGHTMAX:
  6198. #if ENABLE_ASH_BASH_COMPAT
  6199. case VSSUBSTR:
  6200. case VSREPLACE:
  6201. case VSREPLACEALL:
  6202. #endif
  6203. break;
  6204. default:
  6205. abort();
  6206. }
  6207. #endif
  6208. if (varlen >= 0) {
  6209. /*
  6210. * Terminate the string and start recording the pattern
  6211. * right after it
  6212. */
  6213. STPUTC('\0', expdest);
  6214. patloc = expdest - (char *)stackblock();
  6215. if (NULL == subevalvar(p, /* varname: */ NULL, patloc, subtype,
  6216. startloc, varflags,
  6217. /* quotes: */ flags & (EXP_FULL | EXP_CASE | EXP_REDIR),
  6218. var_str_list)
  6219. ) {
  6220. int amount = expdest - (
  6221. (char *)stackblock() + patloc - 1
  6222. );
  6223. STADJUST(-amount, expdest);
  6224. }
  6225. /* Remove any recorded regions beyond start of variable */
  6226. removerecordregions(startloc);
  6227. record:
  6228. recordregion(startloc, expdest - (char *)stackblock(), quoted);
  6229. }
  6230. end:
  6231. if (subtype != VSNORMAL) { /* skip to end of alternative */
  6232. int nesting = 1;
  6233. for (;;) {
  6234. unsigned char c = *p++;
  6235. if (c == CTLESC)
  6236. p++;
  6237. else if (c == CTLBACKQ || c == (CTLBACKQ|CTLQUOTE)) {
  6238. if (varlen >= 0)
  6239. argbackq = argbackq->next;
  6240. } else if (c == CTLVAR) {
  6241. if ((*p++ & VSTYPE) != VSNORMAL)
  6242. nesting++;
  6243. } else if (c == CTLENDVAR) {
  6244. if (--nesting == 0)
  6245. break;
  6246. }
  6247. }
  6248. }
  6249. return p;
  6250. }
  6251. /*
  6252. * Break the argument string into pieces based upon IFS and add the
  6253. * strings to the argument list. The regions of the string to be
  6254. * searched for IFS characters have been stored by recordregion.
  6255. */
  6256. static void
  6257. ifsbreakup(char *string, struct arglist *arglist)
  6258. {
  6259. struct ifsregion *ifsp;
  6260. struct strlist *sp;
  6261. char *start;
  6262. char *p;
  6263. char *q;
  6264. const char *ifs, *realifs;
  6265. int ifsspc;
  6266. int nulonly;
  6267. start = string;
  6268. if (ifslastp != NULL) {
  6269. ifsspc = 0;
  6270. nulonly = 0;
  6271. realifs = ifsset() ? ifsval() : defifs;
  6272. ifsp = &ifsfirst;
  6273. do {
  6274. p = string + ifsp->begoff;
  6275. nulonly = ifsp->nulonly;
  6276. ifs = nulonly ? nullstr : realifs;
  6277. ifsspc = 0;
  6278. while (p < string + ifsp->endoff) {
  6279. q = p;
  6280. if ((unsigned char)*p == CTLESC)
  6281. p++;
  6282. if (!strchr(ifs, *p)) {
  6283. p++;
  6284. continue;
  6285. }
  6286. if (!nulonly)
  6287. ifsspc = (strchr(defifs, *p) != NULL);
  6288. /* Ignore IFS whitespace at start */
  6289. if (q == start && ifsspc) {
  6290. p++;
  6291. start = p;
  6292. continue;
  6293. }
  6294. *q = '\0';
  6295. sp = stzalloc(sizeof(*sp));
  6296. sp->text = start;
  6297. *arglist->lastp = sp;
  6298. arglist->lastp = &sp->next;
  6299. p++;
  6300. if (!nulonly) {
  6301. for (;;) {
  6302. if (p >= string + ifsp->endoff) {
  6303. break;
  6304. }
  6305. q = p;
  6306. if ((unsigned char)*p == CTLESC)
  6307. p++;
  6308. if (strchr(ifs, *p) == NULL) {
  6309. p = q;
  6310. break;
  6311. }
  6312. if (strchr(defifs, *p) == NULL) {
  6313. if (ifsspc) {
  6314. p++;
  6315. ifsspc = 0;
  6316. } else {
  6317. p = q;
  6318. break;
  6319. }
  6320. } else
  6321. p++;
  6322. }
  6323. }
  6324. start = p;
  6325. } /* while */
  6326. ifsp = ifsp->next;
  6327. } while (ifsp != NULL);
  6328. if (nulonly)
  6329. goto add;
  6330. }
  6331. if (!*start)
  6332. return;
  6333. add:
  6334. sp = stzalloc(sizeof(*sp));
  6335. sp->text = start;
  6336. *arglist->lastp = sp;
  6337. arglist->lastp = &sp->next;
  6338. }
  6339. static void
  6340. ifsfree(void)
  6341. {
  6342. struct ifsregion *p;
  6343. INT_OFF;
  6344. p = ifsfirst.next;
  6345. do {
  6346. struct ifsregion *ifsp;
  6347. ifsp = p->next;
  6348. free(p);
  6349. p = ifsp;
  6350. } while (p);
  6351. ifslastp = NULL;
  6352. ifsfirst.next = NULL;
  6353. INT_ON;
  6354. }
  6355. /*
  6356. * Add a file name to the list.
  6357. */
  6358. static void
  6359. addfname(const char *name)
  6360. {
  6361. struct strlist *sp;
  6362. sp = stzalloc(sizeof(*sp));
  6363. sp->text = ststrdup(name);
  6364. *exparg.lastp = sp;
  6365. exparg.lastp = &sp->next;
  6366. }
  6367. /*
  6368. * Do metacharacter (i.e. *, ?, [...]) expansion.
  6369. */
  6370. static void
  6371. expmeta(char *expdir, char *enddir, char *name)
  6372. {
  6373. char *p;
  6374. const char *cp;
  6375. char *start;
  6376. char *endname;
  6377. int metaflag;
  6378. struct stat statb;
  6379. DIR *dirp;
  6380. struct dirent *dp;
  6381. int atend;
  6382. int matchdot;
  6383. metaflag = 0;
  6384. start = name;
  6385. for (p = name; *p; p++) {
  6386. if (*p == '*' || *p == '?')
  6387. metaflag = 1;
  6388. else if (*p == '[') {
  6389. char *q = p + 1;
  6390. if (*q == '!')
  6391. q++;
  6392. for (;;) {
  6393. if (*q == '\\')
  6394. q++;
  6395. if (*q == '/' || *q == '\0')
  6396. break;
  6397. if (*++q == ']') {
  6398. metaflag = 1;
  6399. break;
  6400. }
  6401. }
  6402. } else if (*p == '\\')
  6403. p++;
  6404. else if (*p == '/') {
  6405. if (metaflag)
  6406. goto out;
  6407. start = p + 1;
  6408. }
  6409. }
  6410. out:
  6411. if (metaflag == 0) { /* we've reached the end of the file name */
  6412. if (enddir != expdir)
  6413. metaflag++;
  6414. p = name;
  6415. do {
  6416. if (*p == '\\')
  6417. p++;
  6418. *enddir++ = *p;
  6419. } while (*p++);
  6420. if (metaflag == 0 || lstat(expdir, &statb) >= 0)
  6421. addfname(expdir);
  6422. return;
  6423. }
  6424. endname = p;
  6425. if (name < start) {
  6426. p = name;
  6427. do {
  6428. if (*p == '\\')
  6429. p++;
  6430. *enddir++ = *p++;
  6431. } while (p < start);
  6432. }
  6433. if (enddir == expdir) {
  6434. cp = ".";
  6435. } else if (enddir == expdir + 1 && *expdir == '/') {
  6436. cp = "/";
  6437. } else {
  6438. cp = expdir;
  6439. enddir[-1] = '\0';
  6440. }
  6441. dirp = opendir(cp);
  6442. if (dirp == NULL)
  6443. return;
  6444. if (enddir != expdir)
  6445. enddir[-1] = '/';
  6446. if (*endname == 0) {
  6447. atend = 1;
  6448. } else {
  6449. atend = 0;
  6450. *endname++ = '\0';
  6451. }
  6452. matchdot = 0;
  6453. p = start;
  6454. if (*p == '\\')
  6455. p++;
  6456. if (*p == '.')
  6457. matchdot++;
  6458. while (!pending_int && (dp = readdir(dirp)) != NULL) {
  6459. if (dp->d_name[0] == '.' && !matchdot)
  6460. continue;
  6461. if (pmatch(start, dp->d_name)) {
  6462. if (atend) {
  6463. strcpy(enddir, dp->d_name);
  6464. addfname(expdir);
  6465. } else {
  6466. for (p = enddir, cp = dp->d_name; (*p++ = *cp++) != '\0';)
  6467. continue;
  6468. p[-1] = '/';
  6469. expmeta(expdir, p, endname);
  6470. }
  6471. }
  6472. }
  6473. closedir(dirp);
  6474. if (!atend)
  6475. endname[-1] = '/';
  6476. }
  6477. static struct strlist *
  6478. msort(struct strlist *list, int len)
  6479. {
  6480. struct strlist *p, *q = NULL;
  6481. struct strlist **lpp;
  6482. int half;
  6483. int n;
  6484. if (len <= 1)
  6485. return list;
  6486. half = len >> 1;
  6487. p = list;
  6488. for (n = half; --n >= 0;) {
  6489. q = p;
  6490. p = p->next;
  6491. }
  6492. q->next = NULL; /* terminate first half of list */
  6493. q = msort(list, half); /* sort first half of list */
  6494. p = msort(p, len - half); /* sort second half */
  6495. lpp = &list;
  6496. for (;;) {
  6497. #if ENABLE_LOCALE_SUPPORT
  6498. if (strcoll(p->text, q->text) < 0)
  6499. #else
  6500. if (strcmp(p->text, q->text) < 0)
  6501. #endif
  6502. {
  6503. *lpp = p;
  6504. lpp = &p->next;
  6505. p = *lpp;
  6506. if (p == NULL) {
  6507. *lpp = q;
  6508. break;
  6509. }
  6510. } else {
  6511. *lpp = q;
  6512. lpp = &q->next;
  6513. q = *lpp;
  6514. if (q == NULL) {
  6515. *lpp = p;
  6516. break;
  6517. }
  6518. }
  6519. }
  6520. return list;
  6521. }
  6522. /*
  6523. * Sort the results of file name expansion. It calculates the number of
  6524. * strings to sort and then calls msort (short for merge sort) to do the
  6525. * work.
  6526. */
  6527. static struct strlist *
  6528. expsort(struct strlist *str)
  6529. {
  6530. int len;
  6531. struct strlist *sp;
  6532. len = 0;
  6533. for (sp = str; sp; sp = sp->next)
  6534. len++;
  6535. return msort(str, len);
  6536. }
  6537. static void
  6538. expandmeta(struct strlist *str /*, int flag*/)
  6539. {
  6540. static const char metachars[] ALIGN1 = {
  6541. '*', '?', '[', 0
  6542. };
  6543. /* TODO - EXP_REDIR */
  6544. while (str) {
  6545. char *expdir;
  6546. struct strlist **savelastp;
  6547. struct strlist *sp;
  6548. char *p;
  6549. if (fflag)
  6550. goto nometa;
  6551. if (!strpbrk(str->text, metachars))
  6552. goto nometa;
  6553. savelastp = exparg.lastp;
  6554. INT_OFF;
  6555. p = preglob(str->text, 0, RMESCAPE_ALLOC | RMESCAPE_HEAP);
  6556. {
  6557. int i = strlen(str->text);
  6558. expdir = ckmalloc(i < 2048 ? 2048 : i); /* XXX */
  6559. }
  6560. expmeta(expdir, expdir, p);
  6561. free(expdir);
  6562. if (p != str->text)
  6563. free(p);
  6564. INT_ON;
  6565. if (exparg.lastp == savelastp) {
  6566. /*
  6567. * no matches
  6568. */
  6569. nometa:
  6570. *exparg.lastp = str;
  6571. rmescapes(str->text, 0);
  6572. exparg.lastp = &str->next;
  6573. } else {
  6574. *exparg.lastp = NULL;
  6575. *savelastp = sp = expsort(*savelastp);
  6576. while (sp->next != NULL)
  6577. sp = sp->next;
  6578. exparg.lastp = &sp->next;
  6579. }
  6580. str = str->next;
  6581. }
  6582. }
  6583. /*
  6584. * Perform variable substitution and command substitution on an argument,
  6585. * placing the resulting list of arguments in arglist. If EXP_FULL is true,
  6586. * perform splitting and file name expansion. When arglist is NULL, perform
  6587. * here document expansion.
  6588. */
  6589. static void
  6590. expandarg(union node *arg, struct arglist *arglist, int flag)
  6591. {
  6592. struct strlist *sp;
  6593. char *p;
  6594. argbackq = arg->narg.backquote;
  6595. STARTSTACKSTR(expdest);
  6596. ifsfirst.next = NULL;
  6597. ifslastp = NULL;
  6598. TRACE(("expandarg: argstr('%s',flags:%x)\n", arg->narg.text, flag));
  6599. argstr(arg->narg.text, flag,
  6600. /* var_str_list: */ arglist ? arglist->list : NULL);
  6601. p = _STPUTC('\0', expdest);
  6602. expdest = p - 1;
  6603. if (arglist == NULL) {
  6604. return; /* here document expanded */
  6605. }
  6606. p = grabstackstr(p);
  6607. TRACE(("expandarg: p:'%s'\n", p));
  6608. exparg.lastp = &exparg.list;
  6609. /*
  6610. * TODO - EXP_REDIR
  6611. */
  6612. if (flag & EXP_FULL) {
  6613. ifsbreakup(p, &exparg);
  6614. *exparg.lastp = NULL;
  6615. exparg.lastp = &exparg.list;
  6616. expandmeta(exparg.list /*, flag*/);
  6617. } else {
  6618. if (flag & EXP_REDIR) { /*XXX - for now, just remove escapes */
  6619. rmescapes(p, 0);
  6620. TRACE(("expandarg: rmescapes:'%s'\n", p));
  6621. }
  6622. sp = stzalloc(sizeof(*sp));
  6623. sp->text = p;
  6624. *exparg.lastp = sp;
  6625. exparg.lastp = &sp->next;
  6626. }
  6627. if (ifsfirst.next)
  6628. ifsfree();
  6629. *exparg.lastp = NULL;
  6630. if (exparg.list) {
  6631. *arglist->lastp = exparg.list;
  6632. arglist->lastp = exparg.lastp;
  6633. }
  6634. }
  6635. /*
  6636. * Expand shell variables and backquotes inside a here document.
  6637. */
  6638. static void
  6639. expandhere(union node *arg, int fd)
  6640. {
  6641. herefd = fd;
  6642. expandarg(arg, (struct arglist *)NULL, 0);
  6643. full_write(fd, stackblock(), expdest - (char *)stackblock());
  6644. }
  6645. /*
  6646. * Returns true if the pattern matches the string.
  6647. */
  6648. static int
  6649. patmatch(char *pattern, const char *string)
  6650. {
  6651. return pmatch(preglob(pattern, 0, 0), string);
  6652. }
  6653. /*
  6654. * See if a pattern matches in a case statement.
  6655. */
  6656. static int
  6657. casematch(union node *pattern, char *val)
  6658. {
  6659. struct stackmark smark;
  6660. int result;
  6661. setstackmark(&smark);
  6662. argbackq = pattern->narg.backquote;
  6663. STARTSTACKSTR(expdest);
  6664. ifslastp = NULL;
  6665. argstr(pattern->narg.text, EXP_TILDE | EXP_CASE,
  6666. /* var_str_list: */ NULL);
  6667. STACKSTRNUL(expdest);
  6668. result = patmatch(stackblock(), val);
  6669. popstackmark(&smark);
  6670. return result;
  6671. }
  6672. /* ============ find_command */
  6673. struct builtincmd {
  6674. const char *name;
  6675. int (*builtin)(int, char **) FAST_FUNC;
  6676. /* unsigned flags; */
  6677. };
  6678. #define IS_BUILTIN_SPECIAL(b) ((b)->name[0] & 1)
  6679. /* "regular" builtins always take precedence over commands,
  6680. * regardless of PATH=....%builtin... position */
  6681. #define IS_BUILTIN_REGULAR(b) ((b)->name[0] & 2)
  6682. #define IS_BUILTIN_ASSIGN(b) ((b)->name[0] & 4)
  6683. struct cmdentry {
  6684. smallint cmdtype; /* CMDxxx */
  6685. union param {
  6686. int index;
  6687. /* index >= 0 for commands without path (slashes) */
  6688. /* (TODO: what exactly does the value mean? PATH position?) */
  6689. /* index == -1 for commands with slashes */
  6690. /* index == (-2 - applet_no) for NOFORK applets */
  6691. const struct builtincmd *cmd;
  6692. struct funcnode *func;
  6693. } u;
  6694. };
  6695. /* values of cmdtype */
  6696. #define CMDUNKNOWN -1 /* no entry in table for command */
  6697. #define CMDNORMAL 0 /* command is an executable program */
  6698. #define CMDFUNCTION 1 /* command is a shell function */
  6699. #define CMDBUILTIN 2 /* command is a shell builtin */
  6700. /* action to find_command() */
  6701. #define DO_ERR 0x01 /* prints errors */
  6702. #define DO_ABS 0x02 /* checks absolute paths */
  6703. #define DO_NOFUNC 0x04 /* don't return shell functions, for command */
  6704. #define DO_ALTPATH 0x08 /* using alternate path */
  6705. #define DO_ALTBLTIN 0x20 /* %builtin in alt. path */
  6706. static void find_command(char *, struct cmdentry *, int, const char *);
  6707. /* ============ Hashing commands */
  6708. /*
  6709. * When commands are first encountered, they are entered in a hash table.
  6710. * This ensures that a full path search will not have to be done for them
  6711. * on each invocation.
  6712. *
  6713. * We should investigate converting to a linear search, even though that
  6714. * would make the command name "hash" a misnomer.
  6715. */
  6716. struct tblentry {
  6717. struct tblentry *next; /* next entry in hash chain */
  6718. union param param; /* definition of builtin function */
  6719. smallint cmdtype; /* CMDxxx */
  6720. char rehash; /* if set, cd done since entry created */
  6721. char cmdname[1]; /* name of command */
  6722. };
  6723. static struct tblentry **cmdtable;
  6724. #define INIT_G_cmdtable() do { \
  6725. cmdtable = xzalloc(CMDTABLESIZE * sizeof(cmdtable[0])); \
  6726. } while (0)
  6727. static int builtinloc = -1; /* index in path of %builtin, or -1 */
  6728. static void
  6729. tryexec(IF_FEATURE_SH_STANDALONE(int applet_no,) char *cmd, char **argv, char **envp)
  6730. {
  6731. #if ENABLE_FEATURE_SH_STANDALONE
  6732. if (applet_no >= 0) {
  6733. if (APPLET_IS_NOEXEC(applet_no)) {
  6734. clearenv();
  6735. while (*envp)
  6736. putenv(*envp++);
  6737. run_applet_no_and_exit(applet_no, argv);
  6738. }
  6739. /* re-exec ourselves with the new arguments */
  6740. execve(bb_busybox_exec_path, argv, envp);
  6741. /* If they called chroot or otherwise made the binary no longer
  6742. * executable, fall through */
  6743. }
  6744. #endif
  6745. repeat:
  6746. #ifdef SYSV
  6747. do {
  6748. execve(cmd, argv, envp);
  6749. } while (errno == EINTR);
  6750. #else
  6751. execve(cmd, argv, envp);
  6752. #endif
  6753. if (cmd == (char*) bb_busybox_exec_path) {
  6754. /* We already visited ENOEXEC branch below, don't do it again */
  6755. //TODO: try execve(initial_argv0_of_shell, argv, envp) before giving up?
  6756. free(argv);
  6757. return;
  6758. }
  6759. if (errno == ENOEXEC) {
  6760. /* Run "cmd" as a shell script:
  6761. * http://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html
  6762. * "If the execve() function fails with ENOEXEC, the shell
  6763. * shall execute a command equivalent to having a shell invoked
  6764. * with the command name as its first operand,
  6765. * with any remaining arguments passed to the new shell"
  6766. *
  6767. * That is, do not use $SHELL, user's shell, or /bin/sh;
  6768. * just call ourselves.
  6769. *
  6770. * Note that bash reads ~80 chars of the file, and if it sees
  6771. * a zero byte before it sees newline, it doesn't try to
  6772. * interpret it, but fails with "cannot execute binary file"
  6773. * message and exit code 126. For one, this prevents attempts
  6774. * to interpret foreign ELF binaries as shell scripts.
  6775. */
  6776. char **ap;
  6777. char **new;
  6778. for (ap = argv; *ap; ap++)
  6779. continue;
  6780. new = ckmalloc((ap - argv + 2) * sizeof(new[0]));
  6781. new[0] = (char*) "ash";
  6782. new[1] = cmd;
  6783. ap = new + 2;
  6784. while ((*ap++ = *++argv) != NULL)
  6785. continue;
  6786. cmd = (char*) bb_busybox_exec_path;
  6787. argv = new;
  6788. goto repeat;
  6789. }
  6790. }
  6791. /*
  6792. * Exec a program. Never returns. If you change this routine, you may
  6793. * have to change the find_command routine as well.
  6794. */
  6795. static void shellexec(char **, const char *, int) NORETURN;
  6796. static void
  6797. shellexec(char **argv, const char *path, int idx)
  6798. {
  6799. char *cmdname;
  6800. int e;
  6801. char **envp;
  6802. int exerrno;
  6803. int applet_no = -1; /* used only by FEATURE_SH_STANDALONE */
  6804. clearredir(/*drop:*/ 1);
  6805. envp = listvars(VEXPORT, VUNSET, /*end:*/ NULL);
  6806. if (strchr(argv[0], '/') != NULL
  6807. #if ENABLE_FEATURE_SH_STANDALONE
  6808. || (applet_no = find_applet_by_name(argv[0])) >= 0
  6809. #endif
  6810. ) {
  6811. tryexec(IF_FEATURE_SH_STANDALONE(applet_no,) argv[0], argv, envp);
  6812. if (applet_no >= 0) {
  6813. /* We tried execing ourself, but it didn't work.
  6814. * Maybe /proc/self/exe doesn't exist?
  6815. * Try $PATH search.
  6816. */
  6817. goto try_PATH;
  6818. }
  6819. e = errno;
  6820. } else {
  6821. try_PATH:
  6822. e = ENOENT;
  6823. while ((cmdname = path_advance(&path, argv[0])) != NULL) {
  6824. if (--idx < 0 && pathopt == NULL) {
  6825. tryexec(IF_FEATURE_SH_STANDALONE(-1,) cmdname, argv, envp);
  6826. if (errno != ENOENT && errno != ENOTDIR)
  6827. e = errno;
  6828. }
  6829. stunalloc(cmdname);
  6830. }
  6831. }
  6832. /* Map to POSIX errors */
  6833. switch (e) {
  6834. case EACCES:
  6835. exerrno = 126;
  6836. break;
  6837. case ENOENT:
  6838. exerrno = 127;
  6839. break;
  6840. default:
  6841. exerrno = 2;
  6842. break;
  6843. }
  6844. exitstatus = exerrno;
  6845. TRACE(("shellexec failed for %s, errno %d, suppress_int %d\n",
  6846. argv[0], e, suppress_int));
  6847. ash_msg_and_raise(EXEXEC, "%s: %s", argv[0], errmsg(e, "not found"));
  6848. /* NOTREACHED */
  6849. }
  6850. static void
  6851. printentry(struct tblentry *cmdp)
  6852. {
  6853. int idx;
  6854. const char *path;
  6855. char *name;
  6856. idx = cmdp->param.index;
  6857. path = pathval();
  6858. do {
  6859. name = path_advance(&path, cmdp->cmdname);
  6860. stunalloc(name);
  6861. } while (--idx >= 0);
  6862. out1fmt("%s%s\n", name, (cmdp->rehash ? "*" : nullstr));
  6863. }
  6864. /*
  6865. * Clear out command entries. The argument specifies the first entry in
  6866. * PATH which has changed.
  6867. */
  6868. static void
  6869. clearcmdentry(int firstchange)
  6870. {
  6871. struct tblentry **tblp;
  6872. struct tblentry **pp;
  6873. struct tblentry *cmdp;
  6874. INT_OFF;
  6875. for (tblp = cmdtable; tblp < &cmdtable[CMDTABLESIZE]; tblp++) {
  6876. pp = tblp;
  6877. while ((cmdp = *pp) != NULL) {
  6878. if ((cmdp->cmdtype == CMDNORMAL &&
  6879. cmdp->param.index >= firstchange)
  6880. || (cmdp->cmdtype == CMDBUILTIN &&
  6881. builtinloc >= firstchange)
  6882. ) {
  6883. *pp = cmdp->next;
  6884. free(cmdp);
  6885. } else {
  6886. pp = &cmdp->next;
  6887. }
  6888. }
  6889. }
  6890. INT_ON;
  6891. }
  6892. /*
  6893. * Locate a command in the command hash table. If "add" is nonzero,
  6894. * add the command to the table if it is not already present. The
  6895. * variable "lastcmdentry" is set to point to the address of the link
  6896. * pointing to the entry, so that delete_cmd_entry can delete the
  6897. * entry.
  6898. *
  6899. * Interrupts must be off if called with add != 0.
  6900. */
  6901. static struct tblentry **lastcmdentry;
  6902. static struct tblentry *
  6903. cmdlookup(const char *name, int add)
  6904. {
  6905. unsigned int hashval;
  6906. const char *p;
  6907. struct tblentry *cmdp;
  6908. struct tblentry **pp;
  6909. p = name;
  6910. hashval = (unsigned char)*p << 4;
  6911. while (*p)
  6912. hashval += (unsigned char)*p++;
  6913. hashval &= 0x7FFF;
  6914. pp = &cmdtable[hashval % CMDTABLESIZE];
  6915. for (cmdp = *pp; cmdp; cmdp = cmdp->next) {
  6916. if (strcmp(cmdp->cmdname, name) == 0)
  6917. break;
  6918. pp = &cmdp->next;
  6919. }
  6920. if (add && cmdp == NULL) {
  6921. cmdp = *pp = ckzalloc(sizeof(struct tblentry)
  6922. + strlen(name)
  6923. /* + 1 - already done because
  6924. * tblentry::cmdname is char[1] */);
  6925. /*cmdp->next = NULL; - ckzalloc did it */
  6926. cmdp->cmdtype = CMDUNKNOWN;
  6927. strcpy(cmdp->cmdname, name);
  6928. }
  6929. lastcmdentry = pp;
  6930. return cmdp;
  6931. }
  6932. /*
  6933. * Delete the command entry returned on the last lookup.
  6934. */
  6935. static void
  6936. delete_cmd_entry(void)
  6937. {
  6938. struct tblentry *cmdp;
  6939. INT_OFF;
  6940. cmdp = *lastcmdentry;
  6941. *lastcmdentry = cmdp->next;
  6942. if (cmdp->cmdtype == CMDFUNCTION)
  6943. freefunc(cmdp->param.func);
  6944. free(cmdp);
  6945. INT_ON;
  6946. }
  6947. /*
  6948. * Add a new command entry, replacing any existing command entry for
  6949. * the same name - except special builtins.
  6950. */
  6951. static void
  6952. addcmdentry(char *name, struct cmdentry *entry)
  6953. {
  6954. struct tblentry *cmdp;
  6955. cmdp = cmdlookup(name, 1);
  6956. if (cmdp->cmdtype == CMDFUNCTION) {
  6957. freefunc(cmdp->param.func);
  6958. }
  6959. cmdp->cmdtype = entry->cmdtype;
  6960. cmdp->param = entry->u;
  6961. cmdp->rehash = 0;
  6962. }
  6963. static int FAST_FUNC
  6964. hashcmd(int argc UNUSED_PARAM, char **argv UNUSED_PARAM)
  6965. {
  6966. struct tblentry **pp;
  6967. struct tblentry *cmdp;
  6968. int c;
  6969. struct cmdentry entry;
  6970. char *name;
  6971. if (nextopt("r") != '\0') {
  6972. clearcmdentry(0);
  6973. return 0;
  6974. }
  6975. if (*argptr == NULL) {
  6976. for (pp = cmdtable; pp < &cmdtable[CMDTABLESIZE]; pp++) {
  6977. for (cmdp = *pp; cmdp; cmdp = cmdp->next) {
  6978. if (cmdp->cmdtype == CMDNORMAL)
  6979. printentry(cmdp);
  6980. }
  6981. }
  6982. return 0;
  6983. }
  6984. c = 0;
  6985. while ((name = *argptr) != NULL) {
  6986. cmdp = cmdlookup(name, 0);
  6987. if (cmdp != NULL
  6988. && (cmdp->cmdtype == CMDNORMAL
  6989. || (cmdp->cmdtype == CMDBUILTIN && builtinloc >= 0))
  6990. ) {
  6991. delete_cmd_entry();
  6992. }
  6993. find_command(name, &entry, DO_ERR, pathval());
  6994. if (entry.cmdtype == CMDUNKNOWN)
  6995. c = 1;
  6996. argptr++;
  6997. }
  6998. return c;
  6999. }
  7000. /*
  7001. * Called when a cd is done. Marks all commands so the next time they
  7002. * are executed they will be rehashed.
  7003. */
  7004. static void
  7005. hashcd(void)
  7006. {
  7007. struct tblentry **pp;
  7008. struct tblentry *cmdp;
  7009. for (pp = cmdtable; pp < &cmdtable[CMDTABLESIZE]; pp++) {
  7010. for (cmdp = *pp; cmdp; cmdp = cmdp->next) {
  7011. if (cmdp->cmdtype == CMDNORMAL
  7012. || (cmdp->cmdtype == CMDBUILTIN
  7013. && !IS_BUILTIN_REGULAR(cmdp->param.cmd)
  7014. && builtinloc > 0)
  7015. ) {
  7016. cmdp->rehash = 1;
  7017. }
  7018. }
  7019. }
  7020. }
  7021. /*
  7022. * Fix command hash table when PATH changed.
  7023. * Called before PATH is changed. The argument is the new value of PATH;
  7024. * pathval() still returns the old value at this point.
  7025. * Called with interrupts off.
  7026. */
  7027. static void FAST_FUNC
  7028. changepath(const char *new)
  7029. {
  7030. const char *old;
  7031. int firstchange;
  7032. int idx;
  7033. int idx_bltin;
  7034. old = pathval();
  7035. firstchange = 9999; /* assume no change */
  7036. idx = 0;
  7037. idx_bltin = -1;
  7038. for (;;) {
  7039. if (*old != *new) {
  7040. firstchange = idx;
  7041. if ((*old == '\0' && *new == ':')
  7042. || (*old == ':' && *new == '\0')
  7043. ) {
  7044. firstchange++;
  7045. }
  7046. old = new; /* ignore subsequent differences */
  7047. }
  7048. if (*new == '\0')
  7049. break;
  7050. if (*new == '%' && idx_bltin < 0 && prefix(new + 1, "builtin"))
  7051. idx_bltin = idx;
  7052. if (*new == ':')
  7053. idx++;
  7054. new++;
  7055. old++;
  7056. }
  7057. if (builtinloc < 0 && idx_bltin >= 0)
  7058. builtinloc = idx_bltin; /* zap builtins */
  7059. if (builtinloc >= 0 && idx_bltin < 0)
  7060. firstchange = 0;
  7061. clearcmdentry(firstchange);
  7062. builtinloc = idx_bltin;
  7063. }
  7064. #define TEOF 0
  7065. #define TNL 1
  7066. #define TREDIR 2
  7067. #define TWORD 3
  7068. #define TSEMI 4
  7069. #define TBACKGND 5
  7070. #define TAND 6
  7071. #define TOR 7
  7072. #define TPIPE 8
  7073. #define TLP 9
  7074. #define TRP 10
  7075. #define TENDCASE 11
  7076. #define TENDBQUOTE 12
  7077. #define TNOT 13
  7078. #define TCASE 14
  7079. #define TDO 15
  7080. #define TDONE 16
  7081. #define TELIF 17
  7082. #define TELSE 18
  7083. #define TESAC 19
  7084. #define TFI 20
  7085. #define TFOR 21
  7086. #define TIF 22
  7087. #define TIN 23
  7088. #define TTHEN 24
  7089. #define TUNTIL 25
  7090. #define TWHILE 26
  7091. #define TBEGIN 27
  7092. #define TEND 28
  7093. typedef smallint token_id_t;
  7094. /* first char is indicating which tokens mark the end of a list */
  7095. static const char *const tokname_array[] = {
  7096. "\1end of file",
  7097. "\0newline",
  7098. "\0redirection",
  7099. "\0word",
  7100. "\0;",
  7101. "\0&",
  7102. "\0&&",
  7103. "\0||",
  7104. "\0|",
  7105. "\0(",
  7106. "\1)",
  7107. "\1;;",
  7108. "\1`",
  7109. #define KWDOFFSET 13
  7110. /* the following are keywords */
  7111. "\0!",
  7112. "\0case",
  7113. "\1do",
  7114. "\1done",
  7115. "\1elif",
  7116. "\1else",
  7117. "\1esac",
  7118. "\1fi",
  7119. "\0for",
  7120. "\0if",
  7121. "\0in",
  7122. "\1then",
  7123. "\0until",
  7124. "\0while",
  7125. "\0{",
  7126. "\1}",
  7127. };
  7128. /* Wrapper around strcmp for qsort/bsearch/... */
  7129. static int
  7130. pstrcmp(const void *a, const void *b)
  7131. {
  7132. return strcmp((char*) a, (*(char**) b) + 1);
  7133. }
  7134. static const char *const *
  7135. findkwd(const char *s)
  7136. {
  7137. return bsearch(s, tokname_array + KWDOFFSET,
  7138. ARRAY_SIZE(tokname_array) - KWDOFFSET,
  7139. sizeof(tokname_array[0]), pstrcmp);
  7140. }
  7141. /*
  7142. * Locate and print what a word is...
  7143. */
  7144. static int
  7145. describe_command(char *command, int describe_command_verbose)
  7146. {
  7147. struct cmdentry entry;
  7148. struct tblentry *cmdp;
  7149. #if ENABLE_ASH_ALIAS
  7150. const struct alias *ap;
  7151. #endif
  7152. const char *path = pathval();
  7153. if (describe_command_verbose) {
  7154. out1str(command);
  7155. }
  7156. /* First look at the keywords */
  7157. if (findkwd(command)) {
  7158. out1str(describe_command_verbose ? " is a shell keyword" : command);
  7159. goto out;
  7160. }
  7161. #if ENABLE_ASH_ALIAS
  7162. /* Then look at the aliases */
  7163. ap = lookupalias(command, 0);
  7164. if (ap != NULL) {
  7165. if (!describe_command_verbose) {
  7166. out1str("alias ");
  7167. printalias(ap);
  7168. return 0;
  7169. }
  7170. out1fmt(" is an alias for %s", ap->val);
  7171. goto out;
  7172. }
  7173. #endif
  7174. /* Then check if it is a tracked alias */
  7175. cmdp = cmdlookup(command, 0);
  7176. if (cmdp != NULL) {
  7177. entry.cmdtype = cmdp->cmdtype;
  7178. entry.u = cmdp->param;
  7179. } else {
  7180. /* Finally use brute force */
  7181. find_command(command, &entry, DO_ABS, path);
  7182. }
  7183. switch (entry.cmdtype) {
  7184. case CMDNORMAL: {
  7185. int j = entry.u.index;
  7186. char *p;
  7187. if (j < 0) {
  7188. p = command;
  7189. } else {
  7190. do {
  7191. p = path_advance(&path, command);
  7192. stunalloc(p);
  7193. } while (--j >= 0);
  7194. }
  7195. if (describe_command_verbose) {
  7196. out1fmt(" is%s %s",
  7197. (cmdp ? " a tracked alias for" : nullstr), p
  7198. );
  7199. } else {
  7200. out1str(p);
  7201. }
  7202. break;
  7203. }
  7204. case CMDFUNCTION:
  7205. if (describe_command_verbose) {
  7206. out1str(" is a shell function");
  7207. } else {
  7208. out1str(command);
  7209. }
  7210. break;
  7211. case CMDBUILTIN:
  7212. if (describe_command_verbose) {
  7213. out1fmt(" is a %sshell builtin",
  7214. IS_BUILTIN_SPECIAL(entry.u.cmd) ?
  7215. "special " : nullstr
  7216. );
  7217. } else {
  7218. out1str(command);
  7219. }
  7220. break;
  7221. default:
  7222. if (describe_command_verbose) {
  7223. out1str(": not found\n");
  7224. }
  7225. return 127;
  7226. }
  7227. out:
  7228. out1str("\n");
  7229. return 0;
  7230. }
  7231. static int FAST_FUNC
  7232. typecmd(int argc UNUSED_PARAM, char **argv)
  7233. {
  7234. int i = 1;
  7235. int err = 0;
  7236. int verbose = 1;
  7237. /* type -p ... ? (we don't bother checking for 'p') */
  7238. if (argv[1] && argv[1][0] == '-') {
  7239. i++;
  7240. verbose = 0;
  7241. }
  7242. while (argv[i]) {
  7243. err |= describe_command(argv[i++], verbose);
  7244. }
  7245. return err;
  7246. }
  7247. #if ENABLE_ASH_CMDCMD
  7248. static int FAST_FUNC
  7249. commandcmd(int argc UNUSED_PARAM, char **argv UNUSED_PARAM)
  7250. {
  7251. int c;
  7252. enum {
  7253. VERIFY_BRIEF = 1,
  7254. VERIFY_VERBOSE = 2,
  7255. } verify = 0;
  7256. while ((c = nextopt("pvV")) != '\0')
  7257. if (c == 'V')
  7258. verify |= VERIFY_VERBOSE;
  7259. else if (c == 'v')
  7260. verify |= VERIFY_BRIEF;
  7261. #if DEBUG
  7262. else if (c != 'p')
  7263. abort();
  7264. #endif
  7265. /* Mimic bash: just "command -v" doesn't complain, it's a nop */
  7266. if (verify && (*argptr != NULL)) {
  7267. return describe_command(*argptr, verify - VERIFY_BRIEF);
  7268. }
  7269. return 0;
  7270. }
  7271. #endif
  7272. /* ============ eval.c */
  7273. static int funcblocksize; /* size of structures in function */
  7274. static int funcstringsize; /* size of strings in node */
  7275. static void *funcblock; /* block to allocate function from */
  7276. static char *funcstring; /* block to allocate strings from */
  7277. /* flags in argument to evaltree */
  7278. #define EV_EXIT 01 /* exit after evaluating tree */
  7279. #define EV_TESTED 02 /* exit status is checked; ignore -e flag */
  7280. #define EV_BACKCMD 04 /* command executing within back quotes */
  7281. static const uint8_t nodesize[N_NUMBER] = {
  7282. [NCMD ] = SHELL_ALIGN(sizeof(struct ncmd)),
  7283. [NPIPE ] = SHELL_ALIGN(sizeof(struct npipe)),
  7284. [NREDIR ] = SHELL_ALIGN(sizeof(struct nredir)),
  7285. [NBACKGND ] = SHELL_ALIGN(sizeof(struct nredir)),
  7286. [NSUBSHELL] = SHELL_ALIGN(sizeof(struct nredir)),
  7287. [NAND ] = SHELL_ALIGN(sizeof(struct nbinary)),
  7288. [NOR ] = SHELL_ALIGN(sizeof(struct nbinary)),
  7289. [NSEMI ] = SHELL_ALIGN(sizeof(struct nbinary)),
  7290. [NIF ] = SHELL_ALIGN(sizeof(struct nif)),
  7291. [NWHILE ] = SHELL_ALIGN(sizeof(struct nbinary)),
  7292. [NUNTIL ] = SHELL_ALIGN(sizeof(struct nbinary)),
  7293. [NFOR ] = SHELL_ALIGN(sizeof(struct nfor)),
  7294. [NCASE ] = SHELL_ALIGN(sizeof(struct ncase)),
  7295. [NCLIST ] = SHELL_ALIGN(sizeof(struct nclist)),
  7296. [NDEFUN ] = SHELL_ALIGN(sizeof(struct narg)),
  7297. [NARG ] = SHELL_ALIGN(sizeof(struct narg)),
  7298. [NTO ] = SHELL_ALIGN(sizeof(struct nfile)),
  7299. #if ENABLE_ASH_BASH_COMPAT
  7300. [NTO2 ] = SHELL_ALIGN(sizeof(struct nfile)),
  7301. #endif
  7302. [NCLOBBER ] = SHELL_ALIGN(sizeof(struct nfile)),
  7303. [NFROM ] = SHELL_ALIGN(sizeof(struct nfile)),
  7304. [NFROMTO ] = SHELL_ALIGN(sizeof(struct nfile)),
  7305. [NAPPEND ] = SHELL_ALIGN(sizeof(struct nfile)),
  7306. [NTOFD ] = SHELL_ALIGN(sizeof(struct ndup)),
  7307. [NFROMFD ] = SHELL_ALIGN(sizeof(struct ndup)),
  7308. [NHERE ] = SHELL_ALIGN(sizeof(struct nhere)),
  7309. [NXHERE ] = SHELL_ALIGN(sizeof(struct nhere)),
  7310. [NNOT ] = SHELL_ALIGN(sizeof(struct nnot)),
  7311. };
  7312. static void calcsize(union node *n);
  7313. static void
  7314. sizenodelist(struct nodelist *lp)
  7315. {
  7316. while (lp) {
  7317. funcblocksize += SHELL_ALIGN(sizeof(struct nodelist));
  7318. calcsize(lp->n);
  7319. lp = lp->next;
  7320. }
  7321. }
  7322. static void
  7323. calcsize(union node *n)
  7324. {
  7325. if (n == NULL)
  7326. return;
  7327. funcblocksize += nodesize[n->type];
  7328. switch (n->type) {
  7329. case NCMD:
  7330. calcsize(n->ncmd.redirect);
  7331. calcsize(n->ncmd.args);
  7332. calcsize(n->ncmd.assign);
  7333. break;
  7334. case NPIPE:
  7335. sizenodelist(n->npipe.cmdlist);
  7336. break;
  7337. case NREDIR:
  7338. case NBACKGND:
  7339. case NSUBSHELL:
  7340. calcsize(n->nredir.redirect);
  7341. calcsize(n->nredir.n);
  7342. break;
  7343. case NAND:
  7344. case NOR:
  7345. case NSEMI:
  7346. case NWHILE:
  7347. case NUNTIL:
  7348. calcsize(n->nbinary.ch2);
  7349. calcsize(n->nbinary.ch1);
  7350. break;
  7351. case NIF:
  7352. calcsize(n->nif.elsepart);
  7353. calcsize(n->nif.ifpart);
  7354. calcsize(n->nif.test);
  7355. break;
  7356. case NFOR:
  7357. funcstringsize += strlen(n->nfor.var) + 1;
  7358. calcsize(n->nfor.body);
  7359. calcsize(n->nfor.args);
  7360. break;
  7361. case NCASE:
  7362. calcsize(n->ncase.cases);
  7363. calcsize(n->ncase.expr);
  7364. break;
  7365. case NCLIST:
  7366. calcsize(n->nclist.body);
  7367. calcsize(n->nclist.pattern);
  7368. calcsize(n->nclist.next);
  7369. break;
  7370. case NDEFUN:
  7371. case NARG:
  7372. sizenodelist(n->narg.backquote);
  7373. funcstringsize += strlen(n->narg.text) + 1;
  7374. calcsize(n->narg.next);
  7375. break;
  7376. case NTO:
  7377. #if ENABLE_ASH_BASH_COMPAT
  7378. case NTO2:
  7379. #endif
  7380. case NCLOBBER:
  7381. case NFROM:
  7382. case NFROMTO:
  7383. case NAPPEND:
  7384. calcsize(n->nfile.fname);
  7385. calcsize(n->nfile.next);
  7386. break;
  7387. case NTOFD:
  7388. case NFROMFD:
  7389. calcsize(n->ndup.vname);
  7390. calcsize(n->ndup.next);
  7391. break;
  7392. case NHERE:
  7393. case NXHERE:
  7394. calcsize(n->nhere.doc);
  7395. calcsize(n->nhere.next);
  7396. break;
  7397. case NNOT:
  7398. calcsize(n->nnot.com);
  7399. break;
  7400. };
  7401. }
  7402. static char *
  7403. nodeckstrdup(char *s)
  7404. {
  7405. char *rtn = funcstring;
  7406. strcpy(funcstring, s);
  7407. funcstring += strlen(s) + 1;
  7408. return rtn;
  7409. }
  7410. static union node *copynode(union node *);
  7411. static struct nodelist *
  7412. copynodelist(struct nodelist *lp)
  7413. {
  7414. struct nodelist *start;
  7415. struct nodelist **lpp;
  7416. lpp = &start;
  7417. while (lp) {
  7418. *lpp = funcblock;
  7419. funcblock = (char *) funcblock + SHELL_ALIGN(sizeof(struct nodelist));
  7420. (*lpp)->n = copynode(lp->n);
  7421. lp = lp->next;
  7422. lpp = &(*lpp)->next;
  7423. }
  7424. *lpp = NULL;
  7425. return start;
  7426. }
  7427. static union node *
  7428. copynode(union node *n)
  7429. {
  7430. union node *new;
  7431. if (n == NULL)
  7432. return NULL;
  7433. new = funcblock;
  7434. funcblock = (char *) funcblock + nodesize[n->type];
  7435. switch (n->type) {
  7436. case NCMD:
  7437. new->ncmd.redirect = copynode(n->ncmd.redirect);
  7438. new->ncmd.args = copynode(n->ncmd.args);
  7439. new->ncmd.assign = copynode(n->ncmd.assign);
  7440. break;
  7441. case NPIPE:
  7442. new->npipe.cmdlist = copynodelist(n->npipe.cmdlist);
  7443. new->npipe.pipe_backgnd = n->npipe.pipe_backgnd;
  7444. break;
  7445. case NREDIR:
  7446. case NBACKGND:
  7447. case NSUBSHELL:
  7448. new->nredir.redirect = copynode(n->nredir.redirect);
  7449. new->nredir.n = copynode(n->nredir.n);
  7450. break;
  7451. case NAND:
  7452. case NOR:
  7453. case NSEMI:
  7454. case NWHILE:
  7455. case NUNTIL:
  7456. new->nbinary.ch2 = copynode(n->nbinary.ch2);
  7457. new->nbinary.ch1 = copynode(n->nbinary.ch1);
  7458. break;
  7459. case NIF:
  7460. new->nif.elsepart = copynode(n->nif.elsepart);
  7461. new->nif.ifpart = copynode(n->nif.ifpart);
  7462. new->nif.test = copynode(n->nif.test);
  7463. break;
  7464. case NFOR:
  7465. new->nfor.var = nodeckstrdup(n->nfor.var);
  7466. new->nfor.body = copynode(n->nfor.body);
  7467. new->nfor.args = copynode(n->nfor.args);
  7468. break;
  7469. case NCASE:
  7470. new->ncase.cases = copynode(n->ncase.cases);
  7471. new->ncase.expr = copynode(n->ncase.expr);
  7472. break;
  7473. case NCLIST:
  7474. new->nclist.body = copynode(n->nclist.body);
  7475. new->nclist.pattern = copynode(n->nclist.pattern);
  7476. new->nclist.next = copynode(n->nclist.next);
  7477. break;
  7478. case NDEFUN:
  7479. case NARG:
  7480. new->narg.backquote = copynodelist(n->narg.backquote);
  7481. new->narg.text = nodeckstrdup(n->narg.text);
  7482. new->narg.next = copynode(n->narg.next);
  7483. break;
  7484. case NTO:
  7485. #if ENABLE_ASH_BASH_COMPAT
  7486. case NTO2:
  7487. #endif
  7488. case NCLOBBER:
  7489. case NFROM:
  7490. case NFROMTO:
  7491. case NAPPEND:
  7492. new->nfile.fname = copynode(n->nfile.fname);
  7493. new->nfile.fd = n->nfile.fd;
  7494. new->nfile.next = copynode(n->nfile.next);
  7495. break;
  7496. case NTOFD:
  7497. case NFROMFD:
  7498. new->ndup.vname = copynode(n->ndup.vname);
  7499. new->ndup.dupfd = n->ndup.dupfd;
  7500. new->ndup.fd = n->ndup.fd;
  7501. new->ndup.next = copynode(n->ndup.next);
  7502. break;
  7503. case NHERE:
  7504. case NXHERE:
  7505. new->nhere.doc = copynode(n->nhere.doc);
  7506. new->nhere.fd = n->nhere.fd;
  7507. new->nhere.next = copynode(n->nhere.next);
  7508. break;
  7509. case NNOT:
  7510. new->nnot.com = copynode(n->nnot.com);
  7511. break;
  7512. };
  7513. new->type = n->type;
  7514. return new;
  7515. }
  7516. /*
  7517. * Make a copy of a parse tree.
  7518. */
  7519. static struct funcnode *
  7520. copyfunc(union node *n)
  7521. {
  7522. struct funcnode *f;
  7523. size_t blocksize;
  7524. funcblocksize = offsetof(struct funcnode, n);
  7525. funcstringsize = 0;
  7526. calcsize(n);
  7527. blocksize = funcblocksize;
  7528. f = ckmalloc(blocksize + funcstringsize);
  7529. funcblock = (char *) f + offsetof(struct funcnode, n);
  7530. funcstring = (char *) f + blocksize;
  7531. copynode(n);
  7532. f->count = 0;
  7533. return f;
  7534. }
  7535. /*
  7536. * Define a shell function.
  7537. */
  7538. static void
  7539. defun(char *name, union node *func)
  7540. {
  7541. struct cmdentry entry;
  7542. INT_OFF;
  7543. entry.cmdtype = CMDFUNCTION;
  7544. entry.u.func = copyfunc(func);
  7545. addcmdentry(name, &entry);
  7546. INT_ON;
  7547. }
  7548. /* Reasons for skipping commands (see comment on breakcmd routine) */
  7549. #define SKIPBREAK (1 << 0)
  7550. #define SKIPCONT (1 << 1)
  7551. #define SKIPFUNC (1 << 2)
  7552. #define SKIPFILE (1 << 3)
  7553. #define SKIPEVAL (1 << 4)
  7554. static smallint evalskip; /* set to SKIPxxx if we are skipping commands */
  7555. static int skipcount; /* number of levels to skip */
  7556. static int funcnest; /* depth of function calls */
  7557. static int loopnest; /* current loop nesting level */
  7558. /* Forward decl way out to parsing code - dotrap needs it */
  7559. static int evalstring(char *s, int mask);
  7560. /* Called to execute a trap.
  7561. * Single callsite - at the end of evaltree().
  7562. * If we return non-zero, evaltree raises EXEXIT exception.
  7563. *
  7564. * Perhaps we should avoid entering new trap handlers
  7565. * while we are executing a trap handler. [is it a TODO?]
  7566. */
  7567. static int
  7568. dotrap(void)
  7569. {
  7570. uint8_t *g;
  7571. int sig;
  7572. uint8_t savestatus;
  7573. savestatus = exitstatus;
  7574. pending_sig = 0;
  7575. xbarrier();
  7576. TRACE(("dotrap entered\n"));
  7577. for (sig = 1, g = gotsig; sig < NSIG; sig++, g++) {
  7578. int want_exexit;
  7579. char *t;
  7580. if (*g == 0)
  7581. continue;
  7582. t = trap[sig];
  7583. /* non-trapped SIGINT is handled separately by raise_interrupt,
  7584. * don't upset it by resetting gotsig[SIGINT-1] */
  7585. if (sig == SIGINT && !t)
  7586. continue;
  7587. TRACE(("sig %d is active, will run handler '%s'\n", sig, t));
  7588. *g = 0;
  7589. if (!t)
  7590. continue;
  7591. want_exexit = evalstring(t, SKIPEVAL);
  7592. exitstatus = savestatus;
  7593. if (want_exexit) {
  7594. TRACE(("dotrap returns %d\n", want_exexit));
  7595. return want_exexit;
  7596. }
  7597. }
  7598. TRACE(("dotrap returns 0\n"));
  7599. return 0;
  7600. }
  7601. /* forward declarations - evaluation is fairly recursive business... */
  7602. static void evalloop(union node *, int);
  7603. static void evalfor(union node *, int);
  7604. static void evalcase(union node *, int);
  7605. static void evalsubshell(union node *, int);
  7606. static void expredir(union node *);
  7607. static void evalpipe(union node *, int);
  7608. static void evalcommand(union node *, int);
  7609. static int evalbltin(const struct builtincmd *, int, char **);
  7610. static void prehash(union node *);
  7611. /*
  7612. * Evaluate a parse tree. The value is left in the global variable
  7613. * exitstatus.
  7614. */
  7615. static void
  7616. evaltree(union node *n, int flags)
  7617. {
  7618. struct jmploc *volatile savehandler = exception_handler;
  7619. struct jmploc jmploc;
  7620. int checkexit = 0;
  7621. void (*evalfn)(union node *, int);
  7622. int status;
  7623. int int_level;
  7624. SAVE_INT(int_level);
  7625. if (n == NULL) {
  7626. TRACE(("evaltree(NULL) called\n"));
  7627. goto out1;
  7628. }
  7629. TRACE(("evaltree(%p: %d, %d) called\n", n, n->type, flags));
  7630. exception_handler = &jmploc;
  7631. {
  7632. int err = setjmp(jmploc.loc);
  7633. if (err) {
  7634. /* if it was a signal, check for trap handlers */
  7635. if (exception_type == EXSIG) {
  7636. TRACE(("exception %d (EXSIG) in evaltree, err=%d\n",
  7637. exception_type, err));
  7638. goto out;
  7639. }
  7640. /* continue on the way out */
  7641. TRACE(("exception %d in evaltree, propagating err=%d\n",
  7642. exception_type, err));
  7643. exception_handler = savehandler;
  7644. longjmp(exception_handler->loc, err);
  7645. }
  7646. }
  7647. switch (n->type) {
  7648. default:
  7649. #if DEBUG
  7650. out1fmt("Node type = %d\n", n->type);
  7651. fflush_all();
  7652. break;
  7653. #endif
  7654. case NNOT:
  7655. evaltree(n->nnot.com, EV_TESTED);
  7656. status = !exitstatus;
  7657. goto setstatus;
  7658. case NREDIR:
  7659. expredir(n->nredir.redirect);
  7660. status = redirectsafe(n->nredir.redirect, REDIR_PUSH);
  7661. if (!status) {
  7662. evaltree(n->nredir.n, flags & EV_TESTED);
  7663. status = exitstatus;
  7664. }
  7665. popredir(/*drop:*/ 0, /*restore:*/ 0 /* not sure */);
  7666. goto setstatus;
  7667. case NCMD:
  7668. evalfn = evalcommand;
  7669. checkexit:
  7670. if (eflag && !(flags & EV_TESTED))
  7671. checkexit = ~0;
  7672. goto calleval;
  7673. case NFOR:
  7674. evalfn = evalfor;
  7675. goto calleval;
  7676. case NWHILE:
  7677. case NUNTIL:
  7678. evalfn = evalloop;
  7679. goto calleval;
  7680. case NSUBSHELL:
  7681. case NBACKGND:
  7682. evalfn = evalsubshell;
  7683. goto calleval;
  7684. case NPIPE:
  7685. evalfn = evalpipe;
  7686. goto checkexit;
  7687. case NCASE:
  7688. evalfn = evalcase;
  7689. goto calleval;
  7690. case NAND:
  7691. case NOR:
  7692. case NSEMI: {
  7693. #if NAND + 1 != NOR
  7694. #error NAND + 1 != NOR
  7695. #endif
  7696. #if NOR + 1 != NSEMI
  7697. #error NOR + 1 != NSEMI
  7698. #endif
  7699. unsigned is_or = n->type - NAND;
  7700. evaltree(
  7701. n->nbinary.ch1,
  7702. (flags | ((is_or >> 1) - 1)) & EV_TESTED
  7703. );
  7704. if (!exitstatus == is_or)
  7705. break;
  7706. if (!evalskip) {
  7707. n = n->nbinary.ch2;
  7708. evaln:
  7709. evalfn = evaltree;
  7710. calleval:
  7711. evalfn(n, flags);
  7712. break;
  7713. }
  7714. break;
  7715. }
  7716. case NIF:
  7717. evaltree(n->nif.test, EV_TESTED);
  7718. if (evalskip)
  7719. break;
  7720. if (exitstatus == 0) {
  7721. n = n->nif.ifpart;
  7722. goto evaln;
  7723. }
  7724. if (n->nif.elsepart) {
  7725. n = n->nif.elsepart;
  7726. goto evaln;
  7727. }
  7728. goto success;
  7729. case NDEFUN:
  7730. defun(n->narg.text, n->narg.next);
  7731. success:
  7732. status = 0;
  7733. setstatus:
  7734. exitstatus = status;
  7735. break;
  7736. }
  7737. out:
  7738. exception_handler = savehandler;
  7739. out1:
  7740. /* Order of checks below is important:
  7741. * signal handlers trigger before exit caused by "set -e".
  7742. */
  7743. if (pending_sig && dotrap())
  7744. goto exexit;
  7745. if (checkexit & exitstatus)
  7746. evalskip |= SKIPEVAL;
  7747. if (flags & EV_EXIT) {
  7748. exexit:
  7749. raise_exception(EXEXIT);
  7750. }
  7751. RESTORE_INT(int_level);
  7752. TRACE(("leaving evaltree (no interrupts)\n"));
  7753. }
  7754. #if !defined(__alpha__) || (defined(__GNUC__) && __GNUC__ >= 3)
  7755. static
  7756. #endif
  7757. void evaltreenr(union node *, int) __attribute__ ((alias("evaltree"),__noreturn__));
  7758. static void
  7759. evalloop(union node *n, int flags)
  7760. {
  7761. int status;
  7762. loopnest++;
  7763. status = 0;
  7764. flags &= EV_TESTED;
  7765. for (;;) {
  7766. int i;
  7767. evaltree(n->nbinary.ch1, EV_TESTED);
  7768. if (evalskip) {
  7769. skipping:
  7770. if (evalskip == SKIPCONT && --skipcount <= 0) {
  7771. evalskip = 0;
  7772. continue;
  7773. }
  7774. if (evalskip == SKIPBREAK && --skipcount <= 0)
  7775. evalskip = 0;
  7776. break;
  7777. }
  7778. i = exitstatus;
  7779. if (n->type != NWHILE)
  7780. i = !i;
  7781. if (i != 0)
  7782. break;
  7783. evaltree(n->nbinary.ch2, flags);
  7784. status = exitstatus;
  7785. if (evalskip)
  7786. goto skipping;
  7787. }
  7788. loopnest--;
  7789. exitstatus = status;
  7790. }
  7791. static void
  7792. evalfor(union node *n, int flags)
  7793. {
  7794. struct arglist arglist;
  7795. union node *argp;
  7796. struct strlist *sp;
  7797. struct stackmark smark;
  7798. setstackmark(&smark);
  7799. arglist.list = NULL;
  7800. arglist.lastp = &arglist.list;
  7801. for (argp = n->nfor.args; argp; argp = argp->narg.next) {
  7802. expandarg(argp, &arglist, EXP_FULL | EXP_TILDE | EXP_RECORD);
  7803. /* XXX */
  7804. if (evalskip)
  7805. goto out;
  7806. }
  7807. *arglist.lastp = NULL;
  7808. exitstatus = 0;
  7809. loopnest++;
  7810. flags &= EV_TESTED;
  7811. for (sp = arglist.list; sp; sp = sp->next) {
  7812. setvar2(n->nfor.var, sp->text);
  7813. evaltree(n->nfor.body, flags);
  7814. if (evalskip) {
  7815. if (evalskip == SKIPCONT && --skipcount <= 0) {
  7816. evalskip = 0;
  7817. continue;
  7818. }
  7819. if (evalskip == SKIPBREAK && --skipcount <= 0)
  7820. evalskip = 0;
  7821. break;
  7822. }
  7823. }
  7824. loopnest--;
  7825. out:
  7826. popstackmark(&smark);
  7827. }
  7828. static void
  7829. evalcase(union node *n, int flags)
  7830. {
  7831. union node *cp;
  7832. union node *patp;
  7833. struct arglist arglist;
  7834. struct stackmark smark;
  7835. setstackmark(&smark);
  7836. arglist.list = NULL;
  7837. arglist.lastp = &arglist.list;
  7838. expandarg(n->ncase.expr, &arglist, EXP_TILDE);
  7839. exitstatus = 0;
  7840. for (cp = n->ncase.cases; cp && evalskip == 0; cp = cp->nclist.next) {
  7841. for (patp = cp->nclist.pattern; patp; patp = patp->narg.next) {
  7842. if (casematch(patp, arglist.list->text)) {
  7843. if (evalskip == 0) {
  7844. evaltree(cp->nclist.body, flags);
  7845. }
  7846. goto out;
  7847. }
  7848. }
  7849. }
  7850. out:
  7851. popstackmark(&smark);
  7852. }
  7853. /*
  7854. * Kick off a subshell to evaluate a tree.
  7855. */
  7856. static void
  7857. evalsubshell(union node *n, int flags)
  7858. {
  7859. struct job *jp;
  7860. int backgnd = (n->type == NBACKGND);
  7861. int status;
  7862. expredir(n->nredir.redirect);
  7863. if (!backgnd && (flags & EV_EXIT) && !may_have_traps)
  7864. goto nofork;
  7865. INT_OFF;
  7866. jp = makejob(/*n,*/ 1);
  7867. if (forkshell(jp, n, backgnd) == 0) {
  7868. /* child */
  7869. INT_ON;
  7870. flags |= EV_EXIT;
  7871. if (backgnd)
  7872. flags &= ~EV_TESTED;
  7873. nofork:
  7874. redirect(n->nredir.redirect, 0);
  7875. evaltreenr(n->nredir.n, flags);
  7876. /* never returns */
  7877. }
  7878. status = 0;
  7879. if (!backgnd)
  7880. status = waitforjob(jp);
  7881. exitstatus = status;
  7882. INT_ON;
  7883. }
  7884. /*
  7885. * Compute the names of the files in a redirection list.
  7886. */
  7887. static void fixredir(union node *, const char *, int);
  7888. static void
  7889. expredir(union node *n)
  7890. {
  7891. union node *redir;
  7892. for (redir = n; redir; redir = redir->nfile.next) {
  7893. struct arglist fn;
  7894. fn.list = NULL;
  7895. fn.lastp = &fn.list;
  7896. switch (redir->type) {
  7897. case NFROMTO:
  7898. case NFROM:
  7899. case NTO:
  7900. #if ENABLE_ASH_BASH_COMPAT
  7901. case NTO2:
  7902. #endif
  7903. case NCLOBBER:
  7904. case NAPPEND:
  7905. expandarg(redir->nfile.fname, &fn, EXP_TILDE | EXP_REDIR);
  7906. TRACE(("expredir expanded to '%s'\n", fn.list->text));
  7907. #if ENABLE_ASH_BASH_COMPAT
  7908. store_expfname:
  7909. #endif
  7910. #if 0
  7911. // By the design of stack allocator, the loop of this kind:
  7912. // while true; do while true; do break; done </dev/null; done
  7913. // will look like a memory leak: ash plans to free expfname's
  7914. // of "/dev/null" as soon as it finishes running the loop
  7915. // (in this case, never).
  7916. // This "fix" is wrong:
  7917. if (redir->nfile.expfname)
  7918. stunalloc(redir->nfile.expfname);
  7919. // It results in corrupted state of stacked allocations.
  7920. #endif
  7921. redir->nfile.expfname = fn.list->text;
  7922. break;
  7923. case NFROMFD:
  7924. case NTOFD: /* >& */
  7925. if (redir->ndup.vname) {
  7926. expandarg(redir->ndup.vname, &fn, EXP_FULL | EXP_TILDE);
  7927. if (fn.list == NULL)
  7928. ash_msg_and_raise_error("redir error");
  7929. #if ENABLE_ASH_BASH_COMPAT
  7930. //FIXME: we used expandarg with different args!
  7931. if (!isdigit_str9(fn.list->text)) {
  7932. /* >&file, not >&fd */
  7933. if (redir->nfile.fd != 1) /* 123>&file - BAD */
  7934. ash_msg_and_raise_error("redir error");
  7935. redir->type = NTO2;
  7936. goto store_expfname;
  7937. }
  7938. #endif
  7939. fixredir(redir, fn.list->text, 1);
  7940. }
  7941. break;
  7942. }
  7943. }
  7944. }
  7945. /*
  7946. * Evaluate a pipeline. All the processes in the pipeline are children
  7947. * of the process creating the pipeline. (This differs from some versions
  7948. * of the shell, which make the last process in a pipeline the parent
  7949. * of all the rest.)
  7950. */
  7951. static void
  7952. evalpipe(union node *n, int flags)
  7953. {
  7954. struct job *jp;
  7955. struct nodelist *lp;
  7956. int pipelen;
  7957. int prevfd;
  7958. int pip[2];
  7959. TRACE(("evalpipe(0x%lx) called\n", (long)n));
  7960. pipelen = 0;
  7961. for (lp = n->npipe.cmdlist; lp; lp = lp->next)
  7962. pipelen++;
  7963. flags |= EV_EXIT;
  7964. INT_OFF;
  7965. jp = makejob(/*n,*/ pipelen);
  7966. prevfd = -1;
  7967. for (lp = n->npipe.cmdlist; lp; lp = lp->next) {
  7968. prehash(lp->n);
  7969. pip[1] = -1;
  7970. if (lp->next) {
  7971. if (pipe(pip) < 0) {
  7972. close(prevfd);
  7973. ash_msg_and_raise_error("pipe call failed");
  7974. }
  7975. }
  7976. if (forkshell(jp, lp->n, n->npipe.pipe_backgnd) == 0) {
  7977. INT_ON;
  7978. if (pip[1] >= 0) {
  7979. close(pip[0]);
  7980. }
  7981. if (prevfd > 0) {
  7982. dup2(prevfd, 0);
  7983. close(prevfd);
  7984. }
  7985. if (pip[1] > 1) {
  7986. dup2(pip[1], 1);
  7987. close(pip[1]);
  7988. }
  7989. evaltreenr(lp->n, flags);
  7990. /* never returns */
  7991. }
  7992. if (prevfd >= 0)
  7993. close(prevfd);
  7994. prevfd = pip[0];
  7995. /* Don't want to trigger debugging */
  7996. if (pip[1] != -1)
  7997. close(pip[1]);
  7998. }
  7999. if (n->npipe.pipe_backgnd == 0) {
  8000. exitstatus = waitforjob(jp);
  8001. TRACE(("evalpipe: job done exit status %d\n", exitstatus));
  8002. }
  8003. INT_ON;
  8004. }
  8005. /*
  8006. * Controls whether the shell is interactive or not.
  8007. */
  8008. static void
  8009. setinteractive(int on)
  8010. {
  8011. static smallint is_interactive;
  8012. if (++on == is_interactive)
  8013. return;
  8014. is_interactive = on;
  8015. setsignal(SIGINT);
  8016. setsignal(SIGQUIT);
  8017. setsignal(SIGTERM);
  8018. #if !ENABLE_FEATURE_SH_EXTRA_QUIET
  8019. if (is_interactive > 1) {
  8020. /* Looks like they want an interactive shell */
  8021. static smallint did_banner;
  8022. if (!did_banner) {
  8023. /* note: ash and hush share this string */
  8024. out1fmt("\n\n%s %s\n"
  8025. "Enter 'help' for a list of built-in commands."
  8026. "\n\n",
  8027. bb_banner,
  8028. "built-in shell (ash)"
  8029. );
  8030. did_banner = 1;
  8031. }
  8032. }
  8033. #endif
  8034. }
  8035. static void
  8036. optschanged(void)
  8037. {
  8038. #if DEBUG
  8039. opentrace();
  8040. #endif
  8041. setinteractive(iflag);
  8042. setjobctl(mflag);
  8043. #if ENABLE_FEATURE_EDITING_VI
  8044. if (viflag)
  8045. line_input_state->flags |= VI_MODE;
  8046. else
  8047. line_input_state->flags &= ~VI_MODE;
  8048. #else
  8049. viflag = 0; /* forcibly keep the option off */
  8050. #endif
  8051. }
  8052. static struct localvar *localvars;
  8053. /*
  8054. * Called after a function returns.
  8055. * Interrupts must be off.
  8056. */
  8057. static void
  8058. poplocalvars(void)
  8059. {
  8060. struct localvar *lvp;
  8061. struct var *vp;
  8062. while ((lvp = localvars) != NULL) {
  8063. localvars = lvp->next;
  8064. vp = lvp->vp;
  8065. TRACE(("poplocalvar %s\n", vp ? vp->var_text : "-"));
  8066. if (vp == NULL) { /* $- saved */
  8067. memcpy(optlist, lvp->text, sizeof(optlist));
  8068. free((char*)lvp->text);
  8069. optschanged();
  8070. } else if ((lvp->flags & (VUNSET|VSTRFIXED)) == VUNSET) {
  8071. unsetvar(vp->var_text);
  8072. } else {
  8073. if (vp->var_func)
  8074. vp->var_func(var_end(lvp->text));
  8075. if ((vp->flags & (VTEXTFIXED|VSTACK)) == 0)
  8076. free((char*)vp->var_text);
  8077. vp->flags = lvp->flags;
  8078. vp->var_text = lvp->text;
  8079. }
  8080. free(lvp);
  8081. }
  8082. }
  8083. static int
  8084. evalfun(struct funcnode *func, int argc, char **argv, int flags)
  8085. {
  8086. volatile struct shparam saveparam;
  8087. struct localvar *volatile savelocalvars;
  8088. struct jmploc *volatile savehandler;
  8089. struct jmploc jmploc;
  8090. int e;
  8091. saveparam = shellparam;
  8092. savelocalvars = localvars;
  8093. e = setjmp(jmploc.loc);
  8094. if (e) {
  8095. goto funcdone;
  8096. }
  8097. INT_OFF;
  8098. savehandler = exception_handler;
  8099. exception_handler = &jmploc;
  8100. localvars = NULL;
  8101. shellparam.malloced = 0;
  8102. func->count++;
  8103. funcnest++;
  8104. INT_ON;
  8105. shellparam.nparam = argc - 1;
  8106. shellparam.p = argv + 1;
  8107. #if ENABLE_ASH_GETOPTS
  8108. shellparam.optind = 1;
  8109. shellparam.optoff = -1;
  8110. #endif
  8111. evaltree(&func->n, flags & EV_TESTED);
  8112. funcdone:
  8113. INT_OFF;
  8114. funcnest--;
  8115. freefunc(func);
  8116. poplocalvars();
  8117. localvars = savelocalvars;
  8118. freeparam(&shellparam);
  8119. shellparam = saveparam;
  8120. exception_handler = savehandler;
  8121. INT_ON;
  8122. evalskip &= ~SKIPFUNC;
  8123. return e;
  8124. }
  8125. #if ENABLE_ASH_CMDCMD
  8126. static char **
  8127. parse_command_args(char **argv, const char **path)
  8128. {
  8129. char *cp, c;
  8130. for (;;) {
  8131. cp = *++argv;
  8132. if (!cp)
  8133. return 0;
  8134. if (*cp++ != '-')
  8135. break;
  8136. c = *cp++;
  8137. if (!c)
  8138. break;
  8139. if (c == '-' && !*cp) {
  8140. argv++;
  8141. break;
  8142. }
  8143. do {
  8144. switch (c) {
  8145. case 'p':
  8146. *path = bb_default_path;
  8147. break;
  8148. default:
  8149. /* run 'typecmd' for other options */
  8150. return 0;
  8151. }
  8152. c = *cp++;
  8153. } while (c);
  8154. }
  8155. return argv;
  8156. }
  8157. #endif
  8158. /*
  8159. * Make a variable a local variable. When a variable is made local, it's
  8160. * value and flags are saved in a localvar structure. The saved values
  8161. * will be restored when the shell function returns. We handle the name
  8162. * "-" as a special case.
  8163. */
  8164. static void
  8165. mklocal(char *name)
  8166. {
  8167. struct localvar *lvp;
  8168. struct var **vpp;
  8169. struct var *vp;
  8170. INT_OFF;
  8171. lvp = ckzalloc(sizeof(struct localvar));
  8172. if (LONE_DASH(name)) {
  8173. char *p;
  8174. p = ckmalloc(sizeof(optlist));
  8175. lvp->text = memcpy(p, optlist, sizeof(optlist));
  8176. vp = NULL;
  8177. } else {
  8178. char *eq;
  8179. vpp = hashvar(name);
  8180. vp = *findvar(vpp, name);
  8181. eq = strchr(name, '=');
  8182. if (vp == NULL) {
  8183. if (eq)
  8184. setvareq(name, VSTRFIXED);
  8185. else
  8186. setvar(name, NULL, VSTRFIXED);
  8187. vp = *vpp; /* the new variable */
  8188. lvp->flags = VUNSET;
  8189. } else {
  8190. lvp->text = vp->var_text;
  8191. lvp->flags = vp->flags;
  8192. vp->flags |= VSTRFIXED|VTEXTFIXED;
  8193. if (eq)
  8194. setvareq(name, 0);
  8195. }
  8196. }
  8197. lvp->vp = vp;
  8198. lvp->next = localvars;
  8199. localvars = lvp;
  8200. INT_ON;
  8201. }
  8202. /*
  8203. * The "local" command.
  8204. */
  8205. static int FAST_FUNC
  8206. localcmd(int argc UNUSED_PARAM, char **argv)
  8207. {
  8208. char *name;
  8209. argv = argptr;
  8210. while ((name = *argv++) != NULL) {
  8211. mklocal(name);
  8212. }
  8213. return 0;
  8214. }
  8215. static int FAST_FUNC
  8216. falsecmd(int argc UNUSED_PARAM, char **argv UNUSED_PARAM)
  8217. {
  8218. return 1;
  8219. }
  8220. static int FAST_FUNC
  8221. truecmd(int argc UNUSED_PARAM, char **argv UNUSED_PARAM)
  8222. {
  8223. return 0;
  8224. }
  8225. static int FAST_FUNC
  8226. execcmd(int argc UNUSED_PARAM, char **argv)
  8227. {
  8228. if (argv[1]) {
  8229. iflag = 0; /* exit on error */
  8230. mflag = 0;
  8231. optschanged();
  8232. shellexec(argv + 1, pathval(), 0);
  8233. }
  8234. return 0;
  8235. }
  8236. /*
  8237. * The return command.
  8238. */
  8239. static int FAST_FUNC
  8240. returncmd(int argc UNUSED_PARAM, char **argv)
  8241. {
  8242. /*
  8243. * If called outside a function, do what ksh does;
  8244. * skip the rest of the file.
  8245. */
  8246. evalskip = funcnest ? SKIPFUNC : SKIPFILE;
  8247. return argv[1] ? number(argv[1]) : exitstatus;
  8248. }
  8249. /* Forward declarations for builtintab[] */
  8250. static int breakcmd(int, char **) FAST_FUNC;
  8251. static int dotcmd(int, char **) FAST_FUNC;
  8252. static int evalcmd(int, char **) FAST_FUNC;
  8253. static int exitcmd(int, char **) FAST_FUNC;
  8254. static int exportcmd(int, char **) FAST_FUNC;
  8255. #if ENABLE_ASH_GETOPTS
  8256. static int getoptscmd(int, char **) FAST_FUNC;
  8257. #endif
  8258. #if !ENABLE_FEATURE_SH_EXTRA_QUIET
  8259. static int helpcmd(int, char **) FAST_FUNC;
  8260. #endif
  8261. #if MAX_HISTORY
  8262. static int historycmd(int, char **) FAST_FUNC;
  8263. #endif
  8264. #if ENABLE_SH_MATH_SUPPORT
  8265. static int letcmd(int, char **) FAST_FUNC;
  8266. #endif
  8267. static int readcmd(int, char **) FAST_FUNC;
  8268. static int setcmd(int, char **) FAST_FUNC;
  8269. static int shiftcmd(int, char **) FAST_FUNC;
  8270. static int timescmd(int, char **) FAST_FUNC;
  8271. static int trapcmd(int, char **) FAST_FUNC;
  8272. static int umaskcmd(int, char **) FAST_FUNC;
  8273. static int unsetcmd(int, char **) FAST_FUNC;
  8274. static int ulimitcmd(int, char **) FAST_FUNC;
  8275. #define BUILTIN_NOSPEC "0"
  8276. #define BUILTIN_SPECIAL "1"
  8277. #define BUILTIN_REGULAR "2"
  8278. #define BUILTIN_SPEC_REG "3"
  8279. #define BUILTIN_ASSIGN "4"
  8280. #define BUILTIN_SPEC_ASSG "5"
  8281. #define BUILTIN_REG_ASSG "6"
  8282. #define BUILTIN_SPEC_REG_ASSG "7"
  8283. /* Stubs for calling non-FAST_FUNC's */
  8284. #if ENABLE_ASH_BUILTIN_ECHO
  8285. static int FAST_FUNC echocmd(int argc, char **argv) { return echo_main(argc, argv); }
  8286. #endif
  8287. #if ENABLE_ASH_BUILTIN_PRINTF
  8288. static int FAST_FUNC printfcmd(int argc, char **argv) { return printf_main(argc, argv); }
  8289. #endif
  8290. #if ENABLE_ASH_BUILTIN_TEST
  8291. static int FAST_FUNC testcmd(int argc, char **argv) { return test_main(argc, argv); }
  8292. #endif
  8293. /* Keep these in proper order since it is searched via bsearch() */
  8294. static const struct builtincmd builtintab[] = {
  8295. { BUILTIN_SPEC_REG "." , dotcmd },
  8296. { BUILTIN_SPEC_REG ":" , truecmd },
  8297. #if ENABLE_ASH_BUILTIN_TEST
  8298. { BUILTIN_REGULAR "[" , testcmd },
  8299. #if ENABLE_ASH_BASH_COMPAT
  8300. { BUILTIN_REGULAR "[[" , testcmd },
  8301. #endif
  8302. #endif
  8303. #if ENABLE_ASH_ALIAS
  8304. { BUILTIN_REG_ASSG "alias" , aliascmd },
  8305. #endif
  8306. #if JOBS
  8307. { BUILTIN_REGULAR "bg" , fg_bgcmd },
  8308. #endif
  8309. { BUILTIN_SPEC_REG "break" , breakcmd },
  8310. { BUILTIN_REGULAR "cd" , cdcmd },
  8311. { BUILTIN_NOSPEC "chdir" , cdcmd },
  8312. #if ENABLE_ASH_CMDCMD
  8313. { BUILTIN_REGULAR "command" , commandcmd },
  8314. #endif
  8315. { BUILTIN_SPEC_REG "continue", breakcmd },
  8316. #if ENABLE_ASH_BUILTIN_ECHO
  8317. { BUILTIN_REGULAR "echo" , echocmd },
  8318. #endif
  8319. { BUILTIN_SPEC_REG "eval" , evalcmd },
  8320. { BUILTIN_SPEC_REG "exec" , execcmd },
  8321. { BUILTIN_SPEC_REG "exit" , exitcmd },
  8322. { BUILTIN_SPEC_REG_ASSG "export" , exportcmd },
  8323. { BUILTIN_REGULAR "false" , falsecmd },
  8324. #if JOBS
  8325. { BUILTIN_REGULAR "fg" , fg_bgcmd },
  8326. #endif
  8327. #if ENABLE_ASH_GETOPTS
  8328. { BUILTIN_REGULAR "getopts" , getoptscmd },
  8329. #endif
  8330. { BUILTIN_NOSPEC "hash" , hashcmd },
  8331. #if !ENABLE_FEATURE_SH_EXTRA_QUIET
  8332. { BUILTIN_NOSPEC "help" , helpcmd },
  8333. #endif
  8334. #if MAX_HISTORY
  8335. { BUILTIN_NOSPEC "history" , historycmd },
  8336. #endif
  8337. #if JOBS
  8338. { BUILTIN_REGULAR "jobs" , jobscmd },
  8339. { BUILTIN_REGULAR "kill" , killcmd },
  8340. #endif
  8341. #if ENABLE_SH_MATH_SUPPORT
  8342. { BUILTIN_NOSPEC "let" , letcmd },
  8343. #endif
  8344. { BUILTIN_ASSIGN "local" , localcmd },
  8345. #if ENABLE_ASH_BUILTIN_PRINTF
  8346. { BUILTIN_REGULAR "printf" , printfcmd },
  8347. #endif
  8348. { BUILTIN_NOSPEC "pwd" , pwdcmd },
  8349. { BUILTIN_REGULAR "read" , readcmd },
  8350. { BUILTIN_SPEC_REG_ASSG "readonly", exportcmd },
  8351. { BUILTIN_SPEC_REG "return" , returncmd },
  8352. { BUILTIN_SPEC_REG "set" , setcmd },
  8353. { BUILTIN_SPEC_REG "shift" , shiftcmd },
  8354. #if ENABLE_ASH_BASH_COMPAT
  8355. { BUILTIN_SPEC_REG "source" , dotcmd },
  8356. #endif
  8357. #if ENABLE_ASH_BUILTIN_TEST
  8358. { BUILTIN_REGULAR "test" , testcmd },
  8359. #endif
  8360. { BUILTIN_SPEC_REG "times" , timescmd },
  8361. { BUILTIN_SPEC_REG "trap" , trapcmd },
  8362. { BUILTIN_REGULAR "true" , truecmd },
  8363. { BUILTIN_NOSPEC "type" , typecmd },
  8364. { BUILTIN_NOSPEC "ulimit" , ulimitcmd },
  8365. { BUILTIN_REGULAR "umask" , umaskcmd },
  8366. #if ENABLE_ASH_ALIAS
  8367. { BUILTIN_REGULAR "unalias" , unaliascmd },
  8368. #endif
  8369. { BUILTIN_SPEC_REG "unset" , unsetcmd },
  8370. { BUILTIN_REGULAR "wait" , waitcmd },
  8371. };
  8372. /* Should match the above table! */
  8373. #define COMMANDCMD (builtintab + \
  8374. 2 + \
  8375. 1 * ENABLE_ASH_BUILTIN_TEST + \
  8376. 1 * ENABLE_ASH_BUILTIN_TEST * ENABLE_ASH_BASH_COMPAT + \
  8377. 1 * ENABLE_ASH_ALIAS + \
  8378. 1 * ENABLE_ASH_JOB_CONTROL + \
  8379. 3)
  8380. #define EXECCMD (builtintab + \
  8381. 2 + \
  8382. 1 * ENABLE_ASH_BUILTIN_TEST + \
  8383. 1 * ENABLE_ASH_BUILTIN_TEST * ENABLE_ASH_BASH_COMPAT + \
  8384. 1 * ENABLE_ASH_ALIAS + \
  8385. 1 * ENABLE_ASH_JOB_CONTROL + \
  8386. 3 + \
  8387. 1 * ENABLE_ASH_CMDCMD + \
  8388. 1 + \
  8389. ENABLE_ASH_BUILTIN_ECHO + \
  8390. 1)
  8391. /*
  8392. * Search the table of builtin commands.
  8393. */
  8394. static struct builtincmd *
  8395. find_builtin(const char *name)
  8396. {
  8397. struct builtincmd *bp;
  8398. bp = bsearch(
  8399. name, builtintab, ARRAY_SIZE(builtintab), sizeof(builtintab[0]),
  8400. pstrcmp
  8401. );
  8402. return bp;
  8403. }
  8404. /*
  8405. * Execute a simple command.
  8406. */
  8407. static int
  8408. isassignment(const char *p)
  8409. {
  8410. const char *q = endofname(p);
  8411. if (p == q)
  8412. return 0;
  8413. return *q == '=';
  8414. }
  8415. static int FAST_FUNC
  8416. bltincmd(int argc UNUSED_PARAM, char **argv UNUSED_PARAM)
  8417. {
  8418. /* Preserve exitstatus of a previous possible redirection
  8419. * as POSIX mandates */
  8420. return back_exitstatus;
  8421. }
  8422. static void
  8423. evalcommand(union node *cmd, int flags)
  8424. {
  8425. static const struct builtincmd null_bltin = {
  8426. "\0\0", bltincmd /* why three NULs? */
  8427. };
  8428. struct stackmark smark;
  8429. union node *argp;
  8430. struct arglist arglist;
  8431. struct arglist varlist;
  8432. char **argv;
  8433. int argc;
  8434. const struct strlist *sp;
  8435. struct cmdentry cmdentry;
  8436. struct job *jp;
  8437. char *lastarg;
  8438. const char *path;
  8439. int spclbltin;
  8440. int status;
  8441. char **nargv;
  8442. struct builtincmd *bcmd;
  8443. smallint cmd_is_exec;
  8444. smallint pseudovarflag = 0;
  8445. /* First expand the arguments. */
  8446. TRACE(("evalcommand(0x%lx, %d) called\n", (long)cmd, flags));
  8447. setstackmark(&smark);
  8448. back_exitstatus = 0;
  8449. cmdentry.cmdtype = CMDBUILTIN;
  8450. cmdentry.u.cmd = &null_bltin;
  8451. varlist.lastp = &varlist.list;
  8452. *varlist.lastp = NULL;
  8453. arglist.lastp = &arglist.list;
  8454. *arglist.lastp = NULL;
  8455. argc = 0;
  8456. if (cmd->ncmd.args) {
  8457. bcmd = find_builtin(cmd->ncmd.args->narg.text);
  8458. pseudovarflag = bcmd && IS_BUILTIN_ASSIGN(bcmd);
  8459. }
  8460. for (argp = cmd->ncmd.args; argp; argp = argp->narg.next) {
  8461. struct strlist **spp;
  8462. spp = arglist.lastp;
  8463. if (pseudovarflag && isassignment(argp->narg.text))
  8464. expandarg(argp, &arglist, EXP_VARTILDE);
  8465. else
  8466. expandarg(argp, &arglist, EXP_FULL | EXP_TILDE);
  8467. for (sp = *spp; sp; sp = sp->next)
  8468. argc++;
  8469. }
  8470. argv = nargv = stalloc(sizeof(char *) * (argc + 1));
  8471. for (sp = arglist.list; sp; sp = sp->next) {
  8472. TRACE(("evalcommand arg: %s\n", sp->text));
  8473. *nargv++ = sp->text;
  8474. }
  8475. *nargv = NULL;
  8476. lastarg = NULL;
  8477. if (iflag && funcnest == 0 && argc > 0)
  8478. lastarg = nargv[-1];
  8479. preverrout_fd = 2;
  8480. expredir(cmd->ncmd.redirect);
  8481. status = redirectsafe(cmd->ncmd.redirect, REDIR_PUSH | REDIR_SAVEFD2);
  8482. path = vpath.var_text;
  8483. for (argp = cmd->ncmd.assign; argp; argp = argp->narg.next) {
  8484. struct strlist **spp;
  8485. char *p;
  8486. spp = varlist.lastp;
  8487. expandarg(argp, &varlist, EXP_VARTILDE);
  8488. /*
  8489. * Modify the command lookup path, if a PATH= assignment
  8490. * is present
  8491. */
  8492. p = (*spp)->text;
  8493. if (varcmp(p, path) == 0)
  8494. path = p;
  8495. }
  8496. /* Print the command if xflag is set. */
  8497. if (xflag) {
  8498. int n;
  8499. const char *p = " %s" + 1;
  8500. fdprintf(preverrout_fd, p, expandstr(ps4val()));
  8501. sp = varlist.list;
  8502. for (n = 0; n < 2; n++) {
  8503. while (sp) {
  8504. fdprintf(preverrout_fd, p, sp->text);
  8505. sp = sp->next;
  8506. p = " %s";
  8507. }
  8508. sp = arglist.list;
  8509. }
  8510. safe_write(preverrout_fd, "\n", 1);
  8511. }
  8512. cmd_is_exec = 0;
  8513. spclbltin = -1;
  8514. /* Now locate the command. */
  8515. if (argc) {
  8516. int cmd_flag = DO_ERR;
  8517. #if ENABLE_ASH_CMDCMD
  8518. const char *oldpath = path + 5;
  8519. #endif
  8520. path += 5;
  8521. for (;;) {
  8522. find_command(argv[0], &cmdentry, cmd_flag, path);
  8523. if (cmdentry.cmdtype == CMDUNKNOWN) {
  8524. flush_stdout_stderr();
  8525. status = 127;
  8526. goto bail;
  8527. }
  8528. /* implement bltin and command here */
  8529. if (cmdentry.cmdtype != CMDBUILTIN)
  8530. break;
  8531. if (spclbltin < 0)
  8532. spclbltin = IS_BUILTIN_SPECIAL(cmdentry.u.cmd);
  8533. if (cmdentry.u.cmd == EXECCMD)
  8534. cmd_is_exec = 1;
  8535. #if ENABLE_ASH_CMDCMD
  8536. if (cmdentry.u.cmd == COMMANDCMD) {
  8537. path = oldpath;
  8538. nargv = parse_command_args(argv, &path);
  8539. if (!nargv)
  8540. break;
  8541. argc -= nargv - argv;
  8542. argv = nargv;
  8543. cmd_flag |= DO_NOFUNC;
  8544. } else
  8545. #endif
  8546. break;
  8547. }
  8548. }
  8549. if (status) {
  8550. /* We have a redirection error. */
  8551. if (spclbltin > 0)
  8552. raise_exception(EXERROR);
  8553. bail:
  8554. exitstatus = status;
  8555. goto out;
  8556. }
  8557. /* Execute the command. */
  8558. switch (cmdentry.cmdtype) {
  8559. default: {
  8560. #if ENABLE_FEATURE_SH_NOFORK
  8561. /* (1) BUG: if variables are set, we need to fork, or save/restore them
  8562. * around run_nofork_applet() call.
  8563. * (2) Should this check also be done in forkshell()?
  8564. * (perhaps it should, so that "VAR=VAL nofork" at least avoids exec...)
  8565. */
  8566. /* find_command() encodes applet_no as (-2 - applet_no) */
  8567. int applet_no = (- cmdentry.u.index - 2);
  8568. if (applet_no >= 0 && APPLET_IS_NOFORK(applet_no)) {
  8569. listsetvar(varlist.list, VEXPORT|VSTACK);
  8570. /* run <applet>_main() */
  8571. exitstatus = run_nofork_applet(applet_no, argv);
  8572. break;
  8573. }
  8574. #endif
  8575. /* Can we avoid forking off? For example, very last command
  8576. * in a script or a subshell does not need forking,
  8577. * we can just exec it.
  8578. */
  8579. if (!(flags & EV_EXIT) || may_have_traps) {
  8580. /* No, forking off a child is necessary */
  8581. INT_OFF;
  8582. jp = makejob(/*cmd,*/ 1);
  8583. if (forkshell(jp, cmd, FORK_FG) != 0) {
  8584. /* parent */
  8585. exitstatus = waitforjob(jp);
  8586. INT_ON;
  8587. TRACE(("forked child exited with %d\n", exitstatus));
  8588. break;
  8589. }
  8590. /* child */
  8591. FORCE_INT_ON;
  8592. /* fall through to exec'ing external program */
  8593. }
  8594. listsetvar(varlist.list, VEXPORT|VSTACK);
  8595. shellexec(argv, path, cmdentry.u.index);
  8596. /* NOTREACHED */
  8597. } /* default */
  8598. case CMDBUILTIN:
  8599. cmdenviron = varlist.list;
  8600. if (cmdenviron) {
  8601. struct strlist *list = cmdenviron;
  8602. int i = VNOSET;
  8603. if (spclbltin > 0 || argc == 0) {
  8604. i = 0;
  8605. if (cmd_is_exec && argc > 1)
  8606. i = VEXPORT;
  8607. }
  8608. listsetvar(list, i);
  8609. }
  8610. /* Tight loop with builtins only:
  8611. * "while kill -0 $child; do true; done"
  8612. * will never exit even if $child died, unless we do this
  8613. * to reap the zombie and make kill detect that it's gone: */
  8614. dowait(DOWAIT_NONBLOCK, NULL);
  8615. if (evalbltin(cmdentry.u.cmd, argc, argv)) {
  8616. int exit_status;
  8617. int i = exception_type;
  8618. if (i == EXEXIT)
  8619. goto raise;
  8620. exit_status = 2;
  8621. if (i == EXINT)
  8622. exit_status = 128 + SIGINT;
  8623. if (i == EXSIG)
  8624. exit_status = 128 + pending_sig;
  8625. exitstatus = exit_status;
  8626. if (i == EXINT || spclbltin > 0) {
  8627. raise:
  8628. longjmp(exception_handler->loc, 1);
  8629. }
  8630. FORCE_INT_ON;
  8631. }
  8632. break;
  8633. case CMDFUNCTION:
  8634. listsetvar(varlist.list, 0);
  8635. /* See above for the rationale */
  8636. dowait(DOWAIT_NONBLOCK, NULL);
  8637. if (evalfun(cmdentry.u.func, argc, argv, flags))
  8638. goto raise;
  8639. break;
  8640. } /* switch */
  8641. out:
  8642. popredir(/*drop:*/ cmd_is_exec, /*restore:*/ cmd_is_exec);
  8643. if (lastarg) {
  8644. /* dsl: I think this is intended to be used to support
  8645. * '_' in 'vi' command mode during line editing...
  8646. * However I implemented that within libedit itself.
  8647. */
  8648. setvar2("_", lastarg);
  8649. }
  8650. popstackmark(&smark);
  8651. }
  8652. static int
  8653. evalbltin(const struct builtincmd *cmd, int argc, char **argv)
  8654. {
  8655. char *volatile savecmdname;
  8656. struct jmploc *volatile savehandler;
  8657. struct jmploc jmploc;
  8658. int i;
  8659. savecmdname = commandname;
  8660. i = setjmp(jmploc.loc);
  8661. if (i)
  8662. goto cmddone;
  8663. savehandler = exception_handler;
  8664. exception_handler = &jmploc;
  8665. commandname = argv[0];
  8666. argptr = argv + 1;
  8667. optptr = NULL; /* initialize nextopt */
  8668. exitstatus = (*cmd->builtin)(argc, argv);
  8669. flush_stdout_stderr();
  8670. cmddone:
  8671. exitstatus |= ferror(stdout);
  8672. clearerr(stdout);
  8673. commandname = savecmdname;
  8674. exception_handler = savehandler;
  8675. return i;
  8676. }
  8677. static int
  8678. goodname(const char *p)
  8679. {
  8680. return endofname(p)[0] == '\0';
  8681. }
  8682. /*
  8683. * Search for a command. This is called before we fork so that the
  8684. * location of the command will be available in the parent as well as
  8685. * the child. The check for "goodname" is an overly conservative
  8686. * check that the name will not be subject to expansion.
  8687. */
  8688. static void
  8689. prehash(union node *n)
  8690. {
  8691. struct cmdentry entry;
  8692. if (n->type == NCMD && n->ncmd.args && goodname(n->ncmd.args->narg.text))
  8693. find_command(n->ncmd.args->narg.text, &entry, 0, pathval());
  8694. }
  8695. /* ============ Builtin commands
  8696. *
  8697. * Builtin commands whose functions are closely tied to evaluation
  8698. * are implemented here.
  8699. */
  8700. /*
  8701. * Handle break and continue commands. Break, continue, and return are
  8702. * all handled by setting the evalskip flag. The evaluation routines
  8703. * above all check this flag, and if it is set they start skipping
  8704. * commands rather than executing them. The variable skipcount is
  8705. * the number of loops to break/continue, or the number of function
  8706. * levels to return. (The latter is always 1.) It should probably
  8707. * be an error to break out of more loops than exist, but it isn't
  8708. * in the standard shell so we don't make it one here.
  8709. */
  8710. static int FAST_FUNC
  8711. breakcmd(int argc UNUSED_PARAM, char **argv)
  8712. {
  8713. int n = argv[1] ? number(argv[1]) : 1;
  8714. if (n <= 0)
  8715. ash_msg_and_raise_error(msg_illnum, argv[1]);
  8716. if (n > loopnest)
  8717. n = loopnest;
  8718. if (n > 0) {
  8719. evalskip = (**argv == 'c') ? SKIPCONT : SKIPBREAK;
  8720. skipcount = n;
  8721. }
  8722. return 0;
  8723. }
  8724. /* ============ input.c
  8725. *
  8726. * This implements the input routines used by the parser.
  8727. */
  8728. enum {
  8729. INPUT_PUSH_FILE = 1,
  8730. INPUT_NOFILE_OK = 2,
  8731. };
  8732. static smallint checkkwd;
  8733. /* values of checkkwd variable */
  8734. #define CHKALIAS 0x1
  8735. #define CHKKWD 0x2
  8736. #define CHKNL 0x4
  8737. /*
  8738. * Push a string back onto the input at this current parsefile level.
  8739. * We handle aliases this way.
  8740. */
  8741. #if !ENABLE_ASH_ALIAS
  8742. #define pushstring(s, ap) pushstring(s)
  8743. #endif
  8744. static void
  8745. pushstring(char *s, struct alias *ap)
  8746. {
  8747. struct strpush *sp;
  8748. int len;
  8749. len = strlen(s);
  8750. INT_OFF;
  8751. if (g_parsefile->strpush) {
  8752. sp = ckzalloc(sizeof(*sp));
  8753. sp->prev = g_parsefile->strpush;
  8754. } else {
  8755. sp = &(g_parsefile->basestrpush);
  8756. }
  8757. g_parsefile->strpush = sp;
  8758. sp->prev_string = g_parsefile->next_to_pgetc;
  8759. sp->prev_left_in_line = g_parsefile->left_in_line;
  8760. #if ENABLE_ASH_ALIAS
  8761. sp->ap = ap;
  8762. if (ap) {
  8763. ap->flag |= ALIASINUSE;
  8764. sp->string = s;
  8765. }
  8766. #endif
  8767. g_parsefile->next_to_pgetc = s;
  8768. g_parsefile->left_in_line = len;
  8769. INT_ON;
  8770. }
  8771. static void
  8772. popstring(void)
  8773. {
  8774. struct strpush *sp = g_parsefile->strpush;
  8775. INT_OFF;
  8776. #if ENABLE_ASH_ALIAS
  8777. if (sp->ap) {
  8778. if (g_parsefile->next_to_pgetc[-1] == ' '
  8779. || g_parsefile->next_to_pgetc[-1] == '\t'
  8780. ) {
  8781. checkkwd |= CHKALIAS;
  8782. }
  8783. if (sp->string != sp->ap->val) {
  8784. free(sp->string);
  8785. }
  8786. sp->ap->flag &= ~ALIASINUSE;
  8787. if (sp->ap->flag & ALIASDEAD) {
  8788. unalias(sp->ap->name);
  8789. }
  8790. }
  8791. #endif
  8792. g_parsefile->next_to_pgetc = sp->prev_string;
  8793. g_parsefile->left_in_line = sp->prev_left_in_line;
  8794. g_parsefile->strpush = sp->prev;
  8795. if (sp != &(g_parsefile->basestrpush))
  8796. free(sp);
  8797. INT_ON;
  8798. }
  8799. //FIXME: BASH_COMPAT with "...&" does TWO pungetc():
  8800. //it peeks whether it is &>, and then pushes back both chars.
  8801. //This function needs to save last *next_to_pgetc to buf[0]
  8802. //to make two pungetc() reliable. Currently,
  8803. // pgetc (out of buf: does preadfd), pgetc, pungetc, pungetc won't work...
  8804. static int
  8805. preadfd(void)
  8806. {
  8807. int nr;
  8808. char *buf = g_parsefile->buf;
  8809. g_parsefile->next_to_pgetc = buf;
  8810. #if ENABLE_FEATURE_EDITING
  8811. retry:
  8812. if (!iflag || g_parsefile->pf_fd != STDIN_FILENO)
  8813. nr = nonblock_immune_read(g_parsefile->pf_fd, buf, IBUFSIZ - 1, /*loop_on_EINTR:*/ 1);
  8814. else {
  8815. int timeout = -1;
  8816. # if ENABLE_ASH_IDLE_TIMEOUT
  8817. if (iflag) {
  8818. const char *tmout_var = lookupvar("TMOUT");
  8819. if (tmout_var) {
  8820. timeout = atoi(tmout_var) * 1000;
  8821. if (timeout <= 0)
  8822. timeout = -1;
  8823. }
  8824. }
  8825. # endif
  8826. # if ENABLE_FEATURE_TAB_COMPLETION
  8827. line_input_state->path_lookup = pathval();
  8828. # endif
  8829. /* Unicode support should be activated even if LANG is set
  8830. * _during_ shell execution, not only if it was set when
  8831. * shell was started. Therefore, re-check LANG every time:
  8832. */
  8833. {
  8834. const char *s = lookupvar("LC_ALL");
  8835. if (!s) s = lookupvar("LC_CTYPE");
  8836. if (!s) s = lookupvar("LANG");
  8837. reinit_unicode(s);
  8838. }
  8839. nr = read_line_input(line_input_state, cmdedit_prompt, buf, IBUFSIZ, timeout);
  8840. if (nr == 0) {
  8841. /* Ctrl+C pressed */
  8842. if (trap[SIGINT]) {
  8843. buf[0] = '\n';
  8844. buf[1] = '\0';
  8845. raise(SIGINT);
  8846. return 1;
  8847. }
  8848. goto retry;
  8849. }
  8850. if (nr < 0) {
  8851. if (errno == 0) {
  8852. /* Ctrl+D pressed */
  8853. nr = 0;
  8854. }
  8855. # if ENABLE_ASH_IDLE_TIMEOUT
  8856. else if (errno == EAGAIN && timeout > 0) {
  8857. printf("\007timed out waiting for input: auto-logout\n");
  8858. exitshell();
  8859. }
  8860. # endif
  8861. }
  8862. }
  8863. #else
  8864. nr = nonblock_immune_read(g_parsefile->pf_fd, buf, IBUFSIZ - 1, /*loop_on_EINTR:*/ 1);
  8865. #endif
  8866. #if 0 /* disabled: nonblock_immune_read() handles this problem */
  8867. if (nr < 0) {
  8868. if (parsefile->fd == 0 && errno == EWOULDBLOCK) {
  8869. int flags = fcntl(0, F_GETFL);
  8870. if (flags >= 0 && (flags & O_NONBLOCK)) {
  8871. flags &= ~O_NONBLOCK;
  8872. if (fcntl(0, F_SETFL, flags) >= 0) {
  8873. out2str("sh: turning off NDELAY mode\n");
  8874. goto retry;
  8875. }
  8876. }
  8877. }
  8878. }
  8879. #endif
  8880. return nr;
  8881. }
  8882. /*
  8883. * Refill the input buffer and return the next input character:
  8884. *
  8885. * 1) If a string was pushed back on the input, pop it;
  8886. * 2) If an EOF was pushed back (g_parsefile->left_in_line < -BIGNUM)
  8887. * or we are reading from a string so we can't refill the buffer,
  8888. * return EOF.
  8889. * 3) If there is more stuff in this buffer, use it else call read to fill it.
  8890. * 4) Process input up to the next newline, deleting nul characters.
  8891. */
  8892. //#define pgetc_debug(...) bb_error_msg(__VA_ARGS__)
  8893. #define pgetc_debug(...) ((void)0)
  8894. static int
  8895. preadbuffer(void)
  8896. {
  8897. char *q;
  8898. int more;
  8899. while (g_parsefile->strpush) {
  8900. #if ENABLE_ASH_ALIAS
  8901. if (g_parsefile->left_in_line == -1
  8902. && g_parsefile->strpush->ap
  8903. && g_parsefile->next_to_pgetc[-1] != ' '
  8904. && g_parsefile->next_to_pgetc[-1] != '\t'
  8905. ) {
  8906. pgetc_debug("preadbuffer PEOA");
  8907. return PEOA;
  8908. }
  8909. #endif
  8910. popstring();
  8911. /* try "pgetc" now: */
  8912. pgetc_debug("preadbuffer internal pgetc at %d:%p'%s'",
  8913. g_parsefile->left_in_line,
  8914. g_parsefile->next_to_pgetc,
  8915. g_parsefile->next_to_pgetc);
  8916. if (--g_parsefile->left_in_line >= 0)
  8917. return (unsigned char)(*g_parsefile->next_to_pgetc++);
  8918. }
  8919. /* on both branches above g_parsefile->left_in_line < 0.
  8920. * "pgetc" needs refilling.
  8921. */
  8922. /* -90 is our -BIGNUM. Below we use -99 to mark "EOF on read",
  8923. * pungetc() may increment it a few times.
  8924. * Assuming it won't increment it to less than -90.
  8925. */
  8926. if (g_parsefile->left_in_line < -90 || g_parsefile->buf == NULL) {
  8927. pgetc_debug("preadbuffer PEOF1");
  8928. /* even in failure keep left_in_line and next_to_pgetc
  8929. * in lock step, for correct multi-layer pungetc.
  8930. * left_in_line was decremented before preadbuffer(),
  8931. * must inc next_to_pgetc: */
  8932. g_parsefile->next_to_pgetc++;
  8933. return PEOF;
  8934. }
  8935. more = g_parsefile->left_in_buffer;
  8936. if (more <= 0) {
  8937. flush_stdout_stderr();
  8938. again:
  8939. more = preadfd();
  8940. if (more <= 0) {
  8941. /* don't try reading again */
  8942. g_parsefile->left_in_line = -99;
  8943. pgetc_debug("preadbuffer PEOF2");
  8944. g_parsefile->next_to_pgetc++;
  8945. return PEOF;
  8946. }
  8947. }
  8948. /* Find out where's the end of line.
  8949. * Set g_parsefile->left_in_line
  8950. * and g_parsefile->left_in_buffer acordingly.
  8951. * NUL chars are deleted.
  8952. */
  8953. q = g_parsefile->next_to_pgetc;
  8954. for (;;) {
  8955. char c;
  8956. more--;
  8957. c = *q;
  8958. if (c == '\0') {
  8959. memmove(q, q + 1, more);
  8960. } else {
  8961. q++;
  8962. if (c == '\n') {
  8963. g_parsefile->left_in_line = q - g_parsefile->next_to_pgetc - 1;
  8964. break;
  8965. }
  8966. }
  8967. if (more <= 0) {
  8968. g_parsefile->left_in_line = q - g_parsefile->next_to_pgetc - 1;
  8969. if (g_parsefile->left_in_line < 0)
  8970. goto again;
  8971. break;
  8972. }
  8973. }
  8974. g_parsefile->left_in_buffer = more;
  8975. if (vflag) {
  8976. char save = *q;
  8977. *q = '\0';
  8978. out2str(g_parsefile->next_to_pgetc);
  8979. *q = save;
  8980. }
  8981. pgetc_debug("preadbuffer at %d:%p'%s'",
  8982. g_parsefile->left_in_line,
  8983. g_parsefile->next_to_pgetc,
  8984. g_parsefile->next_to_pgetc);
  8985. return (unsigned char)*g_parsefile->next_to_pgetc++;
  8986. }
  8987. #define pgetc_as_macro() \
  8988. (--g_parsefile->left_in_line >= 0 \
  8989. ? (unsigned char)*g_parsefile->next_to_pgetc++ \
  8990. : preadbuffer() \
  8991. )
  8992. static int
  8993. pgetc(void)
  8994. {
  8995. pgetc_debug("pgetc_fast at %d:%p'%s'",
  8996. g_parsefile->left_in_line,
  8997. g_parsefile->next_to_pgetc,
  8998. g_parsefile->next_to_pgetc);
  8999. return pgetc_as_macro();
  9000. }
  9001. #if ENABLE_ASH_OPTIMIZE_FOR_SIZE
  9002. # define pgetc_fast() pgetc()
  9003. #else
  9004. # define pgetc_fast() pgetc_as_macro()
  9005. #endif
  9006. #if ENABLE_ASH_ALIAS
  9007. static int
  9008. pgetc_without_PEOA(void)
  9009. {
  9010. int c;
  9011. do {
  9012. pgetc_debug("pgetc_fast at %d:%p'%s'",
  9013. g_parsefile->left_in_line,
  9014. g_parsefile->next_to_pgetc,
  9015. g_parsefile->next_to_pgetc);
  9016. c = pgetc_fast();
  9017. } while (c == PEOA);
  9018. return c;
  9019. }
  9020. #else
  9021. # define pgetc_without_PEOA() pgetc()
  9022. #endif
  9023. /*
  9024. * Read a line from the script.
  9025. */
  9026. static char *
  9027. pfgets(char *line, int len)
  9028. {
  9029. char *p = line;
  9030. int nleft = len;
  9031. int c;
  9032. while (--nleft > 0) {
  9033. c = pgetc_without_PEOA();
  9034. if (c == PEOF) {
  9035. if (p == line)
  9036. return NULL;
  9037. break;
  9038. }
  9039. *p++ = c;
  9040. if (c == '\n')
  9041. break;
  9042. }
  9043. *p = '\0';
  9044. return line;
  9045. }
  9046. /*
  9047. * Undo the last call to pgetc. Only one character may be pushed back.
  9048. * PEOF may be pushed back.
  9049. */
  9050. static void
  9051. pungetc(void)
  9052. {
  9053. g_parsefile->left_in_line++;
  9054. g_parsefile->next_to_pgetc--;
  9055. pgetc_debug("pushed back to %d:%p'%s'",
  9056. g_parsefile->left_in_line,
  9057. g_parsefile->next_to_pgetc,
  9058. g_parsefile->next_to_pgetc);
  9059. }
  9060. /*
  9061. * To handle the "." command, a stack of input files is used. Pushfile
  9062. * adds a new entry to the stack and popfile restores the previous level.
  9063. */
  9064. static void
  9065. pushfile(void)
  9066. {
  9067. struct parsefile *pf;
  9068. pf = ckzalloc(sizeof(*pf));
  9069. pf->prev = g_parsefile;
  9070. pf->pf_fd = -1;
  9071. /*pf->strpush = NULL; - ckzalloc did it */
  9072. /*pf->basestrpush.prev = NULL;*/
  9073. g_parsefile = pf;
  9074. }
  9075. static void
  9076. popfile(void)
  9077. {
  9078. struct parsefile *pf = g_parsefile;
  9079. INT_OFF;
  9080. if (pf->pf_fd >= 0)
  9081. close(pf->pf_fd);
  9082. free(pf->buf);
  9083. while (pf->strpush)
  9084. popstring();
  9085. g_parsefile = pf->prev;
  9086. free(pf);
  9087. INT_ON;
  9088. }
  9089. /*
  9090. * Return to top level.
  9091. */
  9092. static void
  9093. popallfiles(void)
  9094. {
  9095. while (g_parsefile != &basepf)
  9096. popfile();
  9097. }
  9098. /*
  9099. * Close the file(s) that the shell is reading commands from. Called
  9100. * after a fork is done.
  9101. */
  9102. static void
  9103. closescript(void)
  9104. {
  9105. popallfiles();
  9106. if (g_parsefile->pf_fd > 0) {
  9107. close(g_parsefile->pf_fd);
  9108. g_parsefile->pf_fd = 0;
  9109. }
  9110. }
  9111. /*
  9112. * Like setinputfile, but takes an open file descriptor. Call this with
  9113. * interrupts off.
  9114. */
  9115. static void
  9116. setinputfd(int fd, int push)
  9117. {
  9118. close_on_exec_on(fd);
  9119. if (push) {
  9120. pushfile();
  9121. g_parsefile->buf = NULL;
  9122. }
  9123. g_parsefile->pf_fd = fd;
  9124. if (g_parsefile->buf == NULL)
  9125. g_parsefile->buf = ckmalloc(IBUFSIZ);
  9126. g_parsefile->left_in_buffer = 0;
  9127. g_parsefile->left_in_line = 0;
  9128. g_parsefile->linno = 1;
  9129. }
  9130. /*
  9131. * Set the input to take input from a file. If push is set, push the
  9132. * old input onto the stack first.
  9133. */
  9134. static int
  9135. setinputfile(const char *fname, int flags)
  9136. {
  9137. int fd;
  9138. int fd2;
  9139. INT_OFF;
  9140. fd = open(fname, O_RDONLY);
  9141. if (fd < 0) {
  9142. if (flags & INPUT_NOFILE_OK)
  9143. goto out;
  9144. ash_msg_and_raise_error("can't open '%s'", fname);
  9145. }
  9146. if (fd < 10) {
  9147. fd2 = copyfd(fd, 10);
  9148. close(fd);
  9149. if (fd2 < 0)
  9150. ash_msg_and_raise_error("out of file descriptors");
  9151. fd = fd2;
  9152. }
  9153. setinputfd(fd, flags & INPUT_PUSH_FILE);
  9154. out:
  9155. INT_ON;
  9156. return fd;
  9157. }
  9158. /*
  9159. * Like setinputfile, but takes input from a string.
  9160. */
  9161. static void
  9162. setinputstring(char *string)
  9163. {
  9164. INT_OFF;
  9165. pushfile();
  9166. g_parsefile->next_to_pgetc = string;
  9167. g_parsefile->left_in_line = strlen(string);
  9168. g_parsefile->buf = NULL;
  9169. g_parsefile->linno = 1;
  9170. INT_ON;
  9171. }
  9172. /* ============ mail.c
  9173. *
  9174. * Routines to check for mail.
  9175. */
  9176. #if ENABLE_ASH_MAIL
  9177. #define MAXMBOXES 10
  9178. /* times of mailboxes */
  9179. static time_t mailtime[MAXMBOXES];
  9180. /* Set if MAIL or MAILPATH is changed. */
  9181. static smallint mail_var_path_changed;
  9182. /*
  9183. * Print appropriate message(s) if mail has arrived.
  9184. * If mail_var_path_changed is set,
  9185. * then the value of MAIL has mail_var_path_changed,
  9186. * so we just update the values.
  9187. */
  9188. static void
  9189. chkmail(void)
  9190. {
  9191. const char *mpath;
  9192. char *p;
  9193. char *q;
  9194. time_t *mtp;
  9195. struct stackmark smark;
  9196. struct stat statb;
  9197. setstackmark(&smark);
  9198. mpath = mpathset() ? mpathval() : mailval();
  9199. for (mtp = mailtime; mtp < mailtime + MAXMBOXES; mtp++) {
  9200. p = path_advance(&mpath, nullstr);
  9201. if (p == NULL)
  9202. break;
  9203. if (*p == '\0')
  9204. continue;
  9205. for (q = p; *q; q++)
  9206. continue;
  9207. #if DEBUG
  9208. if (q[-1] != '/')
  9209. abort();
  9210. #endif
  9211. q[-1] = '\0'; /* delete trailing '/' */
  9212. if (stat(p, &statb) < 0) {
  9213. *mtp = 0;
  9214. continue;
  9215. }
  9216. if (!mail_var_path_changed && statb.st_mtime != *mtp) {
  9217. fprintf(
  9218. stderr, "%s\n",
  9219. pathopt ? pathopt : "you have mail"
  9220. );
  9221. }
  9222. *mtp = statb.st_mtime;
  9223. }
  9224. mail_var_path_changed = 0;
  9225. popstackmark(&smark);
  9226. }
  9227. static void FAST_FUNC
  9228. changemail(const char *val UNUSED_PARAM)
  9229. {
  9230. mail_var_path_changed = 1;
  9231. }
  9232. #endif /* ASH_MAIL */
  9233. /* ============ ??? */
  9234. /*
  9235. * Set the shell parameters.
  9236. */
  9237. static void
  9238. setparam(char **argv)
  9239. {
  9240. char **newparam;
  9241. char **ap;
  9242. int nparam;
  9243. for (nparam = 0; argv[nparam]; nparam++)
  9244. continue;
  9245. ap = newparam = ckmalloc((nparam + 1) * sizeof(*ap));
  9246. while (*argv) {
  9247. *ap++ = ckstrdup(*argv++);
  9248. }
  9249. *ap = NULL;
  9250. freeparam(&shellparam);
  9251. shellparam.malloced = 1;
  9252. shellparam.nparam = nparam;
  9253. shellparam.p = newparam;
  9254. #if ENABLE_ASH_GETOPTS
  9255. shellparam.optind = 1;
  9256. shellparam.optoff = -1;
  9257. #endif
  9258. }
  9259. /*
  9260. * Process shell options. The global variable argptr contains a pointer
  9261. * to the argument list; we advance it past the options.
  9262. *
  9263. * SUSv3 section 2.8.1 "Consequences of Shell Errors" says:
  9264. * For a non-interactive shell, an error condition encountered
  9265. * by a special built-in ... shall cause the shell to write a diagnostic message
  9266. * to standard error and exit as shown in the following table:
  9267. * Error Special Built-In
  9268. * ...
  9269. * Utility syntax error (option or operand error) Shall exit
  9270. * ...
  9271. * However, in bug 1142 (http://busybox.net/bugs/view.php?id=1142)
  9272. * we see that bash does not do that (set "finishes" with error code 1 instead,
  9273. * and shell continues), and people rely on this behavior!
  9274. * Testcase:
  9275. * set -o barfoo 2>/dev/null
  9276. * echo $?
  9277. *
  9278. * Oh well. Let's mimic that.
  9279. */
  9280. static int
  9281. plus_minus_o(char *name, int val)
  9282. {
  9283. int i;
  9284. if (name) {
  9285. for (i = 0; i < NOPTS; i++) {
  9286. if (strcmp(name, optnames(i)) == 0) {
  9287. optlist[i] = val;
  9288. return 0;
  9289. }
  9290. }
  9291. ash_msg("illegal option %co %s", val ? '-' : '+', name);
  9292. return 1;
  9293. }
  9294. for (i = 0; i < NOPTS; i++) {
  9295. if (val) {
  9296. out1fmt("%-16s%s\n", optnames(i), optlist[i] ? "on" : "off");
  9297. } else {
  9298. out1fmt("set %co %s\n", optlist[i] ? '-' : '+', optnames(i));
  9299. }
  9300. }
  9301. return 0;
  9302. }
  9303. static void
  9304. setoption(int flag, int val)
  9305. {
  9306. int i;
  9307. for (i = 0; i < NOPTS; i++) {
  9308. if (optletters(i) == flag) {
  9309. optlist[i] = val;
  9310. return;
  9311. }
  9312. }
  9313. ash_msg_and_raise_error("illegal option %c%c", val ? '-' : '+', flag);
  9314. /* NOTREACHED */
  9315. }
  9316. static int
  9317. options(int cmdline)
  9318. {
  9319. char *p;
  9320. int val;
  9321. int c;
  9322. if (cmdline)
  9323. minusc = NULL;
  9324. while ((p = *argptr) != NULL) {
  9325. c = *p++;
  9326. if (c != '-' && c != '+')
  9327. break;
  9328. argptr++;
  9329. val = 0; /* val = 0 if c == '+' */
  9330. if (c == '-') {
  9331. val = 1;
  9332. if (p[0] == '\0' || LONE_DASH(p)) {
  9333. if (!cmdline) {
  9334. /* "-" means turn off -x and -v */
  9335. if (p[0] == '\0')
  9336. xflag = vflag = 0;
  9337. /* "--" means reset params */
  9338. else if (*argptr == NULL)
  9339. setparam(argptr);
  9340. }
  9341. break; /* "-" or "--" terminates options */
  9342. }
  9343. }
  9344. /* first char was + or - */
  9345. while ((c = *p++) != '\0') {
  9346. /* bash 3.2 indeed handles -c CMD and +c CMD the same */
  9347. if (c == 'c' && cmdline) {
  9348. minusc = p; /* command is after shell args */
  9349. } else if (c == 'o') {
  9350. if (plus_minus_o(*argptr, val)) {
  9351. /* it already printed err message */
  9352. return 1; /* error */
  9353. }
  9354. if (*argptr)
  9355. argptr++;
  9356. } else if (cmdline && (c == 'l')) { /* -l or +l == --login */
  9357. isloginsh = 1;
  9358. /* bash does not accept +-login, we also won't */
  9359. } else if (cmdline && val && (c == '-')) { /* long options */
  9360. if (strcmp(p, "login") == 0)
  9361. isloginsh = 1;
  9362. break;
  9363. } else {
  9364. setoption(c, val);
  9365. }
  9366. }
  9367. }
  9368. return 0;
  9369. }
  9370. /*
  9371. * The shift builtin command.
  9372. */
  9373. static int FAST_FUNC
  9374. shiftcmd(int argc UNUSED_PARAM, char **argv)
  9375. {
  9376. int n;
  9377. char **ap1, **ap2;
  9378. n = 1;
  9379. if (argv[1])
  9380. n = number(argv[1]);
  9381. if (n > shellparam.nparam)
  9382. n = 0; /* bash compat, was = shellparam.nparam; */
  9383. INT_OFF;
  9384. shellparam.nparam -= n;
  9385. for (ap1 = shellparam.p; --n >= 0; ap1++) {
  9386. if (shellparam.malloced)
  9387. free(*ap1);
  9388. }
  9389. ap2 = shellparam.p;
  9390. while ((*ap2++ = *ap1++) != NULL)
  9391. continue;
  9392. #if ENABLE_ASH_GETOPTS
  9393. shellparam.optind = 1;
  9394. shellparam.optoff = -1;
  9395. #endif
  9396. INT_ON;
  9397. return 0;
  9398. }
  9399. /*
  9400. * POSIX requires that 'set' (but not export or readonly) output the
  9401. * variables in lexicographic order - by the locale's collating order (sigh).
  9402. * Maybe we could keep them in an ordered balanced binary tree
  9403. * instead of hashed lists.
  9404. * For now just roll 'em through qsort for printing...
  9405. */
  9406. static int
  9407. showvars(const char *sep_prefix, int on, int off)
  9408. {
  9409. const char *sep;
  9410. char **ep, **epend;
  9411. ep = listvars(on, off, &epend);
  9412. qsort(ep, epend - ep, sizeof(char *), vpcmp);
  9413. sep = *sep_prefix ? " " : sep_prefix;
  9414. for (; ep < epend; ep++) {
  9415. const char *p;
  9416. const char *q;
  9417. p = strchrnul(*ep, '=');
  9418. q = nullstr;
  9419. if (*p)
  9420. q = single_quote(++p);
  9421. out1fmt("%s%s%.*s%s\n", sep_prefix, sep, (int)(p - *ep), *ep, q);
  9422. }
  9423. return 0;
  9424. }
  9425. /*
  9426. * The set command builtin.
  9427. */
  9428. static int FAST_FUNC
  9429. setcmd(int argc UNUSED_PARAM, char **argv UNUSED_PARAM)
  9430. {
  9431. int retval;
  9432. if (!argv[1])
  9433. return showvars(nullstr, 0, VUNSET);
  9434. INT_OFF;
  9435. retval = options(/*cmdline:*/ 0);
  9436. if (retval == 0) { /* if no parse error... */
  9437. optschanged();
  9438. if (*argptr != NULL) {
  9439. setparam(argptr);
  9440. }
  9441. }
  9442. INT_ON;
  9443. return retval;
  9444. }
  9445. #if ENABLE_ASH_RANDOM_SUPPORT
  9446. static void FAST_FUNC
  9447. change_random(const char *value)
  9448. {
  9449. uint32_t t;
  9450. if (value == NULL) {
  9451. /* "get", generate */
  9452. t = next_random(&random_gen);
  9453. /* set without recursion */
  9454. setvar(vrandom.var_text, utoa(t), VNOFUNC);
  9455. vrandom.flags &= ~VNOFUNC;
  9456. } else {
  9457. /* set/reset */
  9458. t = strtoul(value, NULL, 10);
  9459. INIT_RANDOM_T(&random_gen, (t ? t : 1), t);
  9460. }
  9461. }
  9462. #endif
  9463. #if ENABLE_ASH_GETOPTS
  9464. static int
  9465. getopts(char *optstr, char *optvar, char **optfirst, int *param_optind, int *optoff)
  9466. {
  9467. char *p, *q;
  9468. char c = '?';
  9469. int done = 0;
  9470. int err = 0;
  9471. char s[12];
  9472. char **optnext;
  9473. if (*param_optind < 1)
  9474. return 1;
  9475. optnext = optfirst + *param_optind - 1;
  9476. if (*param_optind <= 1 || *optoff < 0 || (int)strlen(optnext[-1]) < *optoff)
  9477. p = NULL;
  9478. else
  9479. p = optnext[-1] + *optoff;
  9480. if (p == NULL || *p == '\0') {
  9481. /* Current word is done, advance */
  9482. p = *optnext;
  9483. if (p == NULL || *p != '-' || *++p == '\0') {
  9484. atend:
  9485. p = NULL;
  9486. done = 1;
  9487. goto out;
  9488. }
  9489. optnext++;
  9490. if (LONE_DASH(p)) /* check for "--" */
  9491. goto atend;
  9492. }
  9493. c = *p++;
  9494. for (q = optstr; *q != c;) {
  9495. if (*q == '\0') {
  9496. if (optstr[0] == ':') {
  9497. s[0] = c;
  9498. s[1] = '\0';
  9499. err |= setvarsafe("OPTARG", s, 0);
  9500. } else {
  9501. fprintf(stderr, "Illegal option -%c\n", c);
  9502. unsetvar("OPTARG");
  9503. }
  9504. c = '?';
  9505. goto out;
  9506. }
  9507. if (*++q == ':')
  9508. q++;
  9509. }
  9510. if (*++q == ':') {
  9511. if (*p == '\0' && (p = *optnext) == NULL) {
  9512. if (optstr[0] == ':') {
  9513. s[0] = c;
  9514. s[1] = '\0';
  9515. err |= setvarsafe("OPTARG", s, 0);
  9516. c = ':';
  9517. } else {
  9518. fprintf(stderr, "No arg for -%c option\n", c);
  9519. unsetvar("OPTARG");
  9520. c = '?';
  9521. }
  9522. goto out;
  9523. }
  9524. if (p == *optnext)
  9525. optnext++;
  9526. err |= setvarsafe("OPTARG", p, 0);
  9527. p = NULL;
  9528. } else
  9529. err |= setvarsafe("OPTARG", nullstr, 0);
  9530. out:
  9531. *optoff = p ? p - *(optnext - 1) : -1;
  9532. *param_optind = optnext - optfirst + 1;
  9533. fmtstr(s, sizeof(s), "%d", *param_optind);
  9534. err |= setvarsafe("OPTIND", s, VNOFUNC);
  9535. s[0] = c;
  9536. s[1] = '\0';
  9537. err |= setvarsafe(optvar, s, 0);
  9538. if (err) {
  9539. *param_optind = 1;
  9540. *optoff = -1;
  9541. flush_stdout_stderr();
  9542. raise_exception(EXERROR);
  9543. }
  9544. return done;
  9545. }
  9546. /*
  9547. * The getopts builtin. Shellparam.optnext points to the next argument
  9548. * to be processed. Shellparam.optptr points to the next character to
  9549. * be processed in the current argument. If shellparam.optnext is NULL,
  9550. * then it's the first time getopts has been called.
  9551. */
  9552. static int FAST_FUNC
  9553. getoptscmd(int argc, char **argv)
  9554. {
  9555. char **optbase;
  9556. if (argc < 3)
  9557. ash_msg_and_raise_error("usage: getopts optstring var [arg]");
  9558. if (argc == 3) {
  9559. optbase = shellparam.p;
  9560. if (shellparam.optind > shellparam.nparam + 1) {
  9561. shellparam.optind = 1;
  9562. shellparam.optoff = -1;
  9563. }
  9564. } else {
  9565. optbase = &argv[3];
  9566. if (shellparam.optind > argc - 2) {
  9567. shellparam.optind = 1;
  9568. shellparam.optoff = -1;
  9569. }
  9570. }
  9571. return getopts(argv[1], argv[2], optbase, &shellparam.optind,
  9572. &shellparam.optoff);
  9573. }
  9574. #endif /* ASH_GETOPTS */
  9575. /* ============ Shell parser */
  9576. struct heredoc {
  9577. struct heredoc *next; /* next here document in list */
  9578. union node *here; /* redirection node */
  9579. char *eofmark; /* string indicating end of input */
  9580. smallint striptabs; /* if set, strip leading tabs */
  9581. };
  9582. static smallint tokpushback; /* last token pushed back */
  9583. static smallint parsebackquote; /* nonzero if we are inside backquotes */
  9584. static smallint quoteflag; /* set if (part of) last token was quoted */
  9585. static token_id_t lasttoken; /* last token read (integer id Txxx) */
  9586. static struct heredoc *heredoclist; /* list of here documents to read */
  9587. static char *wordtext; /* text of last word returned by readtoken */
  9588. static struct nodelist *backquotelist;
  9589. static union node *redirnode;
  9590. static struct heredoc *heredoc;
  9591. static const char *
  9592. tokname(char *buf, int tok)
  9593. {
  9594. if (tok < TSEMI)
  9595. return tokname_array[tok] + 1;
  9596. sprintf(buf, "\"%s\"", tokname_array[tok] + 1);
  9597. return buf;
  9598. }
  9599. /* raise_error_unexpected_syntax:
  9600. * Called when an unexpected token is read during the parse. The argument
  9601. * is the token that is expected, or -1 if more than one type of token can
  9602. * occur at this point.
  9603. */
  9604. static void raise_error_unexpected_syntax(int) NORETURN;
  9605. static void
  9606. raise_error_unexpected_syntax(int token)
  9607. {
  9608. char msg[64];
  9609. char buf[16];
  9610. int l;
  9611. l = sprintf(msg, "unexpected %s", tokname(buf, lasttoken));
  9612. if (token >= 0)
  9613. sprintf(msg + l, " (expecting %s)", tokname(buf, token));
  9614. raise_error_syntax(msg);
  9615. /* NOTREACHED */
  9616. }
  9617. #define EOFMARKLEN 79
  9618. /* parsing is heavily cross-recursive, need these forward decls */
  9619. static union node *andor(void);
  9620. static union node *pipeline(void);
  9621. static union node *parse_command(void);
  9622. static void parseheredoc(void);
  9623. static char peektoken(void);
  9624. static int readtoken(void);
  9625. static union node *
  9626. list(int nlflag)
  9627. {
  9628. union node *n1, *n2, *n3;
  9629. int tok;
  9630. checkkwd = CHKNL | CHKKWD | CHKALIAS;
  9631. if (nlflag == 2 && peektoken())
  9632. return NULL;
  9633. n1 = NULL;
  9634. for (;;) {
  9635. n2 = andor();
  9636. tok = readtoken();
  9637. if (tok == TBACKGND) {
  9638. if (n2->type == NPIPE) {
  9639. n2->npipe.pipe_backgnd = 1;
  9640. } else {
  9641. if (n2->type != NREDIR) {
  9642. n3 = stzalloc(sizeof(struct nredir));
  9643. n3->nredir.n = n2;
  9644. /*n3->nredir.redirect = NULL; - stzalloc did it */
  9645. n2 = n3;
  9646. }
  9647. n2->type = NBACKGND;
  9648. }
  9649. }
  9650. if (n1 == NULL) {
  9651. n1 = n2;
  9652. } else {
  9653. n3 = stzalloc(sizeof(struct nbinary));
  9654. n3->type = NSEMI;
  9655. n3->nbinary.ch1 = n1;
  9656. n3->nbinary.ch2 = n2;
  9657. n1 = n3;
  9658. }
  9659. switch (tok) {
  9660. case TBACKGND:
  9661. case TSEMI:
  9662. tok = readtoken();
  9663. /* fall through */
  9664. case TNL:
  9665. if (tok == TNL) {
  9666. parseheredoc();
  9667. if (nlflag == 1)
  9668. return n1;
  9669. } else {
  9670. tokpushback = 1;
  9671. }
  9672. checkkwd = CHKNL | CHKKWD | CHKALIAS;
  9673. if (peektoken())
  9674. return n1;
  9675. break;
  9676. case TEOF:
  9677. if (heredoclist)
  9678. parseheredoc();
  9679. else
  9680. pungetc(); /* push back EOF on input */
  9681. return n1;
  9682. default:
  9683. if (nlflag == 1)
  9684. raise_error_unexpected_syntax(-1);
  9685. tokpushback = 1;
  9686. return n1;
  9687. }
  9688. }
  9689. }
  9690. static union node *
  9691. andor(void)
  9692. {
  9693. union node *n1, *n2, *n3;
  9694. int t;
  9695. n1 = pipeline();
  9696. for (;;) {
  9697. t = readtoken();
  9698. if (t == TAND) {
  9699. t = NAND;
  9700. } else if (t == TOR) {
  9701. t = NOR;
  9702. } else {
  9703. tokpushback = 1;
  9704. return n1;
  9705. }
  9706. checkkwd = CHKNL | CHKKWD | CHKALIAS;
  9707. n2 = pipeline();
  9708. n3 = stzalloc(sizeof(struct nbinary));
  9709. n3->type = t;
  9710. n3->nbinary.ch1 = n1;
  9711. n3->nbinary.ch2 = n2;
  9712. n1 = n3;
  9713. }
  9714. }
  9715. static union node *
  9716. pipeline(void)
  9717. {
  9718. union node *n1, *n2, *pipenode;
  9719. struct nodelist *lp, *prev;
  9720. int negate;
  9721. negate = 0;
  9722. TRACE(("pipeline: entered\n"));
  9723. if (readtoken() == TNOT) {
  9724. negate = !negate;
  9725. checkkwd = CHKKWD | CHKALIAS;
  9726. } else
  9727. tokpushback = 1;
  9728. n1 = parse_command();
  9729. if (readtoken() == TPIPE) {
  9730. pipenode = stzalloc(sizeof(struct npipe));
  9731. pipenode->type = NPIPE;
  9732. /*pipenode->npipe.pipe_backgnd = 0; - stzalloc did it */
  9733. lp = stzalloc(sizeof(struct nodelist));
  9734. pipenode->npipe.cmdlist = lp;
  9735. lp->n = n1;
  9736. do {
  9737. prev = lp;
  9738. lp = stzalloc(sizeof(struct nodelist));
  9739. checkkwd = CHKNL | CHKKWD | CHKALIAS;
  9740. lp->n = parse_command();
  9741. prev->next = lp;
  9742. } while (readtoken() == TPIPE);
  9743. lp->next = NULL;
  9744. n1 = pipenode;
  9745. }
  9746. tokpushback = 1;
  9747. if (negate) {
  9748. n2 = stzalloc(sizeof(struct nnot));
  9749. n2->type = NNOT;
  9750. n2->nnot.com = n1;
  9751. return n2;
  9752. }
  9753. return n1;
  9754. }
  9755. static union node *
  9756. makename(void)
  9757. {
  9758. union node *n;
  9759. n = stzalloc(sizeof(struct narg));
  9760. n->type = NARG;
  9761. /*n->narg.next = NULL; - stzalloc did it */
  9762. n->narg.text = wordtext;
  9763. n->narg.backquote = backquotelist;
  9764. return n;
  9765. }
  9766. static void
  9767. fixredir(union node *n, const char *text, int err)
  9768. {
  9769. int fd;
  9770. TRACE(("Fix redir %s %d\n", text, err));
  9771. if (!err)
  9772. n->ndup.vname = NULL;
  9773. fd = bb_strtou(text, NULL, 10);
  9774. if (!errno && fd >= 0)
  9775. n->ndup.dupfd = fd;
  9776. else if (LONE_DASH(text))
  9777. n->ndup.dupfd = -1;
  9778. else {
  9779. if (err)
  9780. raise_error_syntax("bad fd number");
  9781. n->ndup.vname = makename();
  9782. }
  9783. }
  9784. /*
  9785. * Returns true if the text contains nothing to expand (no dollar signs
  9786. * or backquotes).
  9787. */
  9788. static int
  9789. noexpand(const char *text)
  9790. {
  9791. unsigned char c;
  9792. while ((c = *text++) != '\0') {
  9793. if (c == CTLQUOTEMARK)
  9794. continue;
  9795. if (c == CTLESC)
  9796. text++;
  9797. else if (SIT(c, BASESYNTAX) == CCTL)
  9798. return 0;
  9799. }
  9800. return 1;
  9801. }
  9802. static void
  9803. parsefname(void)
  9804. {
  9805. union node *n = redirnode;
  9806. if (readtoken() != TWORD)
  9807. raise_error_unexpected_syntax(-1);
  9808. if (n->type == NHERE) {
  9809. struct heredoc *here = heredoc;
  9810. struct heredoc *p;
  9811. int i;
  9812. if (quoteflag == 0)
  9813. n->type = NXHERE;
  9814. TRACE(("Here document %d\n", n->type));
  9815. if (!noexpand(wordtext) || (i = strlen(wordtext)) == 0 || i > EOFMARKLEN)
  9816. raise_error_syntax("illegal eof marker for << redirection");
  9817. rmescapes(wordtext, 0);
  9818. here->eofmark = wordtext;
  9819. here->next = NULL;
  9820. if (heredoclist == NULL)
  9821. heredoclist = here;
  9822. else {
  9823. for (p = heredoclist; p->next; p = p->next)
  9824. continue;
  9825. p->next = here;
  9826. }
  9827. } else if (n->type == NTOFD || n->type == NFROMFD) {
  9828. fixredir(n, wordtext, 0);
  9829. } else {
  9830. n->nfile.fname = makename();
  9831. }
  9832. }
  9833. static union node *
  9834. simplecmd(void)
  9835. {
  9836. union node *args, **app;
  9837. union node *n = NULL;
  9838. union node *vars, **vpp;
  9839. union node **rpp, *redir;
  9840. int savecheckkwd;
  9841. #if ENABLE_ASH_BASH_COMPAT
  9842. smallint double_brackets_flag = 0;
  9843. #endif
  9844. args = NULL;
  9845. app = &args;
  9846. vars = NULL;
  9847. vpp = &vars;
  9848. redir = NULL;
  9849. rpp = &redir;
  9850. savecheckkwd = CHKALIAS;
  9851. for (;;) {
  9852. int t;
  9853. checkkwd = savecheckkwd;
  9854. t = readtoken();
  9855. switch (t) {
  9856. #if ENABLE_ASH_BASH_COMPAT
  9857. case TAND: /* "&&" */
  9858. case TOR: /* "||" */
  9859. if (!double_brackets_flag) {
  9860. tokpushback = 1;
  9861. goto out;
  9862. }
  9863. wordtext = (char *) (t == TAND ? "-a" : "-o");
  9864. #endif
  9865. case TWORD:
  9866. n = stzalloc(sizeof(struct narg));
  9867. n->type = NARG;
  9868. /*n->narg.next = NULL; - stzalloc did it */
  9869. n->narg.text = wordtext;
  9870. #if ENABLE_ASH_BASH_COMPAT
  9871. if (strcmp("[[", wordtext) == 0)
  9872. double_brackets_flag = 1;
  9873. else if (strcmp("]]", wordtext) == 0)
  9874. double_brackets_flag = 0;
  9875. #endif
  9876. n->narg.backquote = backquotelist;
  9877. if (savecheckkwd && isassignment(wordtext)) {
  9878. *vpp = n;
  9879. vpp = &n->narg.next;
  9880. } else {
  9881. *app = n;
  9882. app = &n->narg.next;
  9883. savecheckkwd = 0;
  9884. }
  9885. break;
  9886. case TREDIR:
  9887. *rpp = n = redirnode;
  9888. rpp = &n->nfile.next;
  9889. parsefname(); /* read name of redirection file */
  9890. break;
  9891. case TLP:
  9892. if (args && app == &args->narg.next
  9893. && !vars && !redir
  9894. ) {
  9895. struct builtincmd *bcmd;
  9896. const char *name;
  9897. /* We have a function */
  9898. if (readtoken() != TRP)
  9899. raise_error_unexpected_syntax(TRP);
  9900. name = n->narg.text;
  9901. if (!goodname(name)
  9902. || ((bcmd = find_builtin(name)) && IS_BUILTIN_SPECIAL(bcmd))
  9903. ) {
  9904. raise_error_syntax("bad function name");
  9905. }
  9906. n->type = NDEFUN;
  9907. checkkwd = CHKNL | CHKKWD | CHKALIAS;
  9908. n->narg.next = parse_command();
  9909. return n;
  9910. }
  9911. /* fall through */
  9912. default:
  9913. tokpushback = 1;
  9914. goto out;
  9915. }
  9916. }
  9917. out:
  9918. *app = NULL;
  9919. *vpp = NULL;
  9920. *rpp = NULL;
  9921. n = stzalloc(sizeof(struct ncmd));
  9922. n->type = NCMD;
  9923. n->ncmd.args = args;
  9924. n->ncmd.assign = vars;
  9925. n->ncmd.redirect = redir;
  9926. return n;
  9927. }
  9928. static union node *
  9929. parse_command(void)
  9930. {
  9931. union node *n1, *n2;
  9932. union node *ap, **app;
  9933. union node *cp, **cpp;
  9934. union node *redir, **rpp;
  9935. union node **rpp2;
  9936. int t;
  9937. redir = NULL;
  9938. rpp2 = &redir;
  9939. switch (readtoken()) {
  9940. default:
  9941. raise_error_unexpected_syntax(-1);
  9942. /* NOTREACHED */
  9943. case TIF:
  9944. n1 = stzalloc(sizeof(struct nif));
  9945. n1->type = NIF;
  9946. n1->nif.test = list(0);
  9947. if (readtoken() != TTHEN)
  9948. raise_error_unexpected_syntax(TTHEN);
  9949. n1->nif.ifpart = list(0);
  9950. n2 = n1;
  9951. while (readtoken() == TELIF) {
  9952. n2->nif.elsepart = stzalloc(sizeof(struct nif));
  9953. n2 = n2->nif.elsepart;
  9954. n2->type = NIF;
  9955. n2->nif.test = list(0);
  9956. if (readtoken() != TTHEN)
  9957. raise_error_unexpected_syntax(TTHEN);
  9958. n2->nif.ifpart = list(0);
  9959. }
  9960. if (lasttoken == TELSE)
  9961. n2->nif.elsepart = list(0);
  9962. else {
  9963. n2->nif.elsepart = NULL;
  9964. tokpushback = 1;
  9965. }
  9966. t = TFI;
  9967. break;
  9968. case TWHILE:
  9969. case TUNTIL: {
  9970. int got;
  9971. n1 = stzalloc(sizeof(struct nbinary));
  9972. n1->type = (lasttoken == TWHILE) ? NWHILE : NUNTIL;
  9973. n1->nbinary.ch1 = list(0);
  9974. got = readtoken();
  9975. if (got != TDO) {
  9976. TRACE(("expecting DO got '%s' %s\n", tokname_array[got] + 1,
  9977. got == TWORD ? wordtext : ""));
  9978. raise_error_unexpected_syntax(TDO);
  9979. }
  9980. n1->nbinary.ch2 = list(0);
  9981. t = TDONE;
  9982. break;
  9983. }
  9984. case TFOR:
  9985. if (readtoken() != TWORD || quoteflag || !goodname(wordtext))
  9986. raise_error_syntax("bad for loop variable");
  9987. n1 = stzalloc(sizeof(struct nfor));
  9988. n1->type = NFOR;
  9989. n1->nfor.var = wordtext;
  9990. checkkwd = CHKKWD | CHKALIAS;
  9991. if (readtoken() == TIN) {
  9992. app = &ap;
  9993. while (readtoken() == TWORD) {
  9994. n2 = stzalloc(sizeof(struct narg));
  9995. n2->type = NARG;
  9996. /*n2->narg.next = NULL; - stzalloc did it */
  9997. n2->narg.text = wordtext;
  9998. n2->narg.backquote = backquotelist;
  9999. *app = n2;
  10000. app = &n2->narg.next;
  10001. }
  10002. *app = NULL;
  10003. n1->nfor.args = ap;
  10004. if (lasttoken != TNL && lasttoken != TSEMI)
  10005. raise_error_unexpected_syntax(-1);
  10006. } else {
  10007. n2 = stzalloc(sizeof(struct narg));
  10008. n2->type = NARG;
  10009. /*n2->narg.next = NULL; - stzalloc did it */
  10010. n2->narg.text = (char *)dolatstr;
  10011. /*n2->narg.backquote = NULL;*/
  10012. n1->nfor.args = n2;
  10013. /*
  10014. * Newline or semicolon here is optional (but note
  10015. * that the original Bourne shell only allowed NL).
  10016. */
  10017. if (lasttoken != TNL && lasttoken != TSEMI)
  10018. tokpushback = 1;
  10019. }
  10020. checkkwd = CHKNL | CHKKWD | CHKALIAS;
  10021. if (readtoken() != TDO)
  10022. raise_error_unexpected_syntax(TDO);
  10023. n1->nfor.body = list(0);
  10024. t = TDONE;
  10025. break;
  10026. case TCASE:
  10027. n1 = stzalloc(sizeof(struct ncase));
  10028. n1->type = NCASE;
  10029. if (readtoken() != TWORD)
  10030. raise_error_unexpected_syntax(TWORD);
  10031. n1->ncase.expr = n2 = stzalloc(sizeof(struct narg));
  10032. n2->type = NARG;
  10033. /*n2->narg.next = NULL; - stzalloc did it */
  10034. n2->narg.text = wordtext;
  10035. n2->narg.backquote = backquotelist;
  10036. do {
  10037. checkkwd = CHKKWD | CHKALIAS;
  10038. } while (readtoken() == TNL);
  10039. if (lasttoken != TIN)
  10040. raise_error_unexpected_syntax(TIN);
  10041. cpp = &n1->ncase.cases;
  10042. next_case:
  10043. checkkwd = CHKNL | CHKKWD;
  10044. t = readtoken();
  10045. while (t != TESAC) {
  10046. if (lasttoken == TLP)
  10047. readtoken();
  10048. *cpp = cp = stzalloc(sizeof(struct nclist));
  10049. cp->type = NCLIST;
  10050. app = &cp->nclist.pattern;
  10051. for (;;) {
  10052. *app = ap = stzalloc(sizeof(struct narg));
  10053. ap->type = NARG;
  10054. /*ap->narg.next = NULL; - stzalloc did it */
  10055. ap->narg.text = wordtext;
  10056. ap->narg.backquote = backquotelist;
  10057. if (readtoken() != TPIPE)
  10058. break;
  10059. app = &ap->narg.next;
  10060. readtoken();
  10061. }
  10062. //ap->narg.next = NULL;
  10063. if (lasttoken != TRP)
  10064. raise_error_unexpected_syntax(TRP);
  10065. cp->nclist.body = list(2);
  10066. cpp = &cp->nclist.next;
  10067. checkkwd = CHKNL | CHKKWD;
  10068. t = readtoken();
  10069. if (t != TESAC) {
  10070. if (t != TENDCASE)
  10071. raise_error_unexpected_syntax(TENDCASE);
  10072. goto next_case;
  10073. }
  10074. }
  10075. *cpp = NULL;
  10076. goto redir;
  10077. case TLP:
  10078. n1 = stzalloc(sizeof(struct nredir));
  10079. n1->type = NSUBSHELL;
  10080. n1->nredir.n = list(0);
  10081. /*n1->nredir.redirect = NULL; - stzalloc did it */
  10082. t = TRP;
  10083. break;
  10084. case TBEGIN:
  10085. n1 = list(0);
  10086. t = TEND;
  10087. break;
  10088. case TWORD:
  10089. case TREDIR:
  10090. tokpushback = 1;
  10091. return simplecmd();
  10092. }
  10093. if (readtoken() != t)
  10094. raise_error_unexpected_syntax(t);
  10095. redir:
  10096. /* Now check for redirection which may follow command */
  10097. checkkwd = CHKKWD | CHKALIAS;
  10098. rpp = rpp2;
  10099. while (readtoken() == TREDIR) {
  10100. *rpp = n2 = redirnode;
  10101. rpp = &n2->nfile.next;
  10102. parsefname();
  10103. }
  10104. tokpushback = 1;
  10105. *rpp = NULL;
  10106. if (redir) {
  10107. if (n1->type != NSUBSHELL) {
  10108. n2 = stzalloc(sizeof(struct nredir));
  10109. n2->type = NREDIR;
  10110. n2->nredir.n = n1;
  10111. n1 = n2;
  10112. }
  10113. n1->nredir.redirect = redir;
  10114. }
  10115. return n1;
  10116. }
  10117. #if ENABLE_ASH_BASH_COMPAT
  10118. static int decode_dollar_squote(void)
  10119. {
  10120. static const char C_escapes[] ALIGN1 = "nrbtfav""x\\01234567";
  10121. int c, cnt;
  10122. char *p;
  10123. char buf[4];
  10124. c = pgetc();
  10125. p = strchr(C_escapes, c);
  10126. if (p) {
  10127. buf[0] = c;
  10128. p = buf;
  10129. cnt = 3;
  10130. if ((unsigned char)(c - '0') <= 7) { /* \ooo */
  10131. do {
  10132. c = pgetc();
  10133. *++p = c;
  10134. } while ((unsigned char)(c - '0') <= 7 && --cnt);
  10135. pungetc();
  10136. } else if (c == 'x') { /* \xHH */
  10137. do {
  10138. c = pgetc();
  10139. *++p = c;
  10140. } while (isxdigit(c) && --cnt);
  10141. pungetc();
  10142. if (cnt == 3) { /* \x but next char is "bad" */
  10143. c = 'x';
  10144. goto unrecognized;
  10145. }
  10146. } else { /* simple seq like \\ or \t */
  10147. p++;
  10148. }
  10149. *p = '\0';
  10150. p = buf;
  10151. c = bb_process_escape_sequence((void*)&p);
  10152. } else { /* unrecognized "\z": print both chars unless ' or " */
  10153. if (c != '\'' && c != '"') {
  10154. unrecognized:
  10155. c |= 0x100; /* "please encode \, then me" */
  10156. }
  10157. }
  10158. return c;
  10159. }
  10160. #endif
  10161. /*
  10162. * If eofmark is NULL, read a word or a redirection symbol. If eofmark
  10163. * is not NULL, read a here document. In the latter case, eofmark is the
  10164. * word which marks the end of the document and striptabs is true if
  10165. * leading tabs should be stripped from the document. The argument c
  10166. * is the first character of the input token or document.
  10167. *
  10168. * Because C does not have internal subroutines, I have simulated them
  10169. * using goto's to implement the subroutine linkage. The following macros
  10170. * will run code that appears at the end of readtoken1.
  10171. */
  10172. #define CHECKEND() {goto checkend; checkend_return:;}
  10173. #define PARSEREDIR() {goto parseredir; parseredir_return:;}
  10174. #define PARSESUB() {goto parsesub; parsesub_return:;}
  10175. #define PARSEBACKQOLD() {oldstyle = 1; goto parsebackq; parsebackq_oldreturn:;}
  10176. #define PARSEBACKQNEW() {oldstyle = 0; goto parsebackq; parsebackq_newreturn:;}
  10177. #define PARSEARITH() {goto parsearith; parsearith_return:;}
  10178. static int
  10179. readtoken1(int c, int syntax, char *eofmark, int striptabs)
  10180. {
  10181. /* NB: syntax parameter fits into smallint */
  10182. /* c parameter is an unsigned char or PEOF or PEOA */
  10183. char *out;
  10184. int len;
  10185. char line[EOFMARKLEN + 1];
  10186. struct nodelist *bqlist;
  10187. smallint quotef;
  10188. smallint dblquote;
  10189. smallint oldstyle;
  10190. smallint prevsyntax; /* syntax before arithmetic */
  10191. #if ENABLE_ASH_EXPAND_PRMT
  10192. smallint pssyntax; /* we are expanding a prompt string */
  10193. #endif
  10194. int varnest; /* levels of variables expansion */
  10195. int arinest; /* levels of arithmetic expansion */
  10196. int parenlevel; /* levels of parens in arithmetic */
  10197. int dqvarnest; /* levels of variables expansion within double quotes */
  10198. IF_ASH_BASH_COMPAT(smallint bash_dollar_squote = 0;)
  10199. #if __GNUC__
  10200. /* Avoid longjmp clobbering */
  10201. (void) &out;
  10202. (void) &quotef;
  10203. (void) &dblquote;
  10204. (void) &varnest;
  10205. (void) &arinest;
  10206. (void) &parenlevel;
  10207. (void) &dqvarnest;
  10208. (void) &oldstyle;
  10209. (void) &prevsyntax;
  10210. (void) &syntax;
  10211. #endif
  10212. startlinno = g_parsefile->linno;
  10213. bqlist = NULL;
  10214. quotef = 0;
  10215. prevsyntax = 0;
  10216. #if ENABLE_ASH_EXPAND_PRMT
  10217. pssyntax = (syntax == PSSYNTAX);
  10218. if (pssyntax)
  10219. syntax = DQSYNTAX;
  10220. #endif
  10221. dblquote = (syntax == DQSYNTAX);
  10222. varnest = 0;
  10223. arinest = 0;
  10224. parenlevel = 0;
  10225. dqvarnest = 0;
  10226. STARTSTACKSTR(out);
  10227. loop:
  10228. /* For each line, until end of word */
  10229. CHECKEND(); /* set c to PEOF if at end of here document */
  10230. for (;;) { /* until end of line or end of word */
  10231. CHECKSTRSPACE(4, out); /* permit 4 calls to USTPUTC */
  10232. switch (SIT(c, syntax)) {
  10233. case CNL: /* '\n' */
  10234. if (syntax == BASESYNTAX)
  10235. goto endword; /* exit outer loop */
  10236. USTPUTC(c, out);
  10237. g_parsefile->linno++;
  10238. setprompt_if(doprompt, 2);
  10239. c = pgetc();
  10240. goto loop; /* continue outer loop */
  10241. case CWORD:
  10242. USTPUTC(c, out);
  10243. break;
  10244. case CCTL:
  10245. if (eofmark == NULL || dblquote)
  10246. USTPUTC(CTLESC, out);
  10247. #if ENABLE_ASH_BASH_COMPAT
  10248. if (c == '\\' && bash_dollar_squote) {
  10249. c = decode_dollar_squote();
  10250. if (c & 0x100) {
  10251. USTPUTC('\\', out);
  10252. c = (unsigned char)c;
  10253. }
  10254. }
  10255. #endif
  10256. USTPUTC(c, out);
  10257. break;
  10258. case CBACK: /* backslash */
  10259. c = pgetc_without_PEOA();
  10260. if (c == PEOF) {
  10261. USTPUTC(CTLESC, out);
  10262. USTPUTC('\\', out);
  10263. pungetc();
  10264. } else if (c == '\n') {
  10265. setprompt_if(doprompt, 2);
  10266. } else {
  10267. #if ENABLE_ASH_EXPAND_PRMT
  10268. if (c == '$' && pssyntax) {
  10269. USTPUTC(CTLESC, out);
  10270. USTPUTC('\\', out);
  10271. }
  10272. #endif
  10273. /* Backslash is retained if we are in "str" and next char isn't special */
  10274. if (dblquote
  10275. && c != '\\'
  10276. && c != '`'
  10277. && c != '$'
  10278. && (c != '"' || eofmark != NULL)
  10279. ) {
  10280. USTPUTC(CTLESC, out);
  10281. USTPUTC('\\', out);
  10282. }
  10283. if (SIT(c, SQSYNTAX) == CCTL)
  10284. USTPUTC(CTLESC, out);
  10285. USTPUTC(c, out);
  10286. quotef = 1;
  10287. }
  10288. break;
  10289. case CSQUOTE:
  10290. syntax = SQSYNTAX;
  10291. quotemark:
  10292. if (eofmark == NULL) {
  10293. USTPUTC(CTLQUOTEMARK, out);
  10294. }
  10295. break;
  10296. case CDQUOTE:
  10297. syntax = DQSYNTAX;
  10298. dblquote = 1;
  10299. goto quotemark;
  10300. case CENDQUOTE:
  10301. IF_ASH_BASH_COMPAT(bash_dollar_squote = 0;)
  10302. if (eofmark != NULL && arinest == 0
  10303. && varnest == 0
  10304. ) {
  10305. USTPUTC(c, out);
  10306. } else {
  10307. if (dqvarnest == 0) {
  10308. syntax = BASESYNTAX;
  10309. dblquote = 0;
  10310. }
  10311. quotef = 1;
  10312. goto quotemark;
  10313. }
  10314. break;
  10315. case CVAR: /* '$' */
  10316. PARSESUB(); /* parse substitution */
  10317. break;
  10318. case CENDVAR: /* '}' */
  10319. if (varnest > 0) {
  10320. varnest--;
  10321. if (dqvarnest > 0) {
  10322. dqvarnest--;
  10323. }
  10324. c = CTLENDVAR;
  10325. }
  10326. USTPUTC(c, out);
  10327. break;
  10328. #if ENABLE_SH_MATH_SUPPORT
  10329. case CLP: /* '(' in arithmetic */
  10330. parenlevel++;
  10331. USTPUTC(c, out);
  10332. break;
  10333. case CRP: /* ')' in arithmetic */
  10334. if (parenlevel > 0) {
  10335. parenlevel--;
  10336. } else {
  10337. if (pgetc() == ')') {
  10338. if (--arinest == 0) {
  10339. syntax = prevsyntax;
  10340. dblquote = (syntax == DQSYNTAX);
  10341. c = CTLENDARI;
  10342. }
  10343. } else {
  10344. /*
  10345. * unbalanced parens
  10346. * (don't 2nd guess - no error)
  10347. */
  10348. pungetc();
  10349. }
  10350. }
  10351. USTPUTC(c, out);
  10352. break;
  10353. #endif
  10354. case CBQUOTE: /* '`' */
  10355. PARSEBACKQOLD();
  10356. break;
  10357. case CENDFILE:
  10358. goto endword; /* exit outer loop */
  10359. case CIGN:
  10360. break;
  10361. default:
  10362. if (varnest == 0) {
  10363. #if ENABLE_ASH_BASH_COMPAT
  10364. if (c == '&') {
  10365. if (pgetc() == '>')
  10366. c = 0x100 + '>'; /* flag &> */
  10367. pungetc();
  10368. }
  10369. #endif
  10370. goto endword; /* exit outer loop */
  10371. }
  10372. IF_ASH_ALIAS(if (c != PEOA))
  10373. USTPUTC(c, out);
  10374. }
  10375. c = pgetc_fast();
  10376. } /* for (;;) */
  10377. endword:
  10378. #if ENABLE_SH_MATH_SUPPORT
  10379. if (syntax == ARISYNTAX)
  10380. raise_error_syntax("missing '))'");
  10381. #endif
  10382. if (syntax != BASESYNTAX && !parsebackquote && eofmark == NULL)
  10383. raise_error_syntax("unterminated quoted string");
  10384. if (varnest != 0) {
  10385. startlinno = g_parsefile->linno;
  10386. /* { */
  10387. raise_error_syntax("missing '}'");
  10388. }
  10389. USTPUTC('\0', out);
  10390. len = out - (char *)stackblock();
  10391. out = stackblock();
  10392. if (eofmark == NULL) {
  10393. if ((c == '>' || c == '<' IF_ASH_BASH_COMPAT( || c == 0x100 + '>'))
  10394. && quotef == 0
  10395. ) {
  10396. if (isdigit_str9(out)) {
  10397. PARSEREDIR(); /* passed as params: out, c */
  10398. lasttoken = TREDIR;
  10399. return lasttoken;
  10400. }
  10401. /* else: non-number X seen, interpret it
  10402. * as "NNNX>file" = "NNNX >file" */
  10403. }
  10404. pungetc();
  10405. }
  10406. quoteflag = quotef;
  10407. backquotelist = bqlist;
  10408. grabstackblock(len);
  10409. wordtext = out;
  10410. lasttoken = TWORD;
  10411. return lasttoken;
  10412. /* end of readtoken routine */
  10413. /*
  10414. * Check to see whether we are at the end of the here document. When this
  10415. * is called, c is set to the first character of the next input line. If
  10416. * we are at the end of the here document, this routine sets the c to PEOF.
  10417. */
  10418. checkend: {
  10419. if (eofmark) {
  10420. #if ENABLE_ASH_ALIAS
  10421. if (c == PEOA)
  10422. c = pgetc_without_PEOA();
  10423. #endif
  10424. if (striptabs) {
  10425. while (c == '\t') {
  10426. c = pgetc_without_PEOA();
  10427. }
  10428. }
  10429. if (c == *eofmark) {
  10430. if (pfgets(line, sizeof(line)) != NULL) {
  10431. char *p, *q;
  10432. p = line;
  10433. for (q = eofmark + 1; *q && *p == *q; p++, q++)
  10434. continue;
  10435. if (*p == '\n' && *q == '\0') {
  10436. c = PEOF;
  10437. g_parsefile->linno++;
  10438. needprompt = doprompt;
  10439. } else {
  10440. pushstring(line, NULL);
  10441. }
  10442. }
  10443. }
  10444. }
  10445. goto checkend_return;
  10446. }
  10447. /*
  10448. * Parse a redirection operator. The variable "out" points to a string
  10449. * specifying the fd to be redirected. The variable "c" contains the
  10450. * first character of the redirection operator.
  10451. */
  10452. parseredir: {
  10453. /* out is already checked to be a valid number or "" */
  10454. int fd = (*out == '\0' ? -1 : atoi(out));
  10455. union node *np;
  10456. np = stzalloc(sizeof(struct nfile));
  10457. if (c == '>') {
  10458. np->nfile.fd = 1;
  10459. c = pgetc();
  10460. if (c == '>')
  10461. np->type = NAPPEND;
  10462. else if (c == '|')
  10463. np->type = NCLOBBER;
  10464. else if (c == '&')
  10465. np->type = NTOFD;
  10466. /* it also can be NTO2 (>&file), but we can't figure it out yet */
  10467. else {
  10468. np->type = NTO;
  10469. pungetc();
  10470. }
  10471. }
  10472. #if ENABLE_ASH_BASH_COMPAT
  10473. else if (c == 0x100 + '>') { /* this flags &> redirection */
  10474. np->nfile.fd = 1;
  10475. pgetc(); /* this is '>', no need to check */
  10476. np->type = NTO2;
  10477. }
  10478. #endif
  10479. else { /* c == '<' */
  10480. /*np->nfile.fd = 0; - stzalloc did it */
  10481. c = pgetc();
  10482. switch (c) {
  10483. case '<':
  10484. if (sizeof(struct nfile) != sizeof(struct nhere)) {
  10485. np = stzalloc(sizeof(struct nhere));
  10486. /*np->nfile.fd = 0; - stzalloc did it */
  10487. }
  10488. np->type = NHERE;
  10489. heredoc = stzalloc(sizeof(struct heredoc));
  10490. heredoc->here = np;
  10491. c = pgetc();
  10492. if (c == '-') {
  10493. heredoc->striptabs = 1;
  10494. } else {
  10495. /*heredoc->striptabs = 0; - stzalloc did it */
  10496. pungetc();
  10497. }
  10498. break;
  10499. case '&':
  10500. np->type = NFROMFD;
  10501. break;
  10502. case '>':
  10503. np->type = NFROMTO;
  10504. break;
  10505. default:
  10506. np->type = NFROM;
  10507. pungetc();
  10508. break;
  10509. }
  10510. }
  10511. if (fd >= 0)
  10512. np->nfile.fd = fd;
  10513. redirnode = np;
  10514. goto parseredir_return;
  10515. }
  10516. /*
  10517. * Parse a substitution. At this point, we have read the dollar sign
  10518. * and nothing else.
  10519. */
  10520. /* is_special(c) evaluates to 1 for c in "!#$*-0123456789?@"; 0 otherwise
  10521. * (assuming ascii char codes, as the original implementation did) */
  10522. #define is_special(c) \
  10523. (((unsigned)(c) - 33 < 32) \
  10524. && ((0xc1ff920dU >> ((unsigned)(c) - 33)) & 1))
  10525. parsesub: {
  10526. unsigned char subtype;
  10527. int typeloc;
  10528. int flags;
  10529. c = pgetc();
  10530. if (c > 255 /* PEOA or PEOF */
  10531. || (c != '(' && c != '{' && !is_name(c) && !is_special(c))
  10532. ) {
  10533. #if ENABLE_ASH_BASH_COMPAT
  10534. if (c == '\'')
  10535. bash_dollar_squote = 1;
  10536. else
  10537. #endif
  10538. USTPUTC('$', out);
  10539. pungetc();
  10540. } else if (c == '(') {
  10541. /* $(command) or $((arith)) */
  10542. if (pgetc() == '(') {
  10543. #if ENABLE_SH_MATH_SUPPORT
  10544. PARSEARITH();
  10545. #else
  10546. raise_error_syntax("you disabled math support for $((arith)) syntax");
  10547. #endif
  10548. } else {
  10549. pungetc();
  10550. PARSEBACKQNEW();
  10551. }
  10552. } else {
  10553. /* $VAR, $<specialchar>, ${...}, or PEOA/PEOF */
  10554. USTPUTC(CTLVAR, out);
  10555. typeloc = out - (char *)stackblock();
  10556. USTPUTC(VSNORMAL, out);
  10557. subtype = VSNORMAL;
  10558. if (c == '{') {
  10559. c = pgetc();
  10560. if (c == '#') {
  10561. c = pgetc();
  10562. if (c == '}')
  10563. c = '#'; /* ${#} - same as $# */
  10564. else
  10565. subtype = VSLENGTH; /* ${#VAR} */
  10566. } else {
  10567. subtype = 0;
  10568. }
  10569. }
  10570. if (c <= 255 /* not PEOA or PEOF */ && is_name(c)) {
  10571. /* $[{[#]]NAME[}] */
  10572. do {
  10573. STPUTC(c, out);
  10574. c = pgetc();
  10575. } while (c <= 255 /* not PEOA or PEOF */ && is_in_name(c));
  10576. } else if (isdigit(c)) {
  10577. /* $[{[#]]NUM[}] */
  10578. do {
  10579. STPUTC(c, out);
  10580. c = pgetc();
  10581. } while (isdigit(c));
  10582. } else if (is_special(c)) {
  10583. /* $[{[#]]<specialchar>[}] */
  10584. USTPUTC(c, out);
  10585. c = pgetc();
  10586. } else {
  10587. badsub:
  10588. raise_error_syntax("bad substitution");
  10589. }
  10590. if (c != '}' && subtype == VSLENGTH) {
  10591. /* ${#VAR didn't end with } */
  10592. goto badsub;
  10593. }
  10594. STPUTC('=', out);
  10595. flags = 0;
  10596. if (subtype == 0) {
  10597. /* ${VAR...} but not $VAR or ${#VAR} */
  10598. /* c == first char after VAR */
  10599. switch (c) {
  10600. case ':':
  10601. c = pgetc();
  10602. #if ENABLE_ASH_BASH_COMPAT
  10603. if (c == ':' || c == '$' || isdigit(c)) {
  10604. //TODO: support more general format ${v:EXPR:EXPR},
  10605. // where EXPR follows $(()) rules
  10606. subtype = VSSUBSTR;
  10607. pungetc();
  10608. break; /* "goto do_pungetc" is bigger (!) */
  10609. }
  10610. #endif
  10611. flags = VSNUL;
  10612. /*FALLTHROUGH*/
  10613. default: {
  10614. static const char types[] ALIGN1 = "}-+?=";
  10615. const char *p = strchr(types, c);
  10616. if (p == NULL)
  10617. goto badsub;
  10618. subtype = p - types + VSNORMAL;
  10619. break;
  10620. }
  10621. case '%':
  10622. case '#': {
  10623. int cc = c;
  10624. subtype = (c == '#' ? VSTRIMLEFT : VSTRIMRIGHT);
  10625. c = pgetc();
  10626. if (c != cc)
  10627. goto do_pungetc;
  10628. subtype++;
  10629. break;
  10630. }
  10631. #if ENABLE_ASH_BASH_COMPAT
  10632. case '/':
  10633. /* ${v/[/]pattern/repl} */
  10634. //TODO: encode pattern and repl separately.
  10635. // Currently ${v/$var_with_slash/repl} is horribly broken
  10636. subtype = VSREPLACE;
  10637. c = pgetc();
  10638. if (c != '/')
  10639. goto do_pungetc;
  10640. subtype++; /* VSREPLACEALL */
  10641. break;
  10642. #endif
  10643. }
  10644. } else {
  10645. do_pungetc:
  10646. pungetc();
  10647. }
  10648. if (dblquote || arinest)
  10649. flags |= VSQUOTE;
  10650. ((unsigned char *)stackblock())[typeloc] = subtype | flags;
  10651. if (subtype != VSNORMAL) {
  10652. varnest++;
  10653. if (dblquote || arinest) {
  10654. dqvarnest++;
  10655. }
  10656. }
  10657. }
  10658. goto parsesub_return;
  10659. }
  10660. /*
  10661. * Called to parse command substitutions. Newstyle is set if the command
  10662. * is enclosed inside $(...); nlpp is a pointer to the head of the linked
  10663. * list of commands (passed by reference), and savelen is the number of
  10664. * characters on the top of the stack which must be preserved.
  10665. */
  10666. parsebackq: {
  10667. struct nodelist **nlpp;
  10668. smallint savepbq;
  10669. union node *n;
  10670. char *volatile str;
  10671. struct jmploc jmploc;
  10672. struct jmploc *volatile savehandler;
  10673. size_t savelen;
  10674. smallint saveprompt = 0;
  10675. #ifdef __GNUC__
  10676. (void) &saveprompt;
  10677. #endif
  10678. savepbq = parsebackquote;
  10679. if (setjmp(jmploc.loc)) {
  10680. free(str);
  10681. parsebackquote = 0;
  10682. exception_handler = savehandler;
  10683. longjmp(exception_handler->loc, 1);
  10684. }
  10685. INT_OFF;
  10686. str = NULL;
  10687. savelen = out - (char *)stackblock();
  10688. if (savelen > 0) {
  10689. str = ckmalloc(savelen);
  10690. memcpy(str, stackblock(), savelen);
  10691. }
  10692. savehandler = exception_handler;
  10693. exception_handler = &jmploc;
  10694. INT_ON;
  10695. if (oldstyle) {
  10696. /* We must read until the closing backquote, giving special
  10697. * treatment to some slashes, and then push the string and
  10698. * reread it as input, interpreting it normally.
  10699. */
  10700. char *pout;
  10701. size_t psavelen;
  10702. char *pstr;
  10703. STARTSTACKSTR(pout);
  10704. for (;;) {
  10705. int pc;
  10706. setprompt_if(needprompt, 2);
  10707. pc = pgetc();
  10708. switch (pc) {
  10709. case '`':
  10710. goto done;
  10711. case '\\':
  10712. pc = pgetc();
  10713. if (pc == '\n') {
  10714. g_parsefile->linno++;
  10715. setprompt_if(doprompt, 2);
  10716. /*
  10717. * If eating a newline, avoid putting
  10718. * the newline into the new character
  10719. * stream (via the STPUTC after the
  10720. * switch).
  10721. */
  10722. continue;
  10723. }
  10724. if (pc != '\\' && pc != '`' && pc != '$'
  10725. && (!dblquote || pc != '"')
  10726. ) {
  10727. STPUTC('\\', pout);
  10728. }
  10729. if (pc <= 255 /* not PEOA or PEOF */) {
  10730. break;
  10731. }
  10732. /* fall through */
  10733. case PEOF:
  10734. IF_ASH_ALIAS(case PEOA:)
  10735. startlinno = g_parsefile->linno;
  10736. raise_error_syntax("EOF in backquote substitution");
  10737. case '\n':
  10738. g_parsefile->linno++;
  10739. needprompt = doprompt;
  10740. break;
  10741. default:
  10742. break;
  10743. }
  10744. STPUTC(pc, pout);
  10745. }
  10746. done:
  10747. STPUTC('\0', pout);
  10748. psavelen = pout - (char *)stackblock();
  10749. if (psavelen > 0) {
  10750. pstr = grabstackstr(pout);
  10751. setinputstring(pstr);
  10752. }
  10753. }
  10754. nlpp = &bqlist;
  10755. while (*nlpp)
  10756. nlpp = &(*nlpp)->next;
  10757. *nlpp = stzalloc(sizeof(**nlpp));
  10758. /* (*nlpp)->next = NULL; - stzalloc did it */
  10759. parsebackquote = oldstyle;
  10760. if (oldstyle) {
  10761. saveprompt = doprompt;
  10762. doprompt = 0;
  10763. }
  10764. n = list(2);
  10765. if (oldstyle)
  10766. doprompt = saveprompt;
  10767. else if (readtoken() != TRP)
  10768. raise_error_unexpected_syntax(TRP);
  10769. (*nlpp)->n = n;
  10770. if (oldstyle) {
  10771. /*
  10772. * Start reading from old file again, ignoring any pushed back
  10773. * tokens left from the backquote parsing
  10774. */
  10775. popfile();
  10776. tokpushback = 0;
  10777. }
  10778. while (stackblocksize() <= savelen)
  10779. growstackblock();
  10780. STARTSTACKSTR(out);
  10781. if (str) {
  10782. memcpy(out, str, savelen);
  10783. STADJUST(savelen, out);
  10784. INT_OFF;
  10785. free(str);
  10786. str = NULL;
  10787. INT_ON;
  10788. }
  10789. parsebackquote = savepbq;
  10790. exception_handler = savehandler;
  10791. if (arinest || dblquote)
  10792. USTPUTC(CTLBACKQ | CTLQUOTE, out);
  10793. else
  10794. USTPUTC(CTLBACKQ, out);
  10795. if (oldstyle)
  10796. goto parsebackq_oldreturn;
  10797. goto parsebackq_newreturn;
  10798. }
  10799. #if ENABLE_SH_MATH_SUPPORT
  10800. /*
  10801. * Parse an arithmetic expansion (indicate start of one and set state)
  10802. */
  10803. parsearith: {
  10804. if (++arinest == 1) {
  10805. prevsyntax = syntax;
  10806. syntax = ARISYNTAX;
  10807. USTPUTC(CTLARI, out);
  10808. if (dblquote)
  10809. USTPUTC('"', out);
  10810. else
  10811. USTPUTC(' ', out);
  10812. } else {
  10813. /*
  10814. * we collapse embedded arithmetic expansion to
  10815. * parenthesis, which should be equivalent
  10816. */
  10817. USTPUTC('(', out);
  10818. }
  10819. goto parsearith_return;
  10820. }
  10821. #endif
  10822. } /* end of readtoken */
  10823. /*
  10824. * Read the next input token.
  10825. * If the token is a word, we set backquotelist to the list of cmds in
  10826. * backquotes. We set quoteflag to true if any part of the word was
  10827. * quoted.
  10828. * If the token is TREDIR, then we set redirnode to a structure containing
  10829. * the redirection.
  10830. * In all cases, the variable startlinno is set to the number of the line
  10831. * on which the token starts.
  10832. *
  10833. * [Change comment: here documents and internal procedures]
  10834. * [Readtoken shouldn't have any arguments. Perhaps we should make the
  10835. * word parsing code into a separate routine. In this case, readtoken
  10836. * doesn't need to have any internal procedures, but parseword does.
  10837. * We could also make parseoperator in essence the main routine, and
  10838. * have parseword (readtoken1?) handle both words and redirection.]
  10839. */
  10840. #define NEW_xxreadtoken
  10841. #ifdef NEW_xxreadtoken
  10842. /* singles must be first! */
  10843. static const char xxreadtoken_chars[7] ALIGN1 = {
  10844. '\n', '(', ')', /* singles */
  10845. '&', '|', ';', /* doubles */
  10846. 0
  10847. };
  10848. #define xxreadtoken_singles 3
  10849. #define xxreadtoken_doubles 3
  10850. static const char xxreadtoken_tokens[] ALIGN1 = {
  10851. TNL, TLP, TRP, /* only single occurrence allowed */
  10852. TBACKGND, TPIPE, TSEMI, /* if single occurrence */
  10853. TEOF, /* corresponds to trailing nul */
  10854. TAND, TOR, TENDCASE /* if double occurrence */
  10855. };
  10856. static int
  10857. xxreadtoken(void)
  10858. {
  10859. int c;
  10860. if (tokpushback) {
  10861. tokpushback = 0;
  10862. return lasttoken;
  10863. }
  10864. setprompt_if(needprompt, 2);
  10865. startlinno = g_parsefile->linno;
  10866. for (;;) { /* until token or start of word found */
  10867. c = pgetc_fast();
  10868. if (c == ' ' || c == '\t' IF_ASH_ALIAS( || c == PEOA))
  10869. continue;
  10870. if (c == '#') {
  10871. while ((c = pgetc()) != '\n' && c != PEOF)
  10872. continue;
  10873. pungetc();
  10874. } else if (c == '\\') {
  10875. if (pgetc() != '\n') {
  10876. pungetc();
  10877. break; /* return readtoken1(...) */
  10878. }
  10879. startlinno = ++g_parsefile->linno;
  10880. setprompt_if(doprompt, 2);
  10881. } else {
  10882. const char *p;
  10883. p = xxreadtoken_chars + sizeof(xxreadtoken_chars) - 1;
  10884. if (c != PEOF) {
  10885. if (c == '\n') {
  10886. g_parsefile->linno++;
  10887. needprompt = doprompt;
  10888. }
  10889. p = strchr(xxreadtoken_chars, c);
  10890. if (p == NULL)
  10891. break; /* return readtoken1(...) */
  10892. if ((int)(p - xxreadtoken_chars) >= xxreadtoken_singles) {
  10893. int cc = pgetc();
  10894. if (cc == c) { /* double occurrence? */
  10895. p += xxreadtoken_doubles + 1;
  10896. } else {
  10897. pungetc();
  10898. #if ENABLE_ASH_BASH_COMPAT
  10899. if (c == '&' && cc == '>') /* &> */
  10900. break; /* return readtoken1(...) */
  10901. #endif
  10902. }
  10903. }
  10904. }
  10905. lasttoken = xxreadtoken_tokens[p - xxreadtoken_chars];
  10906. return lasttoken;
  10907. }
  10908. } /* for (;;) */
  10909. return readtoken1(c, BASESYNTAX, (char *) NULL, 0);
  10910. }
  10911. #else /* old xxreadtoken */
  10912. #define RETURN(token) return lasttoken = token
  10913. static int
  10914. xxreadtoken(void)
  10915. {
  10916. int c;
  10917. if (tokpushback) {
  10918. tokpushback = 0;
  10919. return lasttoken;
  10920. }
  10921. setprompt_if(needprompt, 2);
  10922. startlinno = g_parsefile->linno;
  10923. for (;;) { /* until token or start of word found */
  10924. c = pgetc_fast();
  10925. switch (c) {
  10926. case ' ': case '\t':
  10927. IF_ASH_ALIAS(case PEOA:)
  10928. continue;
  10929. case '#':
  10930. while ((c = pgetc()) != '\n' && c != PEOF)
  10931. continue;
  10932. pungetc();
  10933. continue;
  10934. case '\\':
  10935. if (pgetc() == '\n') {
  10936. startlinno = ++g_parsefile->linno;
  10937. setprompt_if(doprompt, 2);
  10938. continue;
  10939. }
  10940. pungetc();
  10941. goto breakloop;
  10942. case '\n':
  10943. g_parsefile->linno++;
  10944. needprompt = doprompt;
  10945. RETURN(TNL);
  10946. case PEOF:
  10947. RETURN(TEOF);
  10948. case '&':
  10949. if (pgetc() == '&')
  10950. RETURN(TAND);
  10951. pungetc();
  10952. RETURN(TBACKGND);
  10953. case '|':
  10954. if (pgetc() == '|')
  10955. RETURN(TOR);
  10956. pungetc();
  10957. RETURN(TPIPE);
  10958. case ';':
  10959. if (pgetc() == ';')
  10960. RETURN(TENDCASE);
  10961. pungetc();
  10962. RETURN(TSEMI);
  10963. case '(':
  10964. RETURN(TLP);
  10965. case ')':
  10966. RETURN(TRP);
  10967. default:
  10968. goto breakloop;
  10969. }
  10970. }
  10971. breakloop:
  10972. return readtoken1(c, BASESYNTAX, (char *)NULL, 0);
  10973. #undef RETURN
  10974. }
  10975. #endif /* old xxreadtoken */
  10976. static int
  10977. readtoken(void)
  10978. {
  10979. int t;
  10980. #if DEBUG
  10981. smallint alreadyseen = tokpushback;
  10982. #endif
  10983. #if ENABLE_ASH_ALIAS
  10984. top:
  10985. #endif
  10986. t = xxreadtoken();
  10987. /*
  10988. * eat newlines
  10989. */
  10990. if (checkkwd & CHKNL) {
  10991. while (t == TNL) {
  10992. parseheredoc();
  10993. t = xxreadtoken();
  10994. }
  10995. }
  10996. if (t != TWORD || quoteflag) {
  10997. goto out;
  10998. }
  10999. /*
  11000. * check for keywords
  11001. */
  11002. if (checkkwd & CHKKWD) {
  11003. const char *const *pp;
  11004. pp = findkwd(wordtext);
  11005. if (pp) {
  11006. lasttoken = t = pp - tokname_array;
  11007. TRACE(("keyword '%s' recognized\n", tokname_array[t] + 1));
  11008. goto out;
  11009. }
  11010. }
  11011. if (checkkwd & CHKALIAS) {
  11012. #if ENABLE_ASH_ALIAS
  11013. struct alias *ap;
  11014. ap = lookupalias(wordtext, 1);
  11015. if (ap != NULL) {
  11016. if (*ap->val) {
  11017. pushstring(ap->val, ap);
  11018. }
  11019. goto top;
  11020. }
  11021. #endif
  11022. }
  11023. out:
  11024. checkkwd = 0;
  11025. #if DEBUG
  11026. if (!alreadyseen)
  11027. TRACE(("token '%s' %s\n", tokname_array[t] + 1, t == TWORD ? wordtext : ""));
  11028. else
  11029. TRACE(("reread token '%s' %s\n", tokname_array[t] + 1, t == TWORD ? wordtext : ""));
  11030. #endif
  11031. return t;
  11032. }
  11033. static char
  11034. peektoken(void)
  11035. {
  11036. int t;
  11037. t = readtoken();
  11038. tokpushback = 1;
  11039. return tokname_array[t][0];
  11040. }
  11041. /*
  11042. * Read and parse a command. Returns NODE_EOF on end of file.
  11043. * (NULL is a valid parse tree indicating a blank line.)
  11044. */
  11045. static union node *
  11046. parsecmd(int interact)
  11047. {
  11048. int t;
  11049. tokpushback = 0;
  11050. doprompt = interact;
  11051. setprompt_if(doprompt, doprompt);
  11052. needprompt = 0;
  11053. t = readtoken();
  11054. if (t == TEOF)
  11055. return NODE_EOF;
  11056. if (t == TNL)
  11057. return NULL;
  11058. tokpushback = 1;
  11059. return list(1);
  11060. }
  11061. /*
  11062. * Input any here documents.
  11063. */
  11064. static void
  11065. parseheredoc(void)
  11066. {
  11067. struct heredoc *here;
  11068. union node *n;
  11069. here = heredoclist;
  11070. heredoclist = NULL;
  11071. while (here) {
  11072. setprompt_if(needprompt, 2);
  11073. readtoken1(pgetc(), here->here->type == NHERE ? SQSYNTAX : DQSYNTAX,
  11074. here->eofmark, here->striptabs);
  11075. n = stzalloc(sizeof(struct narg));
  11076. n->narg.type = NARG;
  11077. /*n->narg.next = NULL; - stzalloc did it */
  11078. n->narg.text = wordtext;
  11079. n->narg.backquote = backquotelist;
  11080. here->here->nhere.doc = n;
  11081. here = here->next;
  11082. }
  11083. }
  11084. /*
  11085. * called by editline -- any expansions to the prompt should be added here.
  11086. */
  11087. #if ENABLE_ASH_EXPAND_PRMT
  11088. static const char *
  11089. expandstr(const char *ps)
  11090. {
  11091. union node n;
  11092. /* XXX Fix (char *) cast. It _is_ a bug. ps is variable's value,
  11093. * and token processing _can_ alter it (delete NULs etc). */
  11094. setinputstring((char *)ps);
  11095. readtoken1(pgetc(), PSSYNTAX, nullstr, 0);
  11096. popfile();
  11097. n.narg.type = NARG;
  11098. n.narg.next = NULL;
  11099. n.narg.text = wordtext;
  11100. n.narg.backquote = backquotelist;
  11101. expandarg(&n, NULL, 0);
  11102. return stackblock();
  11103. }
  11104. #endif
  11105. /*
  11106. * Execute a command or commands contained in a string.
  11107. */
  11108. static int
  11109. evalstring(char *s, int mask)
  11110. {
  11111. union node *n;
  11112. struct stackmark smark;
  11113. int skip;
  11114. setinputstring(s);
  11115. setstackmark(&smark);
  11116. skip = 0;
  11117. while ((n = parsecmd(0)) != NODE_EOF) {
  11118. evaltree(n, 0);
  11119. popstackmark(&smark);
  11120. skip = evalskip;
  11121. if (skip)
  11122. break;
  11123. }
  11124. popfile();
  11125. skip &= mask;
  11126. evalskip = skip;
  11127. return skip;
  11128. }
  11129. /*
  11130. * The eval command.
  11131. */
  11132. static int FAST_FUNC
  11133. evalcmd(int argc UNUSED_PARAM, char **argv)
  11134. {
  11135. char *p;
  11136. char *concat;
  11137. if (argv[1]) {
  11138. p = argv[1];
  11139. argv += 2;
  11140. if (argv[0]) {
  11141. STARTSTACKSTR(concat);
  11142. for (;;) {
  11143. concat = stack_putstr(p, concat);
  11144. p = *argv++;
  11145. if (p == NULL)
  11146. break;
  11147. STPUTC(' ', concat);
  11148. }
  11149. STPUTC('\0', concat);
  11150. p = grabstackstr(concat);
  11151. }
  11152. evalstring(p, ~SKIPEVAL);
  11153. }
  11154. return exitstatus;
  11155. }
  11156. /*
  11157. * Read and execute commands.
  11158. * "Top" is nonzero for the top level command loop;
  11159. * it turns on prompting if the shell is interactive.
  11160. */
  11161. static int
  11162. cmdloop(int top)
  11163. {
  11164. union node *n;
  11165. struct stackmark smark;
  11166. int inter;
  11167. int numeof = 0;
  11168. TRACE(("cmdloop(%d) called\n", top));
  11169. for (;;) {
  11170. int skip;
  11171. setstackmark(&smark);
  11172. #if JOBS
  11173. if (doing_jobctl)
  11174. showjobs(stderr, SHOW_CHANGED);
  11175. #endif
  11176. inter = 0;
  11177. if (iflag && top) {
  11178. inter++;
  11179. chkmail();
  11180. }
  11181. n = parsecmd(inter);
  11182. #if DEBUG
  11183. if (DEBUG > 2 && debug && (n != NODE_EOF))
  11184. showtree(n);
  11185. #endif
  11186. if (n == NODE_EOF) {
  11187. if (!top || numeof >= 50)
  11188. break;
  11189. if (!stoppedjobs()) {
  11190. if (!Iflag)
  11191. break;
  11192. out2str("\nUse \"exit\" to leave shell.\n");
  11193. }
  11194. numeof++;
  11195. } else if (nflag == 0) {
  11196. /* job_warning can only be 2,1,0. Here 2->1, 1/0->0 */
  11197. job_warning >>= 1;
  11198. numeof = 0;
  11199. evaltree(n, 0);
  11200. }
  11201. popstackmark(&smark);
  11202. skip = evalskip;
  11203. if (skip) {
  11204. evalskip = 0;
  11205. return skip & SKIPEVAL;
  11206. }
  11207. }
  11208. return 0;
  11209. }
  11210. /*
  11211. * Take commands from a file. To be compatible we should do a path
  11212. * search for the file, which is necessary to find sub-commands.
  11213. */
  11214. static char *
  11215. find_dot_file(char *name)
  11216. {
  11217. char *fullname;
  11218. const char *path = pathval();
  11219. struct stat statb;
  11220. /* don't try this for absolute or relative paths */
  11221. if (strchr(name, '/'))
  11222. return name;
  11223. /* IIRC standards do not say whether . is to be searched.
  11224. * And it is even smaller this way, making it unconditional for now:
  11225. */
  11226. if (1) { /* ENABLE_ASH_BASH_COMPAT */
  11227. fullname = name;
  11228. goto try_cur_dir;
  11229. }
  11230. while ((fullname = path_advance(&path, name)) != NULL) {
  11231. try_cur_dir:
  11232. if ((stat(fullname, &statb) == 0) && S_ISREG(statb.st_mode)) {
  11233. /*
  11234. * Don't bother freeing here, since it will
  11235. * be freed by the caller.
  11236. */
  11237. return fullname;
  11238. }
  11239. if (fullname != name)
  11240. stunalloc(fullname);
  11241. }
  11242. /* not found in the PATH */
  11243. ash_msg_and_raise_error("%s: not found", name);
  11244. /* NOTREACHED */
  11245. }
  11246. static int FAST_FUNC
  11247. dotcmd(int argc, char **argv)
  11248. {
  11249. char *fullname;
  11250. struct strlist *sp;
  11251. volatile struct shparam saveparam;
  11252. for (sp = cmdenviron; sp; sp = sp->next)
  11253. setvareq(ckstrdup(sp->text), VSTRFIXED | VTEXTFIXED);
  11254. if (!argv[1]) {
  11255. /* bash says: "bash: .: filename argument required" */
  11256. return 2; /* bash compat */
  11257. }
  11258. /* "false; . empty_file; echo $?" should print 0, not 1: */
  11259. exitstatus = 0;
  11260. /* This aborts if file isn't found, which is POSIXly correct.
  11261. * bash returns exitcode 1 instead.
  11262. */
  11263. fullname = find_dot_file(argv[1]);
  11264. argv += 2;
  11265. argc -= 2;
  11266. if (argc) { /* argc > 0, argv[0] != NULL */
  11267. saveparam = shellparam;
  11268. shellparam.malloced = 0;
  11269. shellparam.nparam = argc;
  11270. shellparam.p = argv;
  11271. };
  11272. /* This aborts if file can't be opened, which is POSIXly correct.
  11273. * bash returns exitcode 1 instead.
  11274. */
  11275. setinputfile(fullname, INPUT_PUSH_FILE);
  11276. commandname = fullname;
  11277. cmdloop(0);
  11278. popfile();
  11279. if (argc) {
  11280. freeparam(&shellparam);
  11281. shellparam = saveparam;
  11282. };
  11283. return exitstatus;
  11284. }
  11285. static int FAST_FUNC
  11286. exitcmd(int argc UNUSED_PARAM, char **argv)
  11287. {
  11288. if (stoppedjobs())
  11289. return 0;
  11290. if (argv[1])
  11291. exitstatus = number(argv[1]);
  11292. raise_exception(EXEXIT);
  11293. /* NOTREACHED */
  11294. }
  11295. /*
  11296. * Read a file containing shell functions.
  11297. */
  11298. static void
  11299. readcmdfile(char *name)
  11300. {
  11301. setinputfile(name, INPUT_PUSH_FILE);
  11302. cmdloop(0);
  11303. popfile();
  11304. }
  11305. /* ============ find_command inplementation */
  11306. /*
  11307. * Resolve a command name. If you change this routine, you may have to
  11308. * change the shellexec routine as well.
  11309. */
  11310. static void
  11311. find_command(char *name, struct cmdentry *entry, int act, const char *path)
  11312. {
  11313. struct tblentry *cmdp;
  11314. int idx;
  11315. int prev;
  11316. char *fullname;
  11317. struct stat statb;
  11318. int e;
  11319. int updatetbl;
  11320. struct builtincmd *bcmd;
  11321. /* If name contains a slash, don't use PATH or hash table */
  11322. if (strchr(name, '/') != NULL) {
  11323. entry->u.index = -1;
  11324. if (act & DO_ABS) {
  11325. while (stat(name, &statb) < 0) {
  11326. #ifdef SYSV
  11327. if (errno == EINTR)
  11328. continue;
  11329. #endif
  11330. entry->cmdtype = CMDUNKNOWN;
  11331. return;
  11332. }
  11333. }
  11334. entry->cmdtype = CMDNORMAL;
  11335. return;
  11336. }
  11337. /* #if ENABLE_FEATURE_SH_STANDALONE... moved after builtin check */
  11338. updatetbl = (path == pathval());
  11339. if (!updatetbl) {
  11340. act |= DO_ALTPATH;
  11341. if (strstr(path, "%builtin") != NULL)
  11342. act |= DO_ALTBLTIN;
  11343. }
  11344. /* If name is in the table, check answer will be ok */
  11345. cmdp = cmdlookup(name, 0);
  11346. if (cmdp != NULL) {
  11347. int bit;
  11348. switch (cmdp->cmdtype) {
  11349. default:
  11350. #if DEBUG
  11351. abort();
  11352. #endif
  11353. case CMDNORMAL:
  11354. bit = DO_ALTPATH;
  11355. break;
  11356. case CMDFUNCTION:
  11357. bit = DO_NOFUNC;
  11358. break;
  11359. case CMDBUILTIN:
  11360. bit = DO_ALTBLTIN;
  11361. break;
  11362. }
  11363. if (act & bit) {
  11364. updatetbl = 0;
  11365. cmdp = NULL;
  11366. } else if (cmdp->rehash == 0)
  11367. /* if not invalidated by cd, we're done */
  11368. goto success;
  11369. }
  11370. /* If %builtin not in path, check for builtin next */
  11371. bcmd = find_builtin(name);
  11372. if (bcmd) {
  11373. if (IS_BUILTIN_REGULAR(bcmd))
  11374. goto builtin_success;
  11375. if (act & DO_ALTPATH) {
  11376. if (!(act & DO_ALTBLTIN))
  11377. goto builtin_success;
  11378. } else if (builtinloc <= 0) {
  11379. goto builtin_success;
  11380. }
  11381. }
  11382. #if ENABLE_FEATURE_SH_STANDALONE
  11383. {
  11384. int applet_no = find_applet_by_name(name);
  11385. if (applet_no >= 0) {
  11386. entry->cmdtype = CMDNORMAL;
  11387. entry->u.index = -2 - applet_no;
  11388. return;
  11389. }
  11390. }
  11391. #endif
  11392. /* We have to search path. */
  11393. prev = -1; /* where to start */
  11394. if (cmdp && cmdp->rehash) { /* doing a rehash */
  11395. if (cmdp->cmdtype == CMDBUILTIN)
  11396. prev = builtinloc;
  11397. else
  11398. prev = cmdp->param.index;
  11399. }
  11400. e = ENOENT;
  11401. idx = -1;
  11402. loop:
  11403. while ((fullname = path_advance(&path, name)) != NULL) {
  11404. stunalloc(fullname);
  11405. /* NB: code below will still use fullname
  11406. * despite it being "unallocated" */
  11407. idx++;
  11408. if (pathopt) {
  11409. if (prefix(pathopt, "builtin")) {
  11410. if (bcmd)
  11411. goto builtin_success;
  11412. continue;
  11413. }
  11414. if ((act & DO_NOFUNC)
  11415. || !prefix(pathopt, "func")
  11416. ) { /* ignore unimplemented options */
  11417. continue;
  11418. }
  11419. }
  11420. /* if rehash, don't redo absolute path names */
  11421. if (fullname[0] == '/' && idx <= prev) {
  11422. if (idx < prev)
  11423. continue;
  11424. TRACE(("searchexec \"%s\": no change\n", name));
  11425. goto success;
  11426. }
  11427. while (stat(fullname, &statb) < 0) {
  11428. #ifdef SYSV
  11429. if (errno == EINTR)
  11430. continue;
  11431. #endif
  11432. if (errno != ENOENT && errno != ENOTDIR)
  11433. e = errno;
  11434. goto loop;
  11435. }
  11436. e = EACCES; /* if we fail, this will be the error */
  11437. if (!S_ISREG(statb.st_mode))
  11438. continue;
  11439. if (pathopt) { /* this is a %func directory */
  11440. stalloc(strlen(fullname) + 1);
  11441. /* NB: stalloc will return space pointed by fullname
  11442. * (because we don't have any intervening allocations
  11443. * between stunalloc above and this stalloc) */
  11444. readcmdfile(fullname);
  11445. cmdp = cmdlookup(name, 0);
  11446. if (cmdp == NULL || cmdp->cmdtype != CMDFUNCTION)
  11447. ash_msg_and_raise_error("%s not defined in %s", name, fullname);
  11448. stunalloc(fullname);
  11449. goto success;
  11450. }
  11451. TRACE(("searchexec \"%s\" returns \"%s\"\n", name, fullname));
  11452. if (!updatetbl) {
  11453. entry->cmdtype = CMDNORMAL;
  11454. entry->u.index = idx;
  11455. return;
  11456. }
  11457. INT_OFF;
  11458. cmdp = cmdlookup(name, 1);
  11459. cmdp->cmdtype = CMDNORMAL;
  11460. cmdp->param.index = idx;
  11461. INT_ON;
  11462. goto success;
  11463. }
  11464. /* We failed. If there was an entry for this command, delete it */
  11465. if (cmdp && updatetbl)
  11466. delete_cmd_entry();
  11467. if (act & DO_ERR)
  11468. ash_msg("%s: %s", name, errmsg(e, "not found"));
  11469. entry->cmdtype = CMDUNKNOWN;
  11470. return;
  11471. builtin_success:
  11472. if (!updatetbl) {
  11473. entry->cmdtype = CMDBUILTIN;
  11474. entry->u.cmd = bcmd;
  11475. return;
  11476. }
  11477. INT_OFF;
  11478. cmdp = cmdlookup(name, 1);
  11479. cmdp->cmdtype = CMDBUILTIN;
  11480. cmdp->param.cmd = bcmd;
  11481. INT_ON;
  11482. success:
  11483. cmdp->rehash = 0;
  11484. entry->cmdtype = cmdp->cmdtype;
  11485. entry->u = cmdp->param;
  11486. }
  11487. /* ============ trap.c */
  11488. /*
  11489. * The trap builtin.
  11490. */
  11491. static int FAST_FUNC
  11492. trapcmd(int argc UNUSED_PARAM, char **argv UNUSED_PARAM)
  11493. {
  11494. char *action;
  11495. char **ap;
  11496. int signo, exitcode;
  11497. nextopt(nullstr);
  11498. ap = argptr;
  11499. if (!*ap) {
  11500. for (signo = 0; signo < NSIG; signo++) {
  11501. char *tr = trap_ptr[signo];
  11502. if (tr) {
  11503. /* note: bash adds "SIG", but only if invoked
  11504. * as "bash". If called as "sh", or if set -o posix,
  11505. * then it prints short signal names.
  11506. * We are printing short names: */
  11507. out1fmt("trap -- %s %s\n",
  11508. single_quote(tr),
  11509. get_signame(signo));
  11510. /* trap_ptr != trap only if we are in special-cased `trap` code.
  11511. * In this case, we will exit very soon, no need to free(). */
  11512. /* if (trap_ptr != trap && tp[0]) */
  11513. /* free(tr); */
  11514. }
  11515. }
  11516. /*
  11517. if (trap_ptr != trap) {
  11518. free(trap_ptr);
  11519. trap_ptr = trap;
  11520. }
  11521. */
  11522. return 0;
  11523. }
  11524. action = NULL;
  11525. if (ap[1])
  11526. action = *ap++;
  11527. exitcode = 0;
  11528. while (*ap) {
  11529. signo = get_signum(*ap);
  11530. if (signo < 0) {
  11531. /* Mimic bash message exactly */
  11532. ash_msg("%s: invalid signal specification", *ap);
  11533. exitcode = 1;
  11534. goto next;
  11535. }
  11536. INT_OFF;
  11537. if (action) {
  11538. if (LONE_DASH(action))
  11539. action = NULL;
  11540. else
  11541. action = ckstrdup(action);
  11542. }
  11543. free(trap[signo]);
  11544. if (action)
  11545. may_have_traps = 1;
  11546. trap[signo] = action;
  11547. if (signo != 0)
  11548. setsignal(signo);
  11549. INT_ON;
  11550. next:
  11551. ap++;
  11552. }
  11553. return exitcode;
  11554. }
  11555. /* ============ Builtins */
  11556. #if !ENABLE_FEATURE_SH_EXTRA_QUIET
  11557. /*
  11558. * Lists available builtins
  11559. */
  11560. static int FAST_FUNC
  11561. helpcmd(int argc UNUSED_PARAM, char **argv UNUSED_PARAM)
  11562. {
  11563. unsigned col;
  11564. unsigned i;
  11565. out1fmt(
  11566. "Built-in commands:\n"
  11567. "------------------\n");
  11568. for (col = 0, i = 0; i < ARRAY_SIZE(builtintab); i++) {
  11569. col += out1fmt("%c%s", ((col == 0) ? '\t' : ' '),
  11570. builtintab[i].name + 1);
  11571. if (col > 60) {
  11572. out1fmt("\n");
  11573. col = 0;
  11574. }
  11575. }
  11576. #if ENABLE_FEATURE_SH_STANDALONE
  11577. {
  11578. const char *a = applet_names;
  11579. while (*a) {
  11580. col += out1fmt("%c%s", ((col == 0) ? '\t' : ' '), a);
  11581. if (col > 60) {
  11582. out1fmt("\n");
  11583. col = 0;
  11584. }
  11585. a += strlen(a) + 1;
  11586. }
  11587. }
  11588. #endif
  11589. out1fmt("\n\n");
  11590. return EXIT_SUCCESS;
  11591. }
  11592. #endif /* FEATURE_SH_EXTRA_QUIET */
  11593. #if MAX_HISTORY
  11594. static int FAST_FUNC
  11595. historycmd(int argc UNUSED_PARAM, char **argv UNUSED_PARAM)
  11596. {
  11597. show_history(line_input_state);
  11598. return EXIT_SUCCESS;
  11599. }
  11600. #endif
  11601. /*
  11602. * The export and readonly commands.
  11603. */
  11604. static int FAST_FUNC
  11605. exportcmd(int argc UNUSED_PARAM, char **argv)
  11606. {
  11607. struct var *vp;
  11608. char *name;
  11609. const char *p;
  11610. char **aptr;
  11611. char opt;
  11612. int flag;
  11613. int flag_off;
  11614. /* "readonly" in bash accepts, but ignores -n.
  11615. * We do the same: it saves a conditional in nextopt's param.
  11616. */
  11617. flag_off = 0;
  11618. while ((opt = nextopt("np")) != '\0') {
  11619. if (opt == 'n')
  11620. flag_off = VEXPORT;
  11621. }
  11622. flag = VEXPORT;
  11623. if (argv[0][0] == 'r') {
  11624. flag = VREADONLY;
  11625. flag_off = 0; /* readonly ignores -n */
  11626. }
  11627. flag_off = ~flag_off;
  11628. /*if (opt_p_not_specified) - bash doesnt check this. Try "export -p NAME" */
  11629. {
  11630. aptr = argptr;
  11631. name = *aptr;
  11632. if (name) {
  11633. do {
  11634. p = strchr(name, '=');
  11635. if (p != NULL) {
  11636. p++;
  11637. } else {
  11638. vp = *findvar(hashvar(name), name);
  11639. if (vp) {
  11640. vp->flags = ((vp->flags | flag) & flag_off);
  11641. continue;
  11642. }
  11643. }
  11644. setvar(name, p, (flag & flag_off));
  11645. } while ((name = *++aptr) != NULL);
  11646. return 0;
  11647. }
  11648. }
  11649. /* No arguments. Show the list of exported or readonly vars.
  11650. * -n is ignored.
  11651. */
  11652. showvars(argv[0], flag, 0);
  11653. return 0;
  11654. }
  11655. /*
  11656. * Delete a function if it exists.
  11657. */
  11658. static void
  11659. unsetfunc(const char *name)
  11660. {
  11661. struct tblentry *cmdp;
  11662. cmdp = cmdlookup(name, 0);
  11663. if (cmdp != NULL && cmdp->cmdtype == CMDFUNCTION)
  11664. delete_cmd_entry();
  11665. }
  11666. /*
  11667. * The unset builtin command. We unset the function before we unset the
  11668. * variable to allow a function to be unset when there is a readonly variable
  11669. * with the same name.
  11670. */
  11671. static int FAST_FUNC
  11672. unsetcmd(int argc UNUSED_PARAM, char **argv UNUSED_PARAM)
  11673. {
  11674. char **ap;
  11675. int i;
  11676. int flag = 0;
  11677. int ret = 0;
  11678. while ((i = nextopt("vf")) != 0) {
  11679. flag = i;
  11680. }
  11681. for (ap = argptr; *ap; ap++) {
  11682. if (flag != 'f') {
  11683. i = unsetvar(*ap);
  11684. ret |= i;
  11685. if (!(i & 2))
  11686. continue;
  11687. }
  11688. if (flag != 'v')
  11689. unsetfunc(*ap);
  11690. }
  11691. return ret & 1;
  11692. }
  11693. static const unsigned char timescmd_str[] ALIGN1 = {
  11694. ' ', offsetof(struct tms, tms_utime),
  11695. '\n', offsetof(struct tms, tms_stime),
  11696. ' ', offsetof(struct tms, tms_cutime),
  11697. '\n', offsetof(struct tms, tms_cstime),
  11698. 0
  11699. };
  11700. static int FAST_FUNC
  11701. timescmd(int argc UNUSED_PARAM, char **argv UNUSED_PARAM)
  11702. {
  11703. unsigned long clk_tck, s, t;
  11704. const unsigned char *p;
  11705. struct tms buf;
  11706. clk_tck = sysconf(_SC_CLK_TCK);
  11707. times(&buf);
  11708. p = timescmd_str;
  11709. do {
  11710. t = *(clock_t *)(((char *) &buf) + p[1]);
  11711. s = t / clk_tck;
  11712. t = t % clk_tck;
  11713. out1fmt("%lum%lu.%03lus%c",
  11714. s / 60, s % 60,
  11715. (t * 1000) / clk_tck,
  11716. p[0]);
  11717. p += 2;
  11718. } while (*p);
  11719. return 0;
  11720. }
  11721. #if ENABLE_SH_MATH_SUPPORT
  11722. /*
  11723. * The let builtin. Partially stolen from GNU Bash, the Bourne Again SHell.
  11724. * Copyright (C) 1987, 1989, 1991 Free Software Foundation, Inc.
  11725. *
  11726. * Copyright (C) 2003 Vladimir Oleynik <dzo@simtreas.ru>
  11727. */
  11728. static int FAST_FUNC
  11729. letcmd(int argc UNUSED_PARAM, char **argv)
  11730. {
  11731. arith_t i;
  11732. argv++;
  11733. if (!*argv)
  11734. ash_msg_and_raise_error("expression expected");
  11735. do {
  11736. i = ash_arith(*argv);
  11737. } while (*++argv);
  11738. return !i;
  11739. }
  11740. #endif
  11741. /*
  11742. * The read builtin. Options:
  11743. * -r Do not interpret '\' specially
  11744. * -s Turn off echo (tty only)
  11745. * -n NCHARS Read NCHARS max
  11746. * -p PROMPT Display PROMPT on stderr (if input is from tty)
  11747. * -t SECONDS Timeout after SECONDS (tty or pipe only)
  11748. * -u FD Read from given FD instead of fd 0
  11749. * This uses unbuffered input, which may be avoidable in some cases.
  11750. * TODO: bash also has:
  11751. * -a ARRAY Read into array[0],[1],etc
  11752. * -d DELIM End on DELIM char, not newline
  11753. * -e Use line editing (tty only)
  11754. */
  11755. static int FAST_FUNC
  11756. readcmd(int argc UNUSED_PARAM, char **argv UNUSED_PARAM)
  11757. {
  11758. char *opt_n = NULL;
  11759. char *opt_p = NULL;
  11760. char *opt_t = NULL;
  11761. char *opt_u = NULL;
  11762. int read_flags = 0;
  11763. const char *r;
  11764. int i;
  11765. while ((i = nextopt("p:u:rt:n:s")) != '\0') {
  11766. switch (i) {
  11767. case 'p':
  11768. opt_p = optionarg;
  11769. break;
  11770. case 'n':
  11771. opt_n = optionarg;
  11772. break;
  11773. case 's':
  11774. read_flags |= BUILTIN_READ_SILENT;
  11775. break;
  11776. case 't':
  11777. opt_t = optionarg;
  11778. break;
  11779. case 'r':
  11780. read_flags |= BUILTIN_READ_RAW;
  11781. break;
  11782. case 'u':
  11783. opt_u = optionarg;
  11784. break;
  11785. default:
  11786. break;
  11787. }
  11788. }
  11789. /* "read -s" needs to save/restore termios, can't allow ^C
  11790. * to jump out of it.
  11791. */
  11792. INT_OFF;
  11793. r = shell_builtin_read(setvar2,
  11794. argptr,
  11795. bltinlookup("IFS"), /* can be NULL */
  11796. read_flags,
  11797. opt_n,
  11798. opt_p,
  11799. opt_t,
  11800. opt_u
  11801. );
  11802. INT_ON;
  11803. if ((uintptr_t)r > 1)
  11804. ash_msg_and_raise_error(r);
  11805. return (uintptr_t)r;
  11806. }
  11807. static int FAST_FUNC
  11808. umaskcmd(int argc UNUSED_PARAM, char **argv)
  11809. {
  11810. static const char permuser[3] ALIGN1 = "ugo";
  11811. static const char permmode[3] ALIGN1 = "rwx";
  11812. static const short permmask[] ALIGN2 = {
  11813. S_IRUSR, S_IWUSR, S_IXUSR,
  11814. S_IRGRP, S_IWGRP, S_IXGRP,
  11815. S_IROTH, S_IWOTH, S_IXOTH
  11816. };
  11817. /* TODO: use bb_parse_mode() instead */
  11818. char *ap;
  11819. mode_t mask;
  11820. int i;
  11821. int symbolic_mode = 0;
  11822. while (nextopt("S") != '\0') {
  11823. symbolic_mode = 1;
  11824. }
  11825. INT_OFF;
  11826. mask = umask(0);
  11827. umask(mask);
  11828. INT_ON;
  11829. ap = *argptr;
  11830. if (ap == NULL) {
  11831. if (symbolic_mode) {
  11832. char buf[18];
  11833. char *p = buf;
  11834. for (i = 0; i < 3; i++) {
  11835. int j;
  11836. *p++ = permuser[i];
  11837. *p++ = '=';
  11838. for (j = 0; j < 3; j++) {
  11839. if ((mask & permmask[3 * i + j]) == 0) {
  11840. *p++ = permmode[j];
  11841. }
  11842. }
  11843. *p++ = ',';
  11844. }
  11845. *--p = 0;
  11846. puts(buf);
  11847. } else {
  11848. out1fmt("%.4o\n", mask);
  11849. }
  11850. } else {
  11851. if (isdigit((unsigned char) *ap)) {
  11852. mask = 0;
  11853. do {
  11854. if (*ap >= '8' || *ap < '0')
  11855. ash_msg_and_raise_error(msg_illnum, argv[1]);
  11856. mask = (mask << 3) + (*ap - '0');
  11857. } while (*++ap != '\0');
  11858. umask(mask);
  11859. } else {
  11860. mask = ~mask & 0777;
  11861. if (!bb_parse_mode(ap, &mask)) {
  11862. ash_msg_and_raise_error("illegal mode: %s", ap);
  11863. }
  11864. umask(~mask & 0777);
  11865. }
  11866. }
  11867. return 0;
  11868. }
  11869. static int FAST_FUNC
  11870. ulimitcmd(int argc UNUSED_PARAM, char **argv)
  11871. {
  11872. return shell_builtin_ulimit(argv);
  11873. }
  11874. /* ============ main() and helpers */
  11875. /*
  11876. * Called to exit the shell.
  11877. */
  11878. static void
  11879. exitshell(void)
  11880. {
  11881. struct jmploc loc;
  11882. char *p;
  11883. int status;
  11884. #if ENABLE_FEATURE_EDITING_SAVE_ON_EXIT
  11885. save_history(line_input_state);
  11886. #endif
  11887. status = exitstatus;
  11888. TRACE(("pid %d, exitshell(%d)\n", getpid(), status));
  11889. if (setjmp(loc.loc)) {
  11890. if (exception_type == EXEXIT)
  11891. /* dash bug: it just does _exit(exitstatus) here
  11892. * but we have to do setjobctl(0) first!
  11893. * (bug is still not fixed in dash-0.5.3 - if you run dash
  11894. * under Midnight Commander, on exit from dash MC is backgrounded) */
  11895. status = exitstatus;
  11896. goto out;
  11897. }
  11898. exception_handler = &loc;
  11899. p = trap[0];
  11900. if (p) {
  11901. trap[0] = NULL;
  11902. evalstring(p, 0);
  11903. free(p);
  11904. }
  11905. flush_stdout_stderr();
  11906. out:
  11907. setjobctl(0);
  11908. _exit(status);
  11909. /* NOTREACHED */
  11910. }
  11911. static void
  11912. init(void)
  11913. {
  11914. /* from input.c: */
  11915. /* we will never free this */
  11916. basepf.next_to_pgetc = basepf.buf = ckmalloc(IBUFSIZ);
  11917. /* from trap.c: */
  11918. signal(SIGCHLD, SIG_DFL);
  11919. /* bash re-enables SIGHUP which is SIG_IGNed on entry.
  11920. * Try: "trap '' HUP; bash; echo RET" and type "kill -HUP $$"
  11921. */
  11922. signal(SIGHUP, SIG_DFL);
  11923. /* from var.c: */
  11924. {
  11925. char **envp;
  11926. const char *p;
  11927. struct stat st1, st2;
  11928. initvar();
  11929. for (envp = environ; envp && *envp; envp++) {
  11930. if (strchr(*envp, '=')) {
  11931. setvareq(*envp, VEXPORT|VTEXTFIXED);
  11932. }
  11933. }
  11934. setvar2("PPID", utoa(getppid()));
  11935. #if ENABLE_ASH_BASH_COMPAT
  11936. p = lookupvar("SHLVL");
  11937. setvar2("SHLVL", utoa(p ? atoi(p) + 1 : 1));
  11938. #endif
  11939. p = lookupvar("PWD");
  11940. if (p) {
  11941. if (*p != '/' || stat(p, &st1) || stat(".", &st2)
  11942. || st1.st_dev != st2.st_dev || st1.st_ino != st2.st_ino
  11943. ) {
  11944. p = '\0';
  11945. }
  11946. }
  11947. setpwd(p, 0);
  11948. }
  11949. }
  11950. //usage:#define ash_trivial_usage
  11951. //usage: "[-/+OPTIONS] [-/+o OPT]... [-c 'SCRIPT' [ARG0 [ARGS]] / FILE [ARGS]]"
  11952. //usage:#define ash_full_usage "\n\n"
  11953. //usage: "Unix shell interpreter"
  11954. //usage:#if ENABLE_FEATURE_SH_IS_ASH
  11955. //usage:# define sh_trivial_usage ash_trivial_usage
  11956. //usage:# define sh_full_usage ash_full_usage
  11957. //usage:#endif
  11958. //usage:#if ENABLE_FEATURE_BASH_IS_ASH
  11959. //usage:# define bash_trivial_usage ash_trivial_usage
  11960. //usage:# define bash_full_usage ash_full_usage
  11961. //usage:#endif
  11962. /*
  11963. * Process the shell command line arguments.
  11964. */
  11965. static void
  11966. procargs(char **argv)
  11967. {
  11968. int i;
  11969. const char *xminusc;
  11970. char **xargv;
  11971. xargv = argv;
  11972. arg0 = xargv[0];
  11973. /* if (xargv[0]) - mmm, this is always true! */
  11974. xargv++;
  11975. for (i = 0; i < NOPTS; i++)
  11976. optlist[i] = 2;
  11977. argptr = xargv;
  11978. if (options(/*cmdline:*/ 1)) {
  11979. /* it already printed err message */
  11980. raise_exception(EXERROR);
  11981. }
  11982. xargv = argptr;
  11983. xminusc = minusc;
  11984. if (*xargv == NULL) {
  11985. if (xminusc)
  11986. ash_msg_and_raise_error(bb_msg_requires_arg, "-c");
  11987. sflag = 1;
  11988. }
  11989. if (iflag == 2 && sflag == 1 && isatty(0) && isatty(1))
  11990. iflag = 1;
  11991. if (mflag == 2)
  11992. mflag = iflag;
  11993. for (i = 0; i < NOPTS; i++)
  11994. if (optlist[i] == 2)
  11995. optlist[i] = 0;
  11996. #if DEBUG == 2
  11997. debug = 1;
  11998. #endif
  11999. /* POSIX 1003.2: first arg after -c cmd is $0, remainder $1... */
  12000. if (xminusc) {
  12001. minusc = *xargv++;
  12002. if (*xargv)
  12003. goto setarg0;
  12004. } else if (!sflag) {
  12005. setinputfile(*xargv, 0);
  12006. setarg0:
  12007. arg0 = *xargv++;
  12008. commandname = arg0;
  12009. }
  12010. shellparam.p = xargv;
  12011. #if ENABLE_ASH_GETOPTS
  12012. shellparam.optind = 1;
  12013. shellparam.optoff = -1;
  12014. #endif
  12015. /* assert(shellparam.malloced == 0 && shellparam.nparam == 0); */
  12016. while (*xargv) {
  12017. shellparam.nparam++;
  12018. xargv++;
  12019. }
  12020. optschanged();
  12021. }
  12022. /*
  12023. * Read /etc/profile or .profile.
  12024. */
  12025. static void
  12026. read_profile(const char *name)
  12027. {
  12028. int skip;
  12029. if (setinputfile(name, INPUT_PUSH_FILE | INPUT_NOFILE_OK) < 0)
  12030. return;
  12031. skip = cmdloop(0);
  12032. popfile();
  12033. if (skip)
  12034. exitshell();
  12035. }
  12036. /*
  12037. * This routine is called when an error or an interrupt occurs in an
  12038. * interactive shell and control is returned to the main command loop.
  12039. */
  12040. static void
  12041. reset(void)
  12042. {
  12043. /* from eval.c: */
  12044. evalskip = 0;
  12045. loopnest = 0;
  12046. /* from input.c: */
  12047. g_parsefile->left_in_buffer = 0;
  12048. g_parsefile->left_in_line = 0; /* clear input buffer */
  12049. popallfiles();
  12050. /* from parser.c: */
  12051. tokpushback = 0;
  12052. checkkwd = 0;
  12053. /* from redir.c: */
  12054. clearredir(/*drop:*/ 0);
  12055. }
  12056. #if PROFILE
  12057. static short profile_buf[16384];
  12058. extern int etext();
  12059. #endif
  12060. /*
  12061. * Main routine. We initialize things, parse the arguments, execute
  12062. * profiles if we're a login shell, and then call cmdloop to execute
  12063. * commands. The setjmp call sets up the location to jump to when an
  12064. * exception occurs. When an exception occurs the variable "state"
  12065. * is used to figure out how far we had gotten.
  12066. */
  12067. int ash_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
  12068. int ash_main(int argc UNUSED_PARAM, char **argv)
  12069. {
  12070. const char *shinit;
  12071. volatile smallint state;
  12072. struct jmploc jmploc;
  12073. struct stackmark smark;
  12074. /* Initialize global data */
  12075. INIT_G_misc();
  12076. INIT_G_memstack();
  12077. INIT_G_var();
  12078. #if ENABLE_ASH_ALIAS
  12079. INIT_G_alias();
  12080. #endif
  12081. INIT_G_cmdtable();
  12082. #if PROFILE
  12083. monitor(4, etext, profile_buf, sizeof(profile_buf), 50);
  12084. #endif
  12085. #if ENABLE_FEATURE_EDITING
  12086. line_input_state = new_line_input_t(FOR_SHELL | WITH_PATH_LOOKUP);
  12087. #endif
  12088. state = 0;
  12089. if (setjmp(jmploc.loc)) {
  12090. smallint e;
  12091. smallint s;
  12092. reset();
  12093. e = exception_type;
  12094. if (e == EXERROR)
  12095. exitstatus = 2;
  12096. s = state;
  12097. if (e == EXEXIT || s == 0 || iflag == 0 || shlvl) {
  12098. exitshell();
  12099. }
  12100. if (e == EXINT) {
  12101. outcslow('\n', stderr);
  12102. }
  12103. popstackmark(&smark);
  12104. FORCE_INT_ON; /* enable interrupts */
  12105. if (s == 1)
  12106. goto state1;
  12107. if (s == 2)
  12108. goto state2;
  12109. if (s == 3)
  12110. goto state3;
  12111. goto state4;
  12112. }
  12113. exception_handler = &jmploc;
  12114. #if DEBUG
  12115. opentrace();
  12116. TRACE(("Shell args: "));
  12117. trace_puts_args(argv);
  12118. #endif
  12119. rootpid = getpid();
  12120. init();
  12121. setstackmark(&smark);
  12122. procargs(argv);
  12123. if (argv[0] && argv[0][0] == '-')
  12124. isloginsh = 1;
  12125. if (isloginsh) {
  12126. const char *hp;
  12127. state = 1;
  12128. read_profile("/etc/profile");
  12129. state1:
  12130. state = 2;
  12131. hp = lookupvar("HOME");
  12132. if (hp) {
  12133. hp = concat_path_file(hp, ".profile");
  12134. read_profile(hp);
  12135. free((char*)hp);
  12136. }
  12137. }
  12138. state2:
  12139. state = 3;
  12140. if (
  12141. #ifndef linux
  12142. getuid() == geteuid() && getgid() == getegid() &&
  12143. #endif
  12144. iflag
  12145. ) {
  12146. shinit = lookupvar("ENV");
  12147. if (shinit != NULL && *shinit != '\0') {
  12148. read_profile(shinit);
  12149. }
  12150. }
  12151. state3:
  12152. state = 4;
  12153. if (minusc) {
  12154. /* evalstring pushes parsefile stack.
  12155. * Ensure we don't falsely claim that 0 (stdin)
  12156. * is one of stacked source fds.
  12157. * Testcase: ash -c 'exec 1>&0' must not complain. */
  12158. // if (!sflag) g_parsefile->pf_fd = -1;
  12159. // ^^ not necessary since now we special-case fd 0
  12160. // in is_hidden_fd() to not be considered "hidden fd"
  12161. evalstring(minusc, 0);
  12162. }
  12163. if (sflag || minusc == NULL) {
  12164. #if MAX_HISTORY > 0 && ENABLE_FEATURE_EDITING_SAVEHISTORY
  12165. if (iflag) {
  12166. const char *hp = lookupvar("HISTFILE");
  12167. if (!hp) {
  12168. hp = lookupvar("HOME");
  12169. if (hp) {
  12170. hp = concat_path_file(hp, ".ash_history");
  12171. setvar2("HISTFILE", hp);
  12172. free((char*)hp);
  12173. hp = lookupvar("HISTFILE");
  12174. }
  12175. }
  12176. if (hp)
  12177. line_input_state->hist_file = hp;
  12178. # if ENABLE_FEATURE_SH_HISTFILESIZE
  12179. hp = lookupvar("HISTFILESIZE");
  12180. line_input_state->max_history = size_from_HISTFILESIZE(hp);
  12181. # endif
  12182. }
  12183. #endif
  12184. state4: /* XXX ??? - why isn't this before the "if" statement */
  12185. cmdloop(1);
  12186. }
  12187. #if PROFILE
  12188. monitor(0);
  12189. #endif
  12190. #ifdef GPROF
  12191. {
  12192. extern void _mcleanup(void);
  12193. _mcleanup();
  12194. }
  12195. #endif
  12196. TRACE(("End of main reached\n"));
  12197. exitshell();
  12198. /* NOTREACHED */
  12199. }
  12200. /*-
  12201. * Copyright (c) 1989, 1991, 1993, 1994
  12202. * The Regents of the University of California. All rights reserved.
  12203. *
  12204. * This code is derived from software contributed to Berkeley by
  12205. * Kenneth Almquist.
  12206. *
  12207. * Redistribution and use in source and binary forms, with or without
  12208. * modification, are permitted provided that the following conditions
  12209. * are met:
  12210. * 1. Redistributions of source code must retain the above copyright
  12211. * notice, this list of conditions and the following disclaimer.
  12212. * 2. Redistributions in binary form must reproduce the above copyright
  12213. * notice, this list of conditions and the following disclaimer in the
  12214. * documentation and/or other materials provided with the distribution.
  12215. * 3. Neither the name of the University nor the names of its contributors
  12216. * may be used to endorse or promote products derived from this software
  12217. * without specific prior written permission.
  12218. *
  12219. * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  12220. * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  12221. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  12222. * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  12223. * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  12224. * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  12225. * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  12226. * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  12227. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  12228. * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  12229. * SUCH DAMAGE.
  12230. */