linux.pp 86 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783378437853786378737883789379037913792379337943795379637973798379938003801380238033804380538063807380838093810381138123813381438153816381738183819382038213822382338243825382638273828382938303831383238333834383538363837383838393840384138423843384438453846384738483849385038513852385338543855385638573858385938603861386238633864386538663867386838693870387138723873387438753876387738783879388038813882388338843885388638873888388938903891389238933894389538963897389838993900390139023903390439053906390739083909391039113912391339143915391639173918391939203921392239233924392539263927392839293930393139323933393439353936393739383939394039413942394339443945394639473948394939503951395239533954395539563957395839593960396139623963396439653966396739683969397039713972397339743975397639773978397939803981398239833984398539863987398839893990399139923993399439953996399739983999400040014002400340044005400640074008400940104011401240134014401540164017401840194020402140224023402440254026402740284029403040314032403340344035403640374038403940404041404240434044404540464047404840494050405140524053405440554056405740584059406040614062406340644065406640674068406940704071407240734074407540764077
  1. {
  2. $Id$
  3. This file is part of the Free Pascal run time library.
  4. Copyright (c) 1999-2000 by Michael Van Canneyt,
  5. member of the Free Pascal development team.
  6. See the file COPYING.FPC, included in this distribution,
  7. for details about the copyright.
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY;without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  11. **********************************************************************}
  12. Unit Linux;
  13. Interface
  14. { Get Types and Constants }
  15. {$i sysconst.inc}
  16. {$i systypes.inc}
  17. { Get System call numbers and error-numbers}
  18. {$i sysnr.inc}
  19. {$i errno.inc}
  20. var
  21. ErrNo,
  22. LinuxError : Longint;
  23. {********************
  24. Process
  25. ********************}
  26. const
  27. { cloning flags }
  28. CSIGNAL = $000000ff; // signal mask to be sent at exit
  29. CLONE_VM = $00000100; // set if VM shared between processes
  30. CLONE_FS = $00000200; // set if fs info shared between processes
  31. CLONE_FILES = $00000400; // set if open files shared between processes
  32. CLONE_SIGHAND = $00000800; // set if signal handlers shared
  33. CLONE_PID = $00001000; // set if pid shared
  34. type
  35. TCloneFunc=function(args:pointer):longint;cdecl;
  36. const
  37. { For getting/setting priority }
  38. Prio_Process = 0;
  39. Prio_PGrp = 1;
  40. Prio_User = 2;
  41. WNOHANG = $1;
  42. WUNTRACED = $2;
  43. __WCLONE = $80000000;
  44. {********************
  45. File
  46. ********************}
  47. Const
  48. P_IN = 1;
  49. P_OUT = 2;
  50. Const
  51. LOCK_SH = 1;
  52. LOCK_EX = 2;
  53. LOCK_UN = 8;
  54. LOCK_NB = 4;
  55. Type
  56. Tpipe = array[1..2] of longint;
  57. pglob = ^tglob;
  58. tglob = record
  59. name : pchar;
  60. next : pglob;
  61. end;
  62. ComStr = String[255];
  63. PathStr = String[255];
  64. DirStr = String[255];
  65. NameStr = String[255];
  66. ExtStr = String[255];
  67. const
  68. { For testing access rights }
  69. R_OK = 4;
  70. W_OK = 2;
  71. X_OK = 1;
  72. F_OK = 0;
  73. { For File control mechanism }
  74. F_GetFd = 1;
  75. F_SetFd = 2;
  76. F_GetFl = 3;
  77. F_SetFl = 4;
  78. F_GetLk = 5;
  79. F_SetLk = 6;
  80. F_SetLkW = 7;
  81. F_GetOwn = 8;
  82. F_SetOwn = 9;
  83. {********************
  84. Signal
  85. ********************}
  86. Const
  87. { For sending a signal }
  88. SA_NOCLDSTOP = 1;
  89. SA_SHIRQ = $04000000;
  90. SA_STACK = $08000000;
  91. SA_RESTART = $10000000;
  92. SA_INTERRUPT = $20000000;
  93. SA_NOMASK = $40000000;
  94. SA_ONESHOT = $80000000;
  95. SIG_BLOCK = 0;
  96. SIG_UNBLOCK = 1;
  97. SIG_SETMASK = 2;
  98. SIG_DFL = 0 ;
  99. SIG_IGN = 1 ;
  100. SIG_ERR = -1 ;
  101. SIGHUP = 1;
  102. SIGINT = 2;
  103. SIGQUIT = 3;
  104. SIGILL = 4;
  105. SIGTRAP = 5;
  106. SIGABRT = 6;
  107. SIGIOT = 6;
  108. SIGBUS = 7;
  109. SIGFPE = 8;
  110. SIGKILL = 9;
  111. SIGUSR1 = 10;
  112. SIGSEGV = 11;
  113. SIGUSR2 = 12;
  114. SIGPIPE = 13;
  115. SIGALRM = 14;
  116. SIGTerm = 15;
  117. SIGSTKFLT = 16;
  118. SIGCHLD = 17;
  119. SIGCONT = 18;
  120. SIGSTOP = 19;
  121. SIGTSTP = 20;
  122. SIGTTIN = 21;
  123. SIGTTOU = 22;
  124. SIGURG = 23;
  125. SIGXCPU = 24;
  126. SIGXFSZ = 25;
  127. SIGVTALRM = 26;
  128. SIGPROF = 27;
  129. SIGWINCH = 28;
  130. SIGIO = 29;
  131. SIGPOLL = SIGIO;
  132. SIGPWR = 30;
  133. SIGUNUSED = 31;
  134. Type
  135. SignalHandler = Procedure(Sig : LongInt);cdecl;
  136. PSignalHandler = ^SignalHandler;
  137. SignalRestorer = Procedure;cdecl;
  138. PSignalRestorer = ^SignalRestorer;
  139. SigSet = Longint;
  140. PSigSet = ^SigSet;
  141. SigActionRec = packed record
  142. Sa_Handler : SignalHandler;
  143. Sa_Mask : SigSet;
  144. Sa_Flags : Longint;
  145. Sa_restorer : SignalRestorer; { Obsolete - Don't use }
  146. end;
  147. PSigActionRec = ^SigActionRec;
  148. {********************
  149. IOCtl(TermIOS)
  150. ********************}
  151. Const
  152. { Amount of Control Chars }
  153. NCCS = 19;
  154. NCC = 8;
  155. { For Terminal handling }
  156. TCGETS = $5401;
  157. TCSETS = $5402;
  158. TCSETSW = $5403;
  159. TCSETSF = $5404;
  160. TCGETA = $5405;
  161. TCSETA = $5406;
  162. TCSETAW = $5407;
  163. TCSETAF = $5408;
  164. TCSBRK = $5409;
  165. TCXONC = $540A;
  166. TCFLSH = $540B;
  167. TIOCEXCL = $540C;
  168. TIOCNXCL = $540D;
  169. TIOCSCTTY = $540E;
  170. TIOCGPGRP = $540F;
  171. TIOCSPGRP = $5410;
  172. TIOCOUTQ = $5411;
  173. TIOCSTI = $5412;
  174. TIOCGWINSZ = $5413;
  175. TIOCSWINSZ = $5414;
  176. TIOCMGET = $5415;
  177. TIOCMBIS = $5416;
  178. TIOCMBIC = $5417;
  179. TIOCMSET = $5418;
  180. TIOCGSOFTCAR = $5419;
  181. TIOCSSOFTCAR = $541A;
  182. FIONREAD = $541B;
  183. TIOCINQ = FIONREAD;
  184. TIOCLINUX = $541C;
  185. TIOCCONS = $541D;
  186. TIOCGSERIAL = $541E;
  187. TIOCSSERIAL = $541F;
  188. TIOCPKT = $5420;
  189. FIONBIO = $5421;
  190. TIOCNOTTY = $5422;
  191. TIOCSETD = $5423;
  192. TIOCGETD = $5424;
  193. TCSBRKP = $5425;
  194. TIOCTTYGSTRUCT = $5426;
  195. FIONCLEX = $5450;
  196. FIOCLEX = $5451;
  197. FIOASYNC = $5452;
  198. TIOCSERCONFIG = $5453;
  199. TIOCSERGWILD = $5454;
  200. TIOCSERSWILD = $5455;
  201. TIOCGLCKTRMIOS = $5456;
  202. TIOCSLCKTRMIOS = $5457;
  203. TIOCSERGSTRUCT = $5458;
  204. TIOCSERGETLSR = $5459;
  205. TIOCSERGETMULTI = $545A;
  206. TIOCSERSETMULTI = $545B;
  207. TIOCMIWAIT = $545C;
  208. TIOCGICOUNT = $545D;
  209. TIOCPKT_DATA = 0;
  210. TIOCPKT_FLUSHREAD = 1;
  211. TIOCPKT_FLUSHWRITE = 2;
  212. TIOCPKT_STOP = 4;
  213. TIOCPKT_START = 8;
  214. TIOCPKT_NOSTOP = 16;
  215. TIOCPKT_DOSTOP = 32;
  216. Type
  217. winsize = packed record
  218. ws_row,
  219. ws_col,
  220. ws_xpixel,
  221. ws_ypixel : word;
  222. end;
  223. TWinSize=winsize;
  224. Termio = packed record
  225. c_iflag, { input mode flags }
  226. c_oflag, { output mode flags }
  227. c_cflag, { control mode flags }
  228. c_lflag : Word; { local mode flags }
  229. c_line : Word; { line discipline - careful, only High byte in use}
  230. c_cc : array [0..NCC-1] of char;{ control characters }
  231. end;
  232. TTermio=Termio;
  233. Termios = packed record
  234. c_iflag,
  235. c_oflag,
  236. c_cflag,
  237. c_lflag : longint;
  238. c_line : char;
  239. c_cc : array[0..NCCS-1] of byte;
  240. end;
  241. TTermios=Termios;
  242. const
  243. InitCC:array[0..NCCS-1] of byte=(3,34,177,25,4,0,1,0,21,23,32,0,22,17,27,26,0,0,0);
  244. const
  245. {c_cc characters}
  246. VINTR = 0;
  247. VQUIT = 1;
  248. VERASE = 2;
  249. VKILL = 3;
  250. VEOF = 4;
  251. VTIME = 5;
  252. VMIN = 6;
  253. VSWTC = 7;
  254. VSTART = 8;
  255. VSTOP = 9;
  256. VSUSP = 10;
  257. VEOL = 11;
  258. VREPRINT = 12;
  259. VDISCARD = 13;
  260. VWERASE = 14;
  261. VLNEXT = 15;
  262. VEOL2 = 16;
  263. {c_iflag bits}
  264. IGNBRK = $0000001;
  265. BRKINT = $0000002;
  266. IGNPAR = $0000004;
  267. PARMRK = $0000008;
  268. INPCK = $0000010;
  269. ISTRIP = $0000020;
  270. INLCR = $0000040;
  271. IGNCR = $0000080;
  272. ICRNL = $0000100;
  273. IUCLC = $0000200;
  274. IXON = $0000400;
  275. IXANY = $0000800;
  276. IXOFF = $0001000;
  277. IMAXBEL = $0002000;
  278. {c_oflag bits}
  279. OPOST = $0000001;
  280. OLCUC = $0000002;
  281. ONLCR = $0000004;
  282. OCRNL = $0000008;
  283. ONOCR = $0000010;
  284. ONLRET = $0000020;
  285. OFILL = $0000040;
  286. OFDEL = $0000080;
  287. NLDLY = $0000100;
  288. NL0 = $0000000;
  289. NL1 = $0000100;
  290. CRDLY = $0000600;
  291. CR0 = $0000000;
  292. CR1 = $0000200;
  293. CR2 = $0000400;
  294. CR3 = $0000600;
  295. TABDLY = $0001800;
  296. TAB0 = $0000000;
  297. TAB1 = $0000800;
  298. TAB2 = $0001000;
  299. TAB3 = $0001800;
  300. XTABS = $0001800;
  301. BSDLY = $0002000;
  302. BS0 = $0000000;
  303. BS1 = $0002000;
  304. VTDLY = $0004000;
  305. VT0 = $0000000;
  306. VT1 = $0004000;
  307. FFDLY = $0008000;
  308. FF0 = $0000000;
  309. FF1 = $0008000;
  310. {c_cflag bits}
  311. CBAUD = $000100F;
  312. B0 = $0000000;
  313. B50 = $0000001;
  314. B75 = $0000002;
  315. B110 = $0000003;
  316. B134 = $0000004;
  317. B150 = $0000005;
  318. B200 = $0000006;
  319. B300 = $0000007;
  320. B600 = $0000008;
  321. B1200 = $0000009;
  322. B1800 = $000000A;
  323. B2400 = $000000B;
  324. B4800 = $000000C;
  325. B9600 = $000000D;
  326. B19200 = $000000E;
  327. B38400 = $000000F;
  328. EXTA = B19200;
  329. EXTB = B38400;
  330. CSIZE = $0000030;
  331. CS5 = $0000000;
  332. CS6 = $0000010;
  333. CS7 = $0000020;
  334. CS8 = $0000030;
  335. CSTOPB = $0000040;
  336. CREAD = $0000080;
  337. PARENB = $0000100;
  338. PARODD = $0000200;
  339. HUPCL = $0000400;
  340. CLOCAL = $0000800;
  341. CBAUDEX = $0001000;
  342. B57600 = $0001001;
  343. B115200 = $0001002;
  344. B230400 = $0001003;
  345. B460800 = $0001004;
  346. CIBAUD = $100F0000;
  347. CMSPAR = $40000000;
  348. CRTSCTS = $80000000;
  349. {c_lflag bits}
  350. ISIG = $0000001;
  351. ICANON = $0000002;
  352. XCASE = $0000004;
  353. ECHO = $0000008;
  354. ECHOE = $0000010;
  355. ECHOK = $0000020;
  356. ECHONL = $0000040;
  357. NOFLSH = $0000080;
  358. TOSTOP = $0000100;
  359. ECHOCTL = $0000200;
  360. ECHOPRT = $0000400;
  361. ECHOKE = $0000800;
  362. FLUSHO = $0001000;
  363. PENDIN = $0004000;
  364. IEXTEN = $0008000;
  365. {c_line bits}
  366. TIOCM_LE = $001;
  367. TIOCM_DTR = $002;
  368. TIOCM_RTS = $004;
  369. TIOCM_ST = $008;
  370. TIOCM_SR = $010;
  371. TIOCM_CTS = $020;
  372. TIOCM_CAR = $040;
  373. TIOCM_RNG = $080;
  374. TIOCM_DSR = $100;
  375. TIOCM_CD = TIOCM_CAR;
  376. TIOCM_RI = TIOCM_RNG;
  377. TIOCM_OUT1 = $2000;
  378. TIOCM_OUT2 = $4000;
  379. {TCSetAttr}
  380. TCSANOW = 0;
  381. TCSADRAIN = 1;
  382. TCSAFLUSH = 2;
  383. {TCFlow}
  384. TCOOFF = 0;
  385. TCOON = 1;
  386. TCIOFF = 2;
  387. TCION = 3;
  388. {TCFlush}
  389. TCIFLUSH = 0;
  390. TCOFLUSH = 1;
  391. TCIOFLUSH = 2;
  392. {********************
  393. Info
  394. ********************}
  395. Type
  396. UTimBuf = packed record {in BSD array[0..1] of timeval, but this is
  397. backwards compatible with linux version}
  398. actime,
  399. dummy1,
  400. modtime,
  401. dummy2 : Longint;
  402. end;
  403. UTimeBuf=UTimBuf;
  404. TUTimeBuf=UTimeBuf;
  405. PUTimeBuf=^UTimeBuf;
  406. TSysinfo = packed record
  407. uptime : longint;
  408. loads : array[1..3] of longint;
  409. totalram,
  410. freeram,
  411. sharedram,
  412. bufferram,
  413. totalswap,
  414. freeswap : longint;
  415. procs : integer;
  416. s : string[18];
  417. end;
  418. PSysInfo = ^TSysInfo;
  419. {******************************************************************************
  420. Procedure/Functions
  421. ******************************************************************************}
  422. //Function SysCall(callnr:longint;var regs:SysCallregs):longint;
  423. {**************************
  424. Time/Date Handling
  425. ***************************}
  426. var
  427. tzdaylight : boolean;
  428. tzseconds : longint;
  429. tzname : array[boolean] of pchar;
  430. { timezone support }
  431. procedure GetLocalTimezone(timer:longint;var leap_correct,leap_hit:longint);
  432. procedure GetLocalTimezone(timer:longint);
  433. procedure ReadTimezoneFile(fn:string);
  434. function GetTimezoneFile:string;
  435. Procedure GetTimeOfDay(var tv:timeval);
  436. Function GetTimeOfDay:longint;
  437. Procedure EpochToLocal(epoch:longint;var year,month,day,hour,minute,second:Word);
  438. Function LocalToEpoch(year,month,day,hour,minute,second:Word):Longint;
  439. procedure GetTime(var hour,min,sec,msec,usec:word);
  440. procedure GetTime(var hour,min,sec,sec100:word);
  441. procedure GetTime(var hour,min,sec:word);
  442. Procedure GetDate(Var Year,Month,Day:Word);
  443. Procedure GetDateTime(Var Year,Month,Day,hour,minute,second:Word);
  444. {**************************
  445. Process Handling
  446. ***************************}
  447. function CreateShellArgV(const prog:string):ppchar;
  448. function CreateShellArgV(const prog:Ansistring):ppchar;
  449. Procedure Execve(Path:pathstr;args:ppchar;ep:ppchar);
  450. Procedure Execve(path:pchar;args:ppchar;ep:ppchar);
  451. Procedure Execv(const path:pathstr;args:ppchar);
  452. Procedure Execvp(Path:Pathstr;Args:ppchar;Ep:ppchar);
  453. Procedure Execl(const Todo:string);
  454. Procedure Execle(Todo:string;Ep:ppchar);
  455. Procedure Execlp(Todo:string;Ep:ppchar);
  456. Function Shell(const Command:String):Longint;
  457. Function Shell(const Command:AnsiString):Longint;
  458. Function Fork:longint;
  459. function Clone(func:TCloneFunc;sp:pointer;flags:longint;args:pointer):longint;
  460. Procedure ExitProcess(val:longint);
  461. Function WaitPid(Pid:longint;Status:pointer;Options:Integer):Longint;
  462. Procedure Nice(N:integer);
  463. Function GetPriority(Which,Who:longint):longint;
  464. Procedure SetPriority(Which,Who,What:longint);
  465. Function GetPid:LongInt;
  466. Function GetPPid:LongInt;
  467. Function GetUid:Longint;
  468. Function GetEUid:Longint;
  469. Function GetGid:Longint;
  470. Function GetEGid:Longint;
  471. {**************************
  472. File Handling
  473. ***************************}
  474. Function fdOpen(pathname:string;flags:longint):longint;
  475. Function fdOpen(pathname:string;flags,mode:longint):longint;
  476. Function fdOpen(pathname:pchar;flags:longint):longint;
  477. Function fdOpen(pathname:pchar;flags,mode:longint):longint;
  478. Function fdClose(fd:longint):boolean;
  479. Function fdRead(fd:longint;var buf;size:longint):longint;
  480. Function fdWrite(fd:longint;var buf;size:longint):longint;
  481. Function fdTruncate(fd,size:longint):boolean;
  482. Function fdSeek (fd,pos,seektype :longint): longint;
  483. Function fdFlush (fd : Longint) : Boolean;
  484. Function Link(OldPath,NewPath:pathstr):boolean;
  485. Function SymLink(OldPath,NewPath:pathstr):boolean;
  486. Function UnLink(Path:pathstr):boolean;
  487. Function UnLink(Path:pchar):Boolean;
  488. Function FReName (OldName,NewName : Pchar) : Boolean;
  489. Function FReName (OldName,NewName : String) : Boolean;
  490. Function Chown(path:pathstr;NewUid,NewGid:longint):boolean;
  491. Function Chmod(path:pathstr;Newmode:longint):boolean;
  492. Function Utime(path:pathstr;utim:utimebuf):boolean;
  493. Function Access(Path:Pathstr ;mode:longint):boolean;
  494. Function Umask(Mask:Integer):integer;
  495. Function Flock (fd,mode : longint) : boolean;
  496. Function Flock (var T : text;mode : longint) : boolean;
  497. Function Flock (var F : File;mode : longint) : boolean;
  498. Function FStat(Path:Pathstr;Var Info:stat):Boolean;
  499. Function FStat(Fd:longint;Var Info:stat):Boolean;
  500. Function FStat(var F:Text;Var Info:stat):Boolean;
  501. Function FStat(var F:File;Var Info:stat):Boolean;
  502. Function Lstat(Filename: PathStr;var Info:stat):Boolean;
  503. Function FSStat(Path:Pathstr;Var Info:statfs):Boolean;
  504. Function FSStat(Fd: Longint;Var Info:statfs):Boolean;
  505. Function Fcntl(Fd:longint;Cmd:Integer):integer;
  506. Procedure Fcntl(Fd:longint;Cmd:Integer;Arg:Longint);
  507. Function Fcntl(var Fd:Text;Cmd:Integer):integer;
  508. Procedure Fcntl(var Fd:Text;Cmd:Integer;Arg:Longint);
  509. Function Dup(oldfile:longint;var newfile:longint):Boolean;
  510. Function Dup(var oldfile,newfile:text):Boolean;
  511. Function Dup(var oldfile,newfile:file):Boolean;
  512. Function Dup2(oldfile,newfile:longint):Boolean;
  513. Function Dup2(var oldfile,newfile:text):Boolean;
  514. Function Dup2(var oldfile,newfile:file):Boolean;
  515. {
  516. Function Select(N:longint;readfds,writefds,exceptfds:PFDSet;TimeOut:PTimeVal):longint;
  517. Function Select(N:longint;readfds,writefds,exceptfds:PFDSet;TimeOut:Longint):longint;
  518. }
  519. Function SelectText(var T:Text;TimeOut :PTimeVal):Longint;
  520. {**************************
  521. Directory Handling
  522. ***************************}
  523. Function OpenDir(f:pchar):pdir;
  524. Function OpenDir(f: String):pdir;
  525. function CloseDir(p:pdir):integer;
  526. Function ReadDir(p:pdir):pdirent;
  527. procedure SeekDir(p:pdir;off:longint);
  528. function TellDir(p:pdir):longint;
  529. {**************************
  530. Pipe/Fifo/Stream
  531. ***************************}
  532. Function AssignPipe(var pipe_in,pipe_out:longint):boolean;
  533. Function AssignPipe(var pipe_in,pipe_out:text):boolean;
  534. Function AssignPipe(var pipe_in,pipe_out:file):boolean;
  535. Function PClose(Var F:text) : longint;
  536. Function PClose(Var F:file) : longint;
  537. Procedure POpen(var F:text;const Prog:String;rw:char);
  538. Procedure POpen(var F:file;const Prog:String;rw:char);
  539. Function mkFifo(pathname:string;mode:longint):boolean;
  540. Procedure AssignStream(Var StreamIn,Streamout:text;Const Prog:String);
  541. function AssignStream(var StreamIn, StreamOut, StreamErr: Text; const prog: String): LongInt;
  542. {**************************
  543. General information
  544. ***************************}
  545. {
  546. Function GetDomainName:String;
  547. Function GetHostName:String;
  548. Function Sysinfo(var Info:TSysinfo):Boolean;
  549. Function Uname(var unamerec:utsname):Boolean;
  550. }
  551. Function GetEnv(P:string):Pchar;
  552. {**************************
  553. Signal
  554. ***************************}
  555. Procedure SigAction(Signum:Integer;Var Act,OldAct:PSigActionRec );
  556. Procedure SigProcMask (How:Integer;SSet,OldSSet:PSigSet);
  557. Function SigPending:SigSet;
  558. Procedure SigSuspend(Mask:Sigset);
  559. //Function Signal(Signum:Integer;Handler:SignalHandler):SignalHandler;
  560. Function Kill(Pid:longint;Sig:integer):integer;
  561. Procedure SigRaise(Sig:integer);
  562. {Function Alarm(Sec : Longint) : longint;
  563. Procedure Pause;
  564. }
  565. {**************************
  566. IOCtl/Termios Functions
  567. ***************************}
  568. Function IOCtl(Handle,Ndx: Longint;Data: Pointer):boolean;
  569. Function TCGetAttr(fd:longint;var tios:TermIOS):boolean;
  570. Function TCSetAttr(fd:longint;OptAct:longint;var tios:TermIOS):boolean;
  571. Procedure CFSetISpeed(var tios:TermIOS;speed:Longint);
  572. Procedure CFSetOSpeed(var tios:TermIOS;speed:Longint);
  573. Procedure CFMakeRaw(var tios:TermIOS);
  574. Function TCSendBreak(fd,duration:longint):boolean;
  575. Function TCSetPGrp(fd,id:longint):boolean;
  576. Function TCGetPGrp(fd:longint;var id:longint):boolean;
  577. Function TCFlush(fd,qsel:longint):boolean;
  578. Function TCDrain(fd:longint):boolean;
  579. Function TCFlow(fd,act:longint):boolean;
  580. Function IsATTY(Handle:Longint):Boolean;
  581. Function IsATTY(f:text):Boolean;
  582. function TTYname(Handle:Longint):string;
  583. function TTYname(var F:Text):string;
  584. {**************************
  585. Memory functions
  586. ***************************}
  587. const
  588. PROT_READ = $1; { page can be read }
  589. PROT_WRITE = $2; { page can be written }
  590. PROT_EXEC = $4; { page can be executed }
  591. PROT_NONE = $0; { page can not be accessed }
  592. MAP_SHARED = $1; { Share changes }
  593. MAP_PRIVATE = $2; { Changes are private }
  594. MAP_TYPE = $f; { Mask for type of mapping }
  595. MAP_FIXED = $10; { Interpret addr exactly }
  596. MAP_ANONYMOUS = $20; { don't use a file }
  597. MAP_GROWSDOWN = $100; { stack-like segment }
  598. MAP_DENYWRITE = $800; { ETXTBSY }
  599. MAP_EXECUTABLE = $1000; { mark it as an executable }
  600. MAP_LOCKED = $2000; { pages are locked }
  601. MAP_NORESERVE = $4000; { don't check for reservations }
  602. type
  603. tmmapargs=record
  604. address : longint;
  605. size : longint;
  606. prot : longint;
  607. flags : longint;
  608. fd : longint;
  609. offset : longint;
  610. end;
  611. function MMap(const m:tmmapargs):longint;
  612. {**************************
  613. Port IO functions
  614. ***************************}
  615. {
  616. Function IOperm (From,Num : Cardinal; Value : Longint) : boolean;
  617. }
  618. {$IFDEF I386}
  619. Procedure WritePort (Port : Longint; Value : Byte);
  620. Procedure WritePort (Port : Longint; Value : Word);
  621. Procedure WritePort (Port : Longint; Value : Longint);
  622. Procedure WritePortl (Port : Longint; Var Buf; Count: longint);
  623. Procedure WritePortW (Port : Longint; Var Buf; Count: longint);
  624. Procedure WritePortB (Port : Longint; Var Buf; Count: longint);
  625. Procedure ReadPort (Port : Longint; Var Value : Byte);
  626. Procedure ReadPort (Port : Longint; Var Value : Word);
  627. Procedure ReadPort (Port : Longint; Var Value : Longint);
  628. Procedure ReadPortL (Port : Longint; Var Buf; Count: longint);
  629. Procedure ReadPortW (Port : Longint; Var Buf; Count: longint);
  630. Procedure ReadPortB (Port : Longint; Var Buf; Count: longint);
  631. {$ENDIF}
  632. {**************************
  633. Utility functions
  634. ***************************}
  635. Function Octal(l:longint):longint;
  636. Function FExpand(Const Path: PathStr):PathStr;
  637. Function FSearch(const path:pathstr;dirlist:string):pathstr;
  638. Procedure FSplit(const Path:PathStr;Var Dir:DirStr;Var Name:NameStr;Var Ext:ExtStr);
  639. Function Dirname(Const path:pathstr):pathstr;
  640. Function Basename(Const path:pathstr;Const suf:pathstr):pathstr;
  641. Function FNMatch(const Pattern,Name:string):Boolean;
  642. Function Glob(Const path:pathstr):pglob;
  643. Procedure Globfree(var p:pglob);
  644. Function StringToPPChar(Var S:STring):ppchar;
  645. Function GetFS(var T:Text):longint;
  646. Function GetFS(Var F:File):longint;
  647. {Filedescriptorsets}
  648. Procedure FD_Zero(var fds:fdSet);
  649. Procedure FD_Clr(fd:longint;var fds:fdSet);
  650. Procedure FD_Set(fd:longint;var fds:fdSet);
  651. Function FD_IsSet(fd:longint;var fds:fdSet):boolean;
  652. {Stat.Mode Types}
  653. Function S_ISLNK(m:word):boolean;
  654. Function S_ISREG(m:word):boolean;
  655. Function S_ISDIR(m:word):boolean;
  656. Function S_ISCHR(m:word):boolean;
  657. Function S_ISBLK(m:word):boolean;
  658. Function S_ISFIFO(m:word):boolean;
  659. Function S_ISSOCK(m:word):boolean;
  660. {******************************************************************************
  661. Implementation
  662. ******************************************************************************}
  663. Implementation
  664. Uses Strings;
  665. { Get the definitions of textrec and filerec }
  666. {$i textrec.inc}
  667. {$i filerec.inc}
  668. { Raw System calls are in Syscalls.inc}
  669. {$i syscalls.inc}
  670. {******************************************************************************
  671. Process related calls
  672. ******************************************************************************}
  673. function CreateShellArgV(const prog:string):ppchar;
  674. {
  675. Create an argv which executes a command in a shell using /bin/sh -c
  676. }
  677. var
  678. pp,p : ppchar;
  679. temp : string;
  680. begin
  681. getmem(pp,4*4);
  682. temp:='/bin/sh'#0'-c'#0+prog+#0;
  683. p:=pp;
  684. p^:=@temp[1];
  685. inc(p);
  686. p^:=@temp[9];
  687. inc(p);
  688. p^:=@temp[12];
  689. inc(p);
  690. p^:=Nil;
  691. CreateShellArgV:=pp;
  692. end;
  693. function CreateShellArgV(const prog:Ansistring):ppchar;
  694. {
  695. Create an argv which executes a command in a shell using /bin/sh -c
  696. using a AnsiString;
  697. }
  698. var
  699. pp,p : ppchar;
  700. temp : AnsiString;
  701. begin
  702. getmem(pp,4*4);
  703. temp:='/bin/sh'#0'-c'#0+prog+#0;
  704. p:=pp;
  705. GetMem(p^,Length(Temp));
  706. Move(@Temp[1],p^^,Length(Temp));
  707. inc(p);
  708. p^:=@pp[0][8];
  709. inc(p);
  710. p^:=@pp[0][11];
  711. inc(p);
  712. p^:=Nil;
  713. CreateShellArgV:=pp;
  714. end;
  715. Function Fork:longint;
  716. {
  717. This function issues the 'fork' System call. the program is duplicated in memory
  718. and Execution continues in parent and child process.
  719. In the parent process, fork returns the PID of the child. In the child process,
  720. zero is returned.
  721. A negative value indicates that an error has occurred, the error is returned in
  722. LinuxError.
  723. }
  724. var retval: LONGINT;
  725. Begin
  726. asm
  727. movl $2,%eax
  728. int $0x80
  729. mov %eax,retval
  730. end;
  731. fork:=checkreturnvalue(retval,retval);
  732. LinuxError:=ErrNo;
  733. End;
  734. function clone(func:TCloneFunc;sp:pointer;flags:longint;args:pointer):longint;
  735. {NOT IMPLEMENTED YET UNDER BSD}
  736. begin
  737. HALT;
  738. END;
  739. {
  740. if (pointer(func)=nil) or (sp=nil) then
  741. begin
  742. LinuxError:=Sys_EInval;
  743. exit;
  744. end;
  745. asm
  746. { Insert the argument onto the new stack. }
  747. movl sp,%ecx
  748. subl $8,%ecx
  749. movl args,%eax
  750. movl %eax,4(%ecx)
  751. { Save the function pointer as the zeroth argument.
  752. It will be popped off in the child in the ebx frobbing below. }
  753. movl func,%eax
  754. movl %eax,0(%ecx)
  755. { Do the system call }
  756. pushl %ebx
  757. pushl %ebx
  758. // movl flags,%ebx
  759. movl $251,%eax
  760. int $0x80
  761. popl %ebx
  762. popl %ebx
  763. test %eax,%eax
  764. jnz .Lclone_end
  765. { We're in the new thread }
  766. subl %ebp,%ebp { terminate the stack frame }
  767. call *%ebx
  768. { exit process }
  769. movl %eax,%ebx
  770. movl $1,%eax
  771. int $0x80
  772. .Lclone_end:
  773. movl %eax,__RESULT
  774. end;
  775. end;
  776. }
  777. Procedure Execve(path:pathstr;args:ppchar;ep:ppchar);
  778. {
  779. Replaces the current program by the program specified in path,
  780. arguments in args are passed to Execve.
  781. environment specified in ep is passed on.
  782. }
  783. var retval: LONGINT;
  784. Begin
  785. path:=path+#0;
  786. asm
  787. lea %ebx,path
  788. inc %ebx
  789. pushl ep
  790. pushl args
  791. pushl %ebx
  792. movl $59,%eax
  793. int $0x80
  794. addl $12,%esp
  795. mov %eax,retval
  796. end;
  797. checkreturnvalue(retval,retval);
  798. { This only gets set when the call fails, otherwise we don't get here ? }
  799. LinuxError:=ErrNo;
  800. End;
  801. Procedure Execve(path:pchar;args:ppchar;ep:ppchar);
  802. {
  803. Replaces the current program by the program specified in path,
  804. arguments in args are passed to Execve.
  805. environment specified in ep is passed on.
  806. }
  807. {
  808. Replaces the current program by the program specified in path,
  809. arguments in args are passed to Execve.
  810. environment specified in ep is passed on.
  811. }
  812. var retval: LONGINT;
  813. Begin
  814. asm
  815. pushl ep
  816. pushl args
  817. pushl path
  818. movl $59,%eax
  819. int $0x80
  820. addl $12,%esp
  821. mov %eax,retval
  822. end;
  823. checkreturnvalue(retval,retval);
  824. { This only gets set when the call fails, otherwise we don't get here ? }
  825. LinuxError:=ErrNo;
  826. End;
  827. Procedure Execv(const path:pathstr;args:ppchar);
  828. {
  829. Replaces the current program by the program specified in path,
  830. arguments in args are passed to Execve.
  831. the current environment is passed on.
  832. }
  833. begin
  834. Execve(path,args,envp); {On error linuxerror will get set there}
  835. end;
  836. Procedure Execvp(Path:Pathstr;Args:ppchar;Ep:ppchar);
  837. {
  838. This does the same as Execve, only it searches the PATH environment
  839. for the place of the Executable, except when Path starts with a slash.
  840. if the PATH environment variable is unavailable, the path is set to '.'
  841. }
  842. var
  843. thepath : string;
  844. begin
  845. if path[1]<>'/' then
  846. begin
  847. Thepath:=strpas(getenv('PATH'));
  848. if thepath='' then
  849. thepath:='.';
  850. Path:=FSearch(path,thepath)
  851. end
  852. else
  853. Path:='';
  854. if Path='' then
  855. linuxerror:=Sys_enoent
  856. else
  857. Execve(Path,args,ep);{On error linuxerror will get set there}
  858. end;
  859. Procedure Execle(Todo:string;Ep:ppchar);
  860. {
  861. This procedure takes the string 'Todo', parses it for command and
  862. command options, and Executes the command with the given options.
  863. The string 'Todo' shoud be of the form 'command options', options
  864. separated by commas.
  865. the PATH environment is not searched for 'command'.
  866. The specified environment(in 'ep') is passed on to command
  867. }
  868. var
  869. p : ppchar;
  870. begin
  871. p:=StringToPPChar(ToDo);
  872. if (p=nil) or (p^=nil) then
  873. exit;
  874. ExecVE(p^,p,EP);
  875. end;
  876. Procedure Execl(const Todo:string);
  877. {
  878. This procedure takes the string 'Todo', parses it for command and
  879. command options, and Executes the command with the given options.
  880. The string 'Todo' shoud be of the form 'command options', options
  881. separated by commas.
  882. the PATH environment is not searched for 'command'.
  883. The current environment is passed on to command
  884. }
  885. begin
  886. ExecLE(ToDo,EnvP);
  887. end;
  888. Procedure Execlp(Todo:string;Ep:ppchar);
  889. {
  890. This procedure takes the string 'Todo', parses it for command and
  891. command options, and Executes the command with the given options.
  892. The string 'Todo' shoud be of the form 'command options', options
  893. separated by commas.
  894. the PATH environment is searched for 'command'.
  895. The specified environment (in 'ep') is passed on to command
  896. }
  897. var
  898. p : ppchar;
  899. begin
  900. p:=StringToPPchar(todo);
  901. if (p=nil) or (p^=nil) then
  902. exit;
  903. ExecVP(StrPas(p^),p,EP);
  904. end;
  905. Procedure ExitProcess(val:longint);
  906. var retval : longint;
  907. begin
  908. asm
  909. pushl Val
  910. mov $1,%eax
  911. int $0x80
  912. addl $4,%eax
  913. mov %eax,retval
  914. end;
  915. checkreturnvalue(retval,retval);
  916. end;
  917. Function WaitPid(Pid:longint;Status:pointer;Options:Integer):Longint;
  918. {
  919. Waits until a child with PID Pid exits, or returns if it is exited already.
  920. Any resources used by the child are freed.
  921. The exit status is reported in the adress referred to by Status. It should
  922. be a longint.
  923. }
  924. var retval : longint;
  925. begin
  926. asm
  927. pushl $0 // BSD wait4 call has extra parameter
  928. push Options
  929. push Status
  930. push Pid
  931. mov $7,%eax
  932. int $0x80
  933. addl $16,%eax
  934. mov %eax,retval
  935. end;
  936. WaitPID:=checkreturnvalue(retval,retval);
  937. LinuxError:=errno;
  938. end;
  939. Function Shell(const Command:String):Longint;
  940. {
  941. Executes the shell, and passes it the string Command. (Through /bin/sh -c)
  942. The current environment is passed to the shell.
  943. It waits for the shell to exit, and returns its exit status.
  944. If the Exec call failed exit status 127 is reported.
  945. }
  946. var
  947. p : ppchar;
  948. temp,pid : longint;
  949. begin
  950. pid:=fork;
  951. if pid=-1 then
  952. exit; {Linuxerror already set in Fork}
  953. if pid=0 then
  954. begin
  955. {This is the child.}
  956. p:=CreateShellArgv(command);
  957. Execve(p^,p,envp);
  958. exit(127);
  959. end;
  960. temp:=0;
  961. WaitPid(pid,@temp,0);{Linuxerror is set there}
  962. Shell:=temp;{ Return exit status }
  963. end;
  964. Function Shell(const Command:AnsiString):Longint;
  965. {
  966. AnsiString version of Shell
  967. }
  968. var
  969. p : ppchar;
  970. temp,pid : longint;
  971. begin
  972. pid:=fork;
  973. if pid=-1 then
  974. exit; {Linuxerror already set in Fork}
  975. if pid=0 then
  976. begin
  977. {This is the child.}
  978. p:=CreateShellArgv(command);
  979. Execve(p^,p,envp);
  980. exit(127);
  981. end;
  982. temp:=0;
  983. WaitPid(pid,@temp,0);{Linuxerror is set there}
  984. Shell:=temp;{ Return exit status }
  985. end;
  986. Function GetPriority(Which,Who:longint):longint;
  987. {
  988. Get Priority of process, process group, or user.
  989. Which : selects what kind of priority is used.
  990. can be one of the following predefined Constants :
  991. Prio_User.
  992. Prio_PGrp.
  993. Prio_Process.
  994. Who : depending on which, this is , respectively :
  995. Uid
  996. Pid
  997. Process Group id
  998. Errors are reported in linuxerror _only_. (priority can be negative)
  999. }
  1000. var
  1001. retval : longint;
  1002. begin
  1003. errno:=0;
  1004. if (which<prio_process) or (which>prio_user) then
  1005. begin
  1006. { We can save an interrupt here }
  1007. getpriority:=0;
  1008. linuxerror:=Sys_einval;
  1009. end
  1010. else
  1011. begin
  1012. asm
  1013. pushl who
  1014. pushl which
  1015. int $0x80
  1016. addl $8,%eax
  1017. mov %eax,retval
  1018. end;
  1019. Getpriority:=checkreturnvalue(retval,retval);
  1020. LinuxError:=errno;
  1021. end;
  1022. end;
  1023. Procedure SetPriority(Which,Who,What:longint);
  1024. {
  1025. Set Priority of process, process group, or user.
  1026. Which : selects what kind of priority is used.
  1027. can be one of the following predefined Constants :
  1028. Prio_User.
  1029. Prio_PGrp.
  1030. Prio_Process.
  1031. Who : depending on value of which, this is, respectively :
  1032. Uid
  1033. Pid
  1034. Process Group id
  1035. what : A number between -20 and 20. -20 is most favorable, 20 least.
  1036. 0 is the default.
  1037. }
  1038. var
  1039. retval : longint;
  1040. begin
  1041. errno:=0;
  1042. if ((which<prio_process) or (which>prio_user)) or ((what<-20) or (what>20)) then
  1043. linuxerror:=Sys_einval { We can save an interrupt here }
  1044. else
  1045. begin
  1046. asm
  1047. pushl what
  1048. pushl who
  1049. pushl which
  1050. mov $96,%eax
  1051. int $0x80
  1052. addl $12,%eax
  1053. mov %eax,retval
  1054. end;
  1055. checkreturnvalue(retval,retval);
  1056. LinuxError:=errno;
  1057. end;
  1058. end;
  1059. Procedure Nice(N:integer);
  1060. {
  1061. Set process priority. A positive N means a lower priority.
  1062. A negative N decreases priority.
  1063. Doesn't exist in BSD. Linux emu uses setpriority in a construct as below:
  1064. }
  1065. begin
  1066. SetPriority(Prio_Process,0,N);
  1067. end;
  1068. Function GetPid:LongInt;
  1069. {
  1070. Get Process ID.
  1071. }
  1072. var retval : longint;
  1073. begin
  1074. asm
  1075. mov $20,%eax
  1076. int $0x80
  1077. mov %eax,retval
  1078. end;
  1079. GetPID:=checkreturnvalue(retval,retval);
  1080. LinuxError:=errno;
  1081. end;
  1082. Function GetPPid:LongInt;
  1083. {
  1084. Get Process ID of parent process.
  1085. }
  1086. var retval : longint;
  1087. begin
  1088. asm
  1089. mov $39,%eax
  1090. int $0x80
  1091. mov %eax,retval
  1092. end;
  1093. GetpPID:=checkreturnvalue(retval,retval);
  1094. LinuxError:=errno;
  1095. end;
  1096. Function GetUid:Longint;
  1097. {
  1098. Get User ID.
  1099. }
  1100. var retval : longint;
  1101. begin
  1102. asm
  1103. mov $24,%eax
  1104. int $0x80
  1105. mov %eax,retval
  1106. end;
  1107. GetUID:=checkreturnvalue(retval,retval);
  1108. LinuxError:=errno;
  1109. end;
  1110. Function GetEUid:Longint;
  1111. {
  1112. Get _effective_ User ID.
  1113. }
  1114. var retval : longint;
  1115. begin
  1116. asm
  1117. mov $25,%eax
  1118. int $0x80
  1119. mov %eax,retval
  1120. end;
  1121. GetEUID:=checkreturnvalue(retval,retval);
  1122. LinuxError:=errno;
  1123. end;
  1124. Function GetGid:Longint;
  1125. {
  1126. Get Group ID.
  1127. }
  1128. var retval : longint;
  1129. begin
  1130. asm
  1131. mov $47,%eax
  1132. int $0x80
  1133. mov %eax,retval
  1134. end;
  1135. GetGID:=checkreturnvalue(retval,retval);
  1136. LinuxError:=errno;
  1137. end;
  1138. Function GetEGid:Longint;
  1139. {
  1140. Get _effective_ Group ID.
  1141. }
  1142. var retval : longint;
  1143. begin
  1144. asm
  1145. mov $43,%eax
  1146. int $0x80
  1147. mov %eax,retval
  1148. end;
  1149. GetEGID:=checkreturnvalue(retval,retval);
  1150. LinuxError:=errno;
  1151. end;
  1152. {******************************************************************************
  1153. Date and Time related calls
  1154. ******************************************************************************}
  1155. Const
  1156. {Date Translation}
  1157. C1970=2440588;
  1158. D0 = 1461;
  1159. D1 = 146097;
  1160. D2 =1721119;
  1161. Function GregorianToJulian(Year,Month,Day:Longint):LongInt;
  1162. Var
  1163. Century,XYear: LongInt;
  1164. Begin
  1165. If Month<=2 Then
  1166. Begin
  1167. Dec(Year);
  1168. Inc(Month,12);
  1169. End;
  1170. Dec(Month,3);
  1171. Century:=(longint(Year Div 100)*D1) shr 2;
  1172. XYear:=(longint(Year Mod 100)*D0) shr 2;
  1173. GregorianToJulian:=((((Month*153)+2) div 5)+Day)+D2+XYear+Century;
  1174. End;
  1175. Procedure JulianToGregorian(JulianDN:LongInt;Var Year,Month,Day:Word);
  1176. Var
  1177. YYear,XYear,Temp,TempMonth : LongInt;
  1178. Begin
  1179. Temp:=((JulianDN-D2) shl 2)-1;
  1180. JulianDN:=Temp Div D1;
  1181. XYear:=(Temp Mod D1) or 3;
  1182. YYear:=(XYear Div D0);
  1183. Temp:=((((XYear mod D0)+4) shr 2)*5)-3;
  1184. Day:=((Temp Mod 153)+5) Div 5;
  1185. TempMonth:=Temp Div 153;
  1186. If TempMonth>=10 Then
  1187. Begin
  1188. inc(YYear);
  1189. dec(TempMonth,12);
  1190. End;
  1191. inc(TempMonth,3);
  1192. Month := TempMonth;
  1193. Year:=YYear+(JulianDN*100);
  1194. end;
  1195. Procedure GetTimeOfDay(var tv:timeval);
  1196. {
  1197. Get the number of seconds since 00:00, January 1 1970, GMT
  1198. the time NOT corrected any way
  1199. }
  1200. var tz : timezone;
  1201. retval : longint;
  1202. begin
  1203. asm
  1204. lea tz,%ebx
  1205. pushl %ebx
  1206. lea tv,%ecx
  1207. pushl %ecx
  1208. mov $116,%eax
  1209. int $0x80
  1210. add $8,%esp
  1211. mov %eax,retval
  1212. end;
  1213. checkreturnvalue(retval,retval);
  1214. LinuxError:=Errno;
  1215. end;
  1216. Function GetTimeOfDay: longint;
  1217. {
  1218. Get the number of seconds since 00:00, January 1 1970, GMT
  1219. the time NOT corrected any way
  1220. }
  1221. begin
  1222. GetTimeOfDay:=Sys_time;
  1223. LinuxError:=Errno;
  1224. end;
  1225. Procedure EpochToLocal(epoch:longint;var year,month,day,hour,minute,second:Word);
  1226. {
  1227. Transforms Epoch time into local time (hour, minute,seconds)
  1228. }
  1229. Var
  1230. DateNum: LongInt;
  1231. Begin
  1232. inc(Epoch,TZSeconds);
  1233. Datenum:=(Epoch Div 86400) + c1970;
  1234. JulianToGregorian(DateNum,Year,Month,day);
  1235. Epoch:=Epoch Mod 86400;
  1236. Hour:=Epoch Div 3600;
  1237. Epoch:=Epoch Mod 3600;
  1238. Minute:=Epoch Div 60;
  1239. Second:=Epoch Mod 60;
  1240. End;
  1241. Function LocalToEpoch(year,month,day,hour,minute,second:Word):Longint;
  1242. {
  1243. Transforms local time (year,month,day,hour,minutes,second) to Epoch time
  1244. (seconds since 00:00, january 1 1970, corrected for local time zone)
  1245. }
  1246. Begin
  1247. LocalToEpoch:=((GregorianToJulian(Year,Month,Day)-c1970)*86400)+
  1248. (LongInt(Hour)*3600)+(Minute*60)+Second-TZSeconds;
  1249. End;
  1250. procedure GetTime(var hour,min,sec,msec,usec:word);
  1251. {
  1252. Gets the current time, adjusted to local time
  1253. }
  1254. var
  1255. year,day,month:Word;
  1256. t : timeval;
  1257. begin
  1258. gettimeofday(t);
  1259. EpochToLocal(t.sec,year,month,day,hour,min,sec);
  1260. msec:=t.usec div 1000;
  1261. usec:=t.usec mod 1000;
  1262. end;
  1263. procedure GetTime(var hour,min,sec,sec100:word);
  1264. {
  1265. Gets the current time, adjusted to local time
  1266. }
  1267. var
  1268. usec : word;
  1269. begin
  1270. gettime(hour,min,sec,sec100,usec);
  1271. sec100:=sec100 div 10;
  1272. end;
  1273. Procedure GetTime(Var Hour,Min,Sec:Word);
  1274. {
  1275. Gets the current time, adjusted to local time
  1276. }
  1277. var
  1278. msec,usec : Word;
  1279. Begin
  1280. gettime(hour,min,sec,msec,usec);
  1281. End;
  1282. Procedure GetDate(Var Year,Month,Day:Word);
  1283. {
  1284. Gets the current date, adjusted to local time
  1285. }
  1286. var
  1287. hour,minute,second : word;
  1288. Begin
  1289. EpochToLocal(GetTimeOfDay,year,month,day,hour,minute,second);
  1290. End;
  1291. Procedure GetDateTime(Var Year,Month,Day,hour,minute,second:Word);
  1292. {
  1293. Gets the current date, adjusted to local time
  1294. }
  1295. Begin
  1296. EpochToLocal(GetTimeOfDay,year,month,day,hour,minute,second);
  1297. End;
  1298. { Include timezone handling routines which use /usr/share/timezone info }
  1299. {$i timezone.inc}
  1300. {******************************************************************************
  1301. FileSystem calls
  1302. ******************************************************************************}
  1303. Function fdOpen(pathname:string;flags:longint):longint;
  1304. begin
  1305. pathname:=pathname+#0;
  1306. fdOpen:=Sys_Open(@pathname[1],flags,438);
  1307. LinuxError:=Errno;
  1308. end;
  1309. Function fdOpen(pathname:string;flags,mode:longint):longint;
  1310. begin
  1311. pathname:=pathname+#0;
  1312. fdOpen:=Sys_Open(@pathname[1],flags,mode);
  1313. LinuxError:=Errno;
  1314. end;
  1315. Function fdOpen(pathname:pchar;flags:longint):longint;
  1316. begin
  1317. fdOpen:=Sys_Open(pathname,flags,0);
  1318. LinuxError:=Errno;
  1319. end;
  1320. Function fdOpen(pathname:pchar;flags,mode:longint):longint;
  1321. begin
  1322. fdOpen:=Sys_Open(pathname,flags,mode);
  1323. LinuxError:=Errno;
  1324. end;
  1325. Function fdClose(fd:longint):boolean;
  1326. begin
  1327. fdClose:=(Sys_Close(fd)=0);
  1328. LinuxError:=Errno;
  1329. end;
  1330. Function fdRead(fd:longint;var buf;size:longint):longint;
  1331. begin
  1332. fdRead:=Sys_Read(fd,pchar(@buf),size);
  1333. LinuxError:=Errno;
  1334. end;
  1335. Function fdWrite(fd:longint;var buf;size:longint):longint;
  1336. begin
  1337. fdWrite:=Sys_Write(fd,pchar(@buf),size);
  1338. LinuxError:=Errno;
  1339. end;
  1340. Function fdTruncate(fd,size:longint):boolean;
  1341. Var Retval : LONGINT;
  1342. begin
  1343. asm
  1344. push size
  1345. push fd
  1346. mov $201,%eax
  1347. int $0x80
  1348. addl $8,%esp
  1349. mov %eax,retval
  1350. end;
  1351. fdtruncate:=checkreturnvalue(retval,retval)=0;
  1352. LinuxError:=Errno;
  1353. end;
  1354. Function fdSeek (fd,pos,seektype :longint): longint;
  1355. {
  1356. Do a Seek on a file descriptor fd to position pos, starting from seektype
  1357. }
  1358. begin
  1359. fdseek:=Sys_LSeek (fd,pos,seektype);
  1360. LinuxError:=Errno;
  1361. end;
  1362. Function fdFlush (fd : Longint) : Boolean;
  1363. Var Retval : LONGINT;
  1364. begin
  1365. asm
  1366. push fd
  1367. mov $95,%eax
  1368. int $0x80
  1369. addl $4,%esp
  1370. mov %eax,retval
  1371. end;
  1372. fdflush:=checkreturnvalue(retval,retval)=0;
  1373. LinuxError:=Errno;
  1374. end;
  1375. function sys_fcntl(Fd:longint;Cmd:Integer;Arg:Longint):longint;
  1376. var retval : LONGINT;
  1377. begin
  1378. asm
  1379. push arg
  1380. push cmd
  1381. push fd
  1382. mov $92,%eax
  1383. int $0x80
  1384. addl $12,%esp
  1385. mov %eax,retval
  1386. end;
  1387. sys_fcntl:=checkreturnvalue(retval,retval);
  1388. LinuxError:=Errno;
  1389. end;
  1390. Function Fcntl(Fd:longint;Cmd:integer):integer;
  1391. {
  1392. Read or manipulate a file.(See also fcntl (2) )
  1393. Possible values for Cmd are :
  1394. F_GetFd,F_GetFl,F_GetOwn
  1395. Errors are reported in Linuxerror;
  1396. If Cmd is different from the allowed values, linuxerror=Sys_eninval.
  1397. }
  1398. begin
  1399. if (cmd in [F_GetFd,F_GetFl,F_GetOwn]) then
  1400. begin
  1401. Linuxerror:=sys_fcntl(fd,cmd,0);
  1402. if linuxerror=-1 then
  1403. begin
  1404. linuxerror:=errno;
  1405. fcntl:=0;
  1406. end
  1407. else
  1408. begin
  1409. fcntl:=linuxerror;
  1410. linuxerror:=0;
  1411. end;
  1412. end
  1413. else
  1414. begin
  1415. linuxerror:=Sys_einval;
  1416. Fcntl:=0;
  1417. end;
  1418. end;
  1419. Procedure Fcntl(Fd:longint;Cmd:Integer;Arg:Longint);
  1420. {
  1421. Read or manipulate a file. (See also fcntl (2) )
  1422. Possible values for Cmd are :
  1423. F_setFd,F_SetFl,F_GetLk,F_SetLk,F_SetLkW,F_SetOwn;
  1424. Errors are reported in Linuxerror;
  1425. If Cmd is different from the allowed values, linuxerror=Sys_eninval.
  1426. F_DupFD is not allowed, due to the structure of Files in Pascal.
  1427. }
  1428. begin
  1429. if (cmd in [F_SetFd,F_SetFl,F_GetLk,F_SetLk,F_SetLkw,F_SetOwn]) then
  1430. begin
  1431. sys_fcntl(fd,cmd,arg);
  1432. LinuxError:=ErrNo;
  1433. end
  1434. else
  1435. linuxerror:=Sys_einval;
  1436. end;
  1437. Function Fcntl(var Fd:Text;Cmd:integer):integer;
  1438. begin
  1439. Fcntl := Fcntl(textrec(Fd).handle, Cmd);
  1440. end;
  1441. Procedure Fcntl(var Fd:Text;Cmd:Integer;Arg:Longint);
  1442. begin
  1443. Fcntl(textrec(Fd).handle, Cmd, Arg);
  1444. end;
  1445. Function Chmod(path:pathstr;Newmode:longint):Boolean;
  1446. {
  1447. Changes the permissions of a file.
  1448. }
  1449. var
  1450. retval : longint;
  1451. begin
  1452. path:=path+#0;
  1453. asm
  1454. lea %ebx,path
  1455. inc %ebx
  1456. push newmode
  1457. push %ebx
  1458. mov $15,%eax
  1459. int $0x80
  1460. addl $8,%esp
  1461. mov %eax,retval
  1462. end;
  1463. ChMod:=checkreturnvalue(retval,retval)=0;
  1464. LinuxError:=Errno;
  1465. end;
  1466. Function Chown(path:pathstr;NewUid,NewGid:longint):boolean;
  1467. {
  1468. Change the owner and group of a file.
  1469. A user can only change the group to a group of which he is a member.
  1470. The super-user can change uid and gid of any file.
  1471. }
  1472. var retval : longint;
  1473. begin
  1474. path:=path+#0;
  1475. asm
  1476. lea %ebx,path
  1477. inc %ebx
  1478. push newgid
  1479. push newuid
  1480. push %ebx
  1481. mov $16,%eax
  1482. int $0x80
  1483. addl $12,%esp
  1484. mov %eax,retval
  1485. end;
  1486. Chown:=checkreturnvalue(retval,retval)=0;
  1487. LinuxError:=Errno;
  1488. end;
  1489. Function Utime(path:pathstr;utim:utimebuf):boolean;
  1490. var
  1491. Retval : longint;
  1492. begin
  1493. asm
  1494. lea %ebx,path
  1495. inc %ebx
  1496. push utim
  1497. push %ebx
  1498. mov $138,%eax
  1499. int $0x80
  1500. addl $12,%esp
  1501. mov %eax,retval
  1502. end;
  1503. utime:=checkreturnvalue(retval,retval)=0;
  1504. LinuxError:=Errno;
  1505. end;
  1506. Function Flock (fd,mode : longint) : boolean;
  1507. var
  1508. Retval : longint;
  1509. begin
  1510. asm
  1511. push mode
  1512. push fd
  1513. mov $131,%eax
  1514. int $0x80
  1515. addl $8,%esp
  1516. mov %eax,retval
  1517. end;
  1518. flock:=checkreturnvalue(retval,retval)=0;
  1519. LinuxError:=Errno;
  1520. end;
  1521. Function Flock (var T : text;mode : longint) : boolean;
  1522. begin
  1523. Flock:=Flock(TextRec(T).Handle,mode);
  1524. end;
  1525. Function Flock (var F : File;mode : longint) : boolean;
  1526. begin
  1527. Flock:=Flock(FileRec(F).Handle,mode);
  1528. end;
  1529. Function FStat(Path:Pathstr;Var Info:stat):Boolean;
  1530. {
  1531. Get all information on a file, and return it in Info.
  1532. }
  1533. begin
  1534. path:=path+#0;
  1535. FStat:=(Sys_stat(@(path[1]),Info)=0);
  1536. LinuxError:=errno;
  1537. end;
  1538. Function Fstat(Fd:Longint;var Info:stat):Boolean;
  1539. {
  1540. Get all information on a file descriptor, and return it in info.
  1541. }
  1542. var
  1543. Retval : longint;
  1544. begin
  1545. asm
  1546. push info
  1547. push fd
  1548. mov $189,%eax
  1549. int $0x80
  1550. addl $8,%esp
  1551. mov %eax,retval
  1552. end;
  1553. FStat:=checkreturnvalue(retval,retval)=0;
  1554. LinuxError:=Errno;
  1555. end;
  1556. Function FStat(var F:Text;Var Info:stat):Boolean;
  1557. {
  1558. Get all information on a text file, and return it in info.
  1559. }
  1560. begin
  1561. FStat:=Fstat(TextRec(F).Handle,INfo);
  1562. end;
  1563. Function FStat(var F:File;Var Info:stat):Boolean;
  1564. {
  1565. Get all information on a untyped file, and return it in info.
  1566. }
  1567. begin
  1568. FStat:=Fstat(FileRec(F).Handle,Info);
  1569. end;
  1570. Function Lstat(Filename: PathStr;var Info:stat):Boolean;
  1571. {
  1572. Get all information on a link (the link itself), and return it in info.
  1573. }
  1574. var
  1575. Retval : longint;
  1576. begin
  1577. FileName:=FileName+#0;
  1578. asm
  1579. lea filename,%ebx
  1580. inc %ebx
  1581. push info
  1582. push %ebx
  1583. mov $189,%eax
  1584. int $0x80
  1585. addl $8,%esp
  1586. mov %eax,retval
  1587. end;
  1588. LStat:=checkreturnvalue(retval,retval)=0;
  1589. LinuxError:=Errno;
  1590. end;
  1591. Function FSStat(Path:Pathstr;Var Info:statfs):Boolean;
  1592. {
  1593. Get all information on a fileSystem, and return it in Info.
  1594. Path is the name of a file/directory on the fileSystem you wish to
  1595. investigate.
  1596. }
  1597. var
  1598. Retval : longint;
  1599. begin
  1600. path:=path+#0;
  1601. asm
  1602. lea path,%ebx
  1603. inc %ebx
  1604. push info
  1605. push %ebx
  1606. mov $157,%eax
  1607. int $0x80
  1608. addl $8,%esp
  1609. mov %eax,retval
  1610. end;
  1611. FSStat:=checkreturnvalue(retval,retval)=0;
  1612. LinuxError:=Errno;
  1613. end;
  1614. Function FSStat(Fd:Longint;Var Info:statfs):Boolean;
  1615. {
  1616. Get all information on a fileSystem, and return it in Info.
  1617. Fd is the file descriptor of a file/directory on the fileSystem
  1618. you wish to investigate.
  1619. }
  1620. var
  1621. Retval : longint;
  1622. begin
  1623. asm
  1624. push info
  1625. push fd
  1626. mov $158,%eax
  1627. int $0x80
  1628. addl $8,%esp
  1629. mov %eax,retval
  1630. end;
  1631. FSStat:=checkreturnvalue(retval,retval)=0;
  1632. LinuxError:=Errno;
  1633. end;
  1634. Function Link(OldPath,NewPath:pathstr):boolean;
  1635. {
  1636. Proceduces a hard link from new to old.
  1637. In effect, new will be the same file as old.
  1638. }
  1639. var
  1640. retval : longint;
  1641. begin
  1642. oldpath:=oldpath+#0;
  1643. newpath:=newpath+#0;
  1644. asm
  1645. lea oldpath,%ebx
  1646. lea newpath,%ecx
  1647. inc %ebx
  1648. inc %ecx
  1649. push %ecx
  1650. push %ebx
  1651. mov $9,%eax
  1652. int $0x80
  1653. addl $8,%esp
  1654. mov %eax,retval
  1655. end;
  1656. Link:=checkreturnvalue(retval,retval)=0;
  1657. LinuxError:=Errno;
  1658. end;
  1659. Function SymLink(OldPath,newPath:pathstr):boolean;
  1660. {
  1661. Proceduces a soft link from new to old.
  1662. }
  1663. var
  1664. retval : longint;
  1665. begin
  1666. oldpath:=oldpath+#0;
  1667. newpath:=newpath+#0;
  1668. asm
  1669. lea oldpath,%ebx
  1670. lea newpath,%ecx
  1671. inc %ebx
  1672. inc %ecx
  1673. push %ecx
  1674. push %ebx
  1675. mov $57,%eax
  1676. int $0x80
  1677. addl $8,%esp
  1678. mov %eax,retval
  1679. end;
  1680. SymLink:=checkreturnvalue(retval,retval)=0;
  1681. LinuxError:=Errno;
  1682. end;
  1683. Function UnLink(Path:pathstr):boolean;
  1684. {
  1685. Removes the file in 'Path' (that is, it decreases the link count with one.
  1686. if the link count is zero, the file is removed from the disk.
  1687. }
  1688. begin
  1689. path:=path+#0;
  1690. Unlink:=Sys_unlink(pchar(@(path[1])))=0;
  1691. linuxerror:=errno;
  1692. end;
  1693. Function UnLink(Path:pchar):Boolean;
  1694. {
  1695. Removes the file in 'Path' (that is, it decreases the link count with one.
  1696. if the link count is zero, the file is removed from the disk.
  1697. }
  1698. begin
  1699. Unlink:=(Sys_unlink(path)=0);
  1700. linuxerror:=errno;
  1701. end;
  1702. Function FRename (OldName,NewName : Pchar) : Boolean;
  1703. begin
  1704. FRename:=Sys_rename(OldName,NewName)=0;
  1705. LinuxError:=Errno;
  1706. end;
  1707. Function FRename (OldName,NewName : String) : Boolean;
  1708. begin
  1709. OldName:=OldName+#0;
  1710. NewName:=NewName+#0;
  1711. FRename:=FRename (@OldName[1],@NewName[1]);
  1712. end;
  1713. {!!}
  1714. Function Umask(Mask:Integer):integer;
  1715. {
  1716. Sets file creation mask to (Mask and 0777 (octal) ), and returns the
  1717. previous value.
  1718. }
  1719. var
  1720. retval : longint;
  1721. begin
  1722. asm
  1723. pushw mask
  1724. mov $60,%eax
  1725. int $0x80
  1726. addl $2,%esp
  1727. mov %eax,retval
  1728. end;
  1729. Umask:=checkreturnvalue(retval,retval);
  1730. LinuxError:=0;
  1731. end;
  1732. Function Access(Path:Pathstr ;mode:longint):boolean;
  1733. {
  1734. Test users access rights on the specified file.
  1735. Mode is a mask xosisting of one or more of R_OK, W_OK, X_OK, F_OK.
  1736. R,W,X stand for read,write and Execute access, simultaneously.
  1737. F_OK checks whether the test would be allowed on the file.
  1738. i.e. It checks the search permissions in all directory components
  1739. of the path.
  1740. The test is done with the real user-ID, instead of the effective.
  1741. If access is denied, or an error occurred, false is returned.
  1742. If access is granted, true is returned.
  1743. Errors other than no access,are reported in linuxerror.
  1744. }
  1745. var
  1746. retval : longint;
  1747. begin
  1748. path:=path+#0;
  1749. asm
  1750. lea path,%ebx
  1751. inc %ebx
  1752. push mode
  1753. push %ebx
  1754. mov $33,%eax
  1755. int $0x80
  1756. addl $8,%esp
  1757. mov %eax,retval
  1758. end;
  1759. Access:=checkreturnvalue(retval,retval)=0;
  1760. LinuxError:=Errno;
  1761. end;
  1762. Function Dup(oldfile:longint;var newfile:longint):Boolean;
  1763. {
  1764. Copies the filedescriptor oldfile to newfile
  1765. }
  1766. var
  1767. retval : longint;
  1768. begin
  1769. asm
  1770. push oldfile
  1771. mov $41,%eax
  1772. int $0x80
  1773. addl $4,%esp
  1774. mov %eax,retval
  1775. end;
  1776. NewFile:=checkreturnvalue(retval,retval);
  1777. LinuxError:=Errno;
  1778. Dup:=(LinuxError=0);
  1779. end;
  1780. Function Dup(var oldfile,newfile:text):Boolean;
  1781. {
  1782. Copies the filedescriptor oldfile to newfile, after flushing the buffer of
  1783. oldfile.
  1784. After which the two textfiles are, in effect, the same, except
  1785. that they don't share the same buffer, and don't share the same
  1786. close_on_exit flag.
  1787. }
  1788. begin
  1789. flush(oldfile);{ We cannot share buffers, so we flush them. }
  1790. textrec(newfile):=textrec(oldfile);
  1791. textrec(newfile).bufptr:=@(textrec(newfile).buffer);{ No shared buffer. }
  1792. Dup:=Dup(textrec(oldfile).handle,textrec(newfile).handle);
  1793. end;
  1794. Function Dup(var oldfile,newfile:file):Boolean;
  1795. {
  1796. Copies the filedescriptor oldfile to newfile
  1797. }
  1798. begin
  1799. filerec(newfile):=filerec(oldfile);
  1800. Dup:=Dup(filerec(oldfile).handle,filerec(newfile).handle);
  1801. end;
  1802. Function Dup2(oldfile,newfile:longint):Boolean;
  1803. {
  1804. Copies the filedescriptor oldfile to newfile
  1805. }
  1806. var
  1807. retval : longint;
  1808. begin
  1809. asm
  1810. push newfile
  1811. push oldfile
  1812. mov $90,%eax
  1813. int $0x80
  1814. addl $8,%esp
  1815. mov %eax,retval
  1816. end;
  1817. checkreturnvalue(retval,retval);
  1818. LinuxError:=Errno;
  1819. Dup2:=(LinuxError=0);
  1820. end;
  1821. Function Dup2(var oldfile,newfile:text):Boolean;
  1822. {
  1823. Copies the filedescriptor oldfile to newfile, after flushing the buffer of
  1824. oldfile. It closes newfile if it was still open.
  1825. After which the two textfiles are, in effect, the same, except
  1826. that they don't share the same buffer, and don't share the same
  1827. close_on_exit flag.
  1828. }
  1829. var
  1830. tmphandle : word;
  1831. begin
  1832. case TextRec(oldfile).mode of
  1833. fmOutput, fmInOut, fmAppend :
  1834. flush(oldfile);{ We cannot share buffers, so we flush them. }
  1835. end;
  1836. case TextRec(newfile).mode of
  1837. fmOutput, fmInOut, fmAppend :
  1838. flush(newfile);
  1839. end;
  1840. tmphandle:=textrec(newfile).handle;
  1841. textrec(newfile):=textrec(oldfile);
  1842. textrec(newfile).handle:=tmphandle;
  1843. textrec(newfile).bufptr:=@(textrec(newfile).buffer);{ No shared buffer. }
  1844. Dup2:=Dup2(textrec(oldfile).handle,textrec(newfile).handle);
  1845. end;
  1846. Function Dup2(var oldfile,newfile:file):Boolean;
  1847. {
  1848. Copies the filedescriptor oldfile to newfile
  1849. }
  1850. begin
  1851. filerec(newfile):=filerec(oldfile);
  1852. Dup2:=Dup2(filerec(oldfile).handle,filerec(newfile).handle);
  1853. end;
  1854. Function Select(N:longint;readfds,writefds,exceptfds:PFDSet;TimeOut:PTimeVal):longint;
  1855. {
  1856. Select checks whether the file descriptor sets in readfs/writefs/exceptfs
  1857. have changed.
  1858. }
  1859. Var
  1860. Retval : LONGINT;
  1861. begin
  1862. asm
  1863. pushl TimeOut
  1864. pushl exceptfds
  1865. pushl writefds
  1866. pushl readfds
  1867. pushl n
  1868. mov $93,%eax
  1869. int $0x80
  1870. addl $20,%esp
  1871. mov %eax,retval
  1872. end;
  1873. Select:=checkreturnvalue(retval,retval);
  1874. LinuxError:=Errno;
  1875. end;
  1876. Function Select(N:longint;readfds,writefds,exceptfds:PFDSet;TimeOut:Longint):longint;
  1877. {
  1878. Select checks whether the file descriptor sets in readfs/writefs/exceptfs
  1879. have changed.
  1880. This function allows specification of a timeout as a longint.
  1881. }
  1882. var
  1883. p : PTimeVal;
  1884. tv : TimeVal;
  1885. begin
  1886. if TimeOut=-1 then
  1887. p:=nil
  1888. else
  1889. begin
  1890. tv.Sec:=Timeout div 1000;
  1891. tv.Usec:=(Timeout mod 1000)*1000;
  1892. p:=@tv;
  1893. end;
  1894. Select:=Select(N,Readfds,WriteFds,ExceptFds,p);
  1895. end;
  1896. Function SelectText(var T:Text;TimeOut :PTimeval):Longint;
  1897. Var
  1898. F:FDSet;
  1899. begin
  1900. if textrec(t).mode=fmclosed then
  1901. begin
  1902. LinuxError:=Sys_EBADF;
  1903. exit(-1);
  1904. end;
  1905. FD_Zero(f);
  1906. FD_Set(textrec(T).handle,f);
  1907. if textrec(T).mode=fminput then
  1908. SelectText:=select(textrec(T).handle+1,@f,nil,nil,TimeOut)
  1909. else
  1910. SelectText:=select(textrec(T).handle+1,nil,@f,nil,TimeOut);
  1911. end;
  1912. {******************************************************************************
  1913. Directory
  1914. ******************************************************************************}
  1915. Function OpenDir(F:String):PDir;
  1916. begin
  1917. F:=F+#0;
  1918. OpenDir:=OpenDir(@F[1]);
  1919. end;
  1920. procedure SeekDir(p:pdir;off:longint);
  1921. begin
  1922. if p=nil then
  1923. begin
  1924. errno:=Sys_EBADF;
  1925. exit;
  1926. end;
  1927. p^.nextoff:=Sys_lseek(p^.fd,off,seek_set);
  1928. p^.size:=0;
  1929. p^.loc:=0;
  1930. end;
  1931. function TellDir(p:pdir):longint;
  1932. begin
  1933. if p=nil then
  1934. begin
  1935. errno:=Sys_EBADF;
  1936. telldir:=-1;
  1937. exit;
  1938. end;
  1939. telldir:=Sys_lseek(p^.fd,0,seek_cur)
  1940. { We could try to use the nextoff field here, but on my 1.2.13
  1941. kernel, this gives nothing... This may have to do with
  1942. the readdir implementation of libc... I also didn't find any trace of
  1943. the field in the kernel code itself, So I suspect it is an artifact of libc.
  1944. Michael. }
  1945. end;
  1946. Function ReadDir(P:pdir):pdirent;
  1947. begin
  1948. ReadDir:=Sys_ReadDir(p);
  1949. LinuxError:=Errno;
  1950. end;
  1951. {******************************************************************************
  1952. Pipes/Fifo
  1953. ******************************************************************************}
  1954. Procedure OpenPipe(var F:Text);
  1955. begin
  1956. case textrec(f).mode of
  1957. fmoutput :
  1958. if textrec(f).userdata[1]<>P_OUT then
  1959. textrec(f).mode:=fmclosed;
  1960. fminput :
  1961. if textrec(f).userdata[1]<>P_IN then
  1962. textrec(f).mode:=fmclosed;
  1963. else
  1964. textrec(f).mode:=fmclosed;
  1965. end;
  1966. end;
  1967. Procedure IOPipe(var F:text);
  1968. begin
  1969. case textrec(f).mode of
  1970. fmoutput :
  1971. begin
  1972. { first check if we need something to write, else we may
  1973. get a SigPipe when Close() is called (PFV) }
  1974. if textrec(f).bufpos>0 then
  1975. Sys_write(textrec(f).handle,pchar(textrec(f).bufptr),textrec(f).bufpos);
  1976. end;
  1977. fminput :
  1978. textrec(f).bufend:=Sys_read(textrec(f).handle,pchar(textrec(f).bufptr),textrec(f).bufsize);
  1979. end;
  1980. textrec(f).bufpos:=0;
  1981. end;
  1982. Procedure FlushPipe(var F:Text);
  1983. begin
  1984. if (textrec(f).mode=fmoutput) and (textrec(f).bufpos<>0) then
  1985. IOPipe(f);
  1986. textrec(f).bufpos:=0;
  1987. end;
  1988. Procedure ClosePipe(var F:text);
  1989. begin
  1990. textrec(f).mode:=fmclosed;
  1991. Sys_close(textrec(f).handle);
  1992. end;
  1993. Function AssignPipe(var pipe_in,pipe_out:longint):boolean;
  1994. {
  1995. Sets up a pair of file variables, which act as a pipe. The first one can
  1996. be read from, the second one can be written to.
  1997. If the operation was unsuccesful, linuxerror is set.
  1998. }
  1999. var
  2000. pip : tpipe;
  2001. retval : LONGINT;
  2002. begin
  2003. asm
  2004. lea pip,%ebx
  2005. push %ebx
  2006. mov $42,%eax
  2007. int $0x80
  2008. addl $4,%esp
  2009. mov %eax,retval
  2010. end;
  2011. checkreturnvalue(retval,retval);
  2012. LinuxError:=Errno;
  2013. pipe_in:=pip[1];
  2014. pipe_out:=pip[2];
  2015. AssignPipe:=(LinuxError=0);
  2016. end;
  2017. Function AssignPipe(var pipe_in,pipe_out:text):boolean;
  2018. {
  2019. Sets up a pair of file variables, which act as a pipe. The first one can
  2020. be read from, the second one can be written to.
  2021. If the operation was unsuccesful, linuxerror is set.
  2022. }
  2023. var
  2024. f_in,f_out : longint;
  2025. begin
  2026. if not AssignPipe(f_in,f_out) then
  2027. begin
  2028. AssignPipe:=false;
  2029. exit;
  2030. end;
  2031. { Set up input }
  2032. Assign(Pipe_in,'');
  2033. Textrec(Pipe_in).Handle:=f_in;
  2034. Textrec(Pipe_in).Mode:=fmInput;
  2035. Textrec(Pipe_in).userdata[1]:=P_IN;
  2036. TextRec(Pipe_in).OpenFunc:=@OpenPipe;
  2037. TextRec(Pipe_in).InOutFunc:=@IOPipe;
  2038. TextRec(Pipe_in).FlushFunc:=@FlushPipe;
  2039. TextRec(Pipe_in).CloseFunc:=@ClosePipe;
  2040. { Set up output }
  2041. Assign(Pipe_out,'');
  2042. Textrec(Pipe_out).Handle:=f_out;
  2043. Textrec(Pipe_out).Mode:=fmOutput;
  2044. Textrec(Pipe_out).userdata[1]:=P_OUT;
  2045. TextRec(Pipe_out).OpenFunc:=@OpenPipe;
  2046. TextRec(Pipe_out).InOutFunc:=@IOPipe;
  2047. TextRec(Pipe_out).FlushFunc:=@FlushPipe;
  2048. TextRec(Pipe_out).CloseFunc:=@ClosePipe;
  2049. AssignPipe:=true;
  2050. end;
  2051. Function AssignPipe(var pipe_in,pipe_out:file):boolean;
  2052. {
  2053. Sets up a pair of file variables, which act as a pipe. The first one can
  2054. be read from, the second one can be written to.
  2055. If the operation was unsuccesful, linuxerror is set.
  2056. }
  2057. var
  2058. f_in,f_out : longint;
  2059. begin
  2060. if not AssignPipe(f_in,f_out) then
  2061. begin
  2062. AssignPipe:=false;
  2063. exit;
  2064. end;
  2065. { Set up input }
  2066. Assign(Pipe_in,'');
  2067. Filerec(Pipe_in).Handle:=f_in;
  2068. Filerec(Pipe_in).Mode:=fmInput;
  2069. Filerec(Pipe_in).recsize:=1;
  2070. Filerec(Pipe_in).userdata[1]:=P_IN;
  2071. { Set up output }
  2072. Assign(Pipe_out,'');
  2073. Filerec(Pipe_out).Handle:=f_out;
  2074. Filerec(Pipe_out).Mode:=fmoutput;
  2075. Filerec(Pipe_out).recsize:=1;
  2076. Filerec(Pipe_out).userdata[1]:=P_OUT;
  2077. AssignPipe:=true;
  2078. end;
  2079. Function PClose(Var F:text) :longint;
  2080. var
  2081. pl : ^longint;
  2082. res : longint;
  2083. begin
  2084. res:=Textrec(F).Handle;
  2085. asm
  2086. push res
  2087. mov $6,%eax
  2088. int $0x80
  2089. add $4,%esp
  2090. end;
  2091. { closed our side, Now wait for the other - this appears to be needed ?? }
  2092. pl:=@(textrec(f).userdata[2]);
  2093. waitpid(pl^,@res,0);
  2094. pclose:=res shr 8;
  2095. end;
  2096. Function PClose(Var F:file) : longint;
  2097. var
  2098. pl : ^longint;
  2099. res : longint;
  2100. begin
  2101. res:=filerec(F).Handle;
  2102. asm
  2103. push res
  2104. mov $6,%eax
  2105. int $0x80
  2106. add $4,%esp
  2107. end;
  2108. { closed our side, Now wait for the other - this appears to be needed ?? }
  2109. pl:=@(filerec(f).userdata[2]);
  2110. waitpid(pl^,@res,0);
  2111. pclose:=res shr 8;
  2112. end;
  2113. Procedure PCloseText(Var F:text);
  2114. {
  2115. May not use @PClose due overloading
  2116. }
  2117. begin
  2118. PClose(f);
  2119. end;
  2120. Procedure POpen(var F:text;const Prog:String;rw:char);
  2121. {
  2122. Starts the program in 'Prog' and makes it's input or out put the
  2123. other end of a pipe. If rw is 'w' or 'W', then whatever is written to
  2124. F, will be read from stdin by the program in 'Prog'. The inverse is true
  2125. for 'r' or 'R' : whatever the program in 'Prog' writes to stdout, can be
  2126. read from 'f'.
  2127. }
  2128. var
  2129. pipi,
  2130. pipo : text;
  2131. pid : longint;
  2132. pl : ^longint;
  2133. pp : ppchar;
  2134. begin
  2135. LinuxError:=0;
  2136. rw:=upcase(rw);
  2137. if not (rw in ['R','W']) then
  2138. begin
  2139. LinuxError:=Sys_enoent;
  2140. exit;
  2141. end;
  2142. AssignPipe(pipi,pipo);
  2143. if Linuxerror<>0 then
  2144. exit;
  2145. pid:=fork;
  2146. if linuxerror<>0 then
  2147. begin
  2148. close(pipi);
  2149. close(pipo);
  2150. exit;
  2151. end;
  2152. if pid=0 then
  2153. begin
  2154. { We're in the child }
  2155. if rw='W' then
  2156. begin
  2157. close(pipo);
  2158. dup2(pipi,input);
  2159. close(pipi);
  2160. if linuxerror<>0 then
  2161. halt(127);
  2162. end
  2163. else
  2164. begin
  2165. close(pipi);
  2166. dup2(pipo,output);
  2167. close(pipo);
  2168. if linuxerror<>0 then
  2169. halt(127);
  2170. end;
  2171. pp:=createshellargv(prog);
  2172. Execve(pp^,pp,envp);
  2173. halt(127);
  2174. end
  2175. else
  2176. begin
  2177. { We're in the parent }
  2178. if rw='W' then
  2179. begin
  2180. close(pipi);
  2181. f:=pipo;
  2182. textrec(f).bufptr:=@textrec(f).buffer;
  2183. end
  2184. else
  2185. begin
  2186. close(pipo);
  2187. f:=pipi;
  2188. textrec(f).bufptr:=@textrec(f).buffer;
  2189. end;
  2190. {Save the process ID - needed when closing }
  2191. pl:=@(textrec(f).userdata[2]);
  2192. pl^:=pid;
  2193. textrec(f).closefunc:=@PCloseText;
  2194. end;
  2195. end;
  2196. Procedure POpen(var F:file;const Prog:String;rw:char);
  2197. {
  2198. Starts the program in 'Prog' and makes it's input or out put the
  2199. other end of a pipe. If rw is 'w' or 'W', then whatever is written to
  2200. F, will be read from stdin by the program in 'Prog'. The inverse is true
  2201. for 'r' or 'R' : whatever the program in 'Prog' writes to stdout, can be
  2202. read from 'f'.
  2203. }
  2204. var
  2205. pipi,
  2206. pipo : file;
  2207. pid : longint;
  2208. pl : ^longint;
  2209. p,pp : ppchar;
  2210. temp : string[255];
  2211. begin
  2212. LinuxError:=0;
  2213. rw:=upcase(rw);
  2214. if not (rw in ['R','W']) then
  2215. begin
  2216. LinuxError:=Sys_enoent;
  2217. exit;
  2218. end;
  2219. AssignPipe(pipi,pipo);
  2220. if Linuxerror<>0 then
  2221. exit;
  2222. pid:=fork;
  2223. if linuxerror<>0 then
  2224. begin
  2225. close(pipi);
  2226. close(pipo);
  2227. exit;
  2228. end;
  2229. if pid=0 then
  2230. begin
  2231. { We're in the child }
  2232. if rw='W' then
  2233. begin
  2234. close(pipo);
  2235. dup2(filerec(pipi).handle,stdinputhandle);
  2236. close(pipi);
  2237. if linuxerror<>0 then
  2238. halt(127);
  2239. end
  2240. else
  2241. begin
  2242. close(pipi);
  2243. dup2(filerec(pipo).handle,stdoutputhandle);
  2244. close(pipo);
  2245. if linuxerror<>0 then
  2246. halt(127);
  2247. end;
  2248. getmem(pp,sizeof(pchar)*4);
  2249. temp:='/bin/sh'#0'-c'#0+prog+#0;
  2250. p:=pp;
  2251. p^:=@temp[1];
  2252. inc(p);
  2253. p^:=@temp[9];
  2254. inc(p);
  2255. p^:=@temp[12];
  2256. inc(p);
  2257. p^:=Nil;
  2258. Execve('/bin/sh',pp,envp);
  2259. halt(127);
  2260. end
  2261. else
  2262. begin
  2263. { We're in the parent }
  2264. if rw='W' then
  2265. begin
  2266. close(pipi);
  2267. f:=pipo;
  2268. end
  2269. else
  2270. begin
  2271. close(pipo);
  2272. f:=pipi;
  2273. end;
  2274. {Save the process ID - needed when closing }
  2275. pl:=@(filerec(f).userdata[2]);
  2276. pl^:=pid;
  2277. end;
  2278. end;
  2279. Function mkFifo(pathname:string;mode:longint):boolean;
  2280. var retval : LONGINT;
  2281. begin
  2282. pathname:=pathname+#0;
  2283. asm
  2284. lea %ecx,pathname
  2285. inc %ecx
  2286. push $0
  2287. mov mode,%ebx
  2288. or STAT_IFIFO,%ebx
  2289. push %ebx
  2290. push %ecx
  2291. mov $14,%eax
  2292. int $0x80
  2293. addl $12,%esp
  2294. mov %eax,retval
  2295. end;
  2296. mkfifo:=checkreturnvalue(retval,retval)=0;
  2297. LinuxError:=Errno;
  2298. end;
  2299. Procedure AssignStream(Var StreamIn,Streamout:text;Const Prog:String);
  2300. {
  2301. Starts the program in 'Prog' and makes its input and output the
  2302. other end of two pipes, which are the stdin and stdout of a program
  2303. specified in 'Prog'.
  2304. streamout can be used to write to the program, streamin can be used to read
  2305. the output of the program. See the following diagram :
  2306. Parent Child
  2307. STreamout --> Input
  2308. Streamin <-- Output
  2309. }
  2310. var
  2311. pipi,
  2312. pipo : text;
  2313. pid : longint;
  2314. pl : ^Longint;
  2315. begin
  2316. LinuxError:=0;
  2317. AssignPipe(streamin,pipo);
  2318. if Linuxerror<>0 then
  2319. exit;
  2320. AssignPipe(pipi,streamout);
  2321. if Linuxerror<>0 then
  2322. exit;
  2323. pid:=fork;
  2324. if linuxerror<>0 then
  2325. begin
  2326. close(pipi);
  2327. close(pipo);
  2328. close (streamin);
  2329. close (streamout);
  2330. exit;
  2331. end;
  2332. if pid=0 then
  2333. begin
  2334. { We're in the child }
  2335. { Close what we don't need }
  2336. close(streamout);
  2337. close(streamin);
  2338. dup2(pipi,input);
  2339. if linuxerror<>0 then
  2340. halt(127);
  2341. close(pipi);
  2342. dup2(pipo,output);
  2343. if linuxerror<>0 then
  2344. halt (127);
  2345. close(pipo);
  2346. Execl(Prog);
  2347. halt(127);
  2348. end
  2349. else
  2350. begin
  2351. { we're in the parent}
  2352. close(pipo);
  2353. close(pipi);
  2354. {Save the process ID - needed when closing }
  2355. pl:=@(textrec(StreamIn).userdata[2]);
  2356. pl^:=pid;
  2357. textrec(StreamIn).closefunc:=@PCloseText;
  2358. {Save the process ID - needed when closing }
  2359. pl:=@(textrec(StreamOut).userdata[2]);
  2360. pl^:=pid;
  2361. textrec(StreamOut).closefunc:=@PCloseText;
  2362. end;
  2363. end;
  2364. function AssignStream(var StreamIn, StreamOut, StreamErr: Text; const prog: String): LongInt;
  2365. {
  2366. Starts the program in 'prog' and makes its input, output and error output the
  2367. other end of three pipes, which are the stdin, stdout and stderr of a program
  2368. specified in 'prog'.
  2369. StreamOut can be used to write to the program, StreamIn can be used to read
  2370. the output of the program, StreamErr reads the error output of the program.
  2371. See the following diagram :
  2372. Parent Child
  2373. StreamOut --> StdIn (input)
  2374. StreamIn <-- StdOut (output)
  2375. StreamErr <-- StdErr (error output)
  2376. }
  2377. var
  2378. PipeIn, PipeOut, PipeErr: text;
  2379. pid: LongInt;
  2380. pl: ^LongInt;
  2381. begin
  2382. LinuxError := 0;
  2383. AssignStream := -1;
  2384. // Assign pipes
  2385. AssignPipe(StreamIn, PipeOut);
  2386. if LinuxError <> 0 then exit;
  2387. AssignPipe(StreamErr, PipeErr);
  2388. if LinuxError <> 0 then begin
  2389. Close(StreamIn);
  2390. Close(PipeOut);
  2391. exit;
  2392. end;
  2393. AssignPipe(PipeIn, StreamOut);
  2394. if LinuxError <> 0 then begin
  2395. Close(StreamIn);
  2396. Close(PipeOut);
  2397. Close(StreamErr);
  2398. Close(PipeErr);
  2399. exit;
  2400. end;
  2401. // Fork
  2402. pid := Fork;
  2403. if LinuxError <> 0 then begin
  2404. Close(StreamIn);
  2405. Close(PipeOut);
  2406. Close(StreamErr);
  2407. Close(PipeErr);
  2408. Close(PipeIn);
  2409. Close(StreamOut);
  2410. exit;
  2411. end;
  2412. if pid = 0 then begin
  2413. // *** We are in the child ***
  2414. // Close what we don not need
  2415. Close(StreamOut);
  2416. Close(StreamIn);
  2417. Close(StreamErr);
  2418. // Connect pipes
  2419. dup2(PipeIn, Input);
  2420. if LinuxError <> 0 then Halt(127);
  2421. Close(PipeIn);
  2422. dup2(PipeOut, Output);
  2423. if LinuxError <> 0 then Halt(127);
  2424. Close(PipeOut);
  2425. dup2(PipeErr, StdErr);
  2426. if LinuxError <> 0 then Halt(127);
  2427. Close(PipeErr);
  2428. // Execute program
  2429. Execl(Prog);
  2430. Halt(127);
  2431. end else begin
  2432. // *** We are in the parent ***
  2433. Close(PipeErr);
  2434. Close(PipeOut);
  2435. Close(PipeIn);
  2436. // Save the process ID - needed when closing
  2437. pl := @(TextRec(StreamIn).userdata[2]);
  2438. pl^ := pid;
  2439. TextRec(StreamIn).closefunc := @PCloseText;
  2440. // Save the process ID - needed when closing
  2441. pl := @(TextRec(StreamOut).userdata[2]);
  2442. pl^ := pid;
  2443. TextRec(StreamOut).closefunc := @PCloseText;
  2444. // Save the process ID - needed when closing
  2445. pl := @(TextRec(StreamErr).userdata[2]);
  2446. pl^ := pid;
  2447. TextRec(StreamErr).closefunc := @PCloseText;
  2448. AssignStream := pid;
  2449. end;
  2450. end;
  2451. {******************************************************************************
  2452. General information calls
  2453. ******************************************************************************}
  2454. {
  2455. Function Sysinfo(var Info:TSysinfo):Boolean;
  2456. {
  2457. Get system info
  2458. }
  2459. var
  2460. regs : SysCallregs;
  2461. Begin
  2462. regs.reg2:=longint(@info);
  2463. Sysinfo:=SysCall(SysCall_nr_Sysinfo,regs)=0;
  2464. End;
  2465. }
  2466. {
  2467. Function Uname(var unamerec:utsname):Boolean;
  2468. {
  2469. Get machine's names
  2470. }
  2471. var
  2472. regs : SysCallregs;
  2473. Begin
  2474. regs.reg2:=longint(@unamerec);
  2475. Uname:=SysCall(SysCall_nr_uname,regs)=0;
  2476. LinuxError:=Errno;
  2477. End;
  2478. }
  2479. Function GetEnv(P:string):Pchar;
  2480. {
  2481. Searches the environment for a string with name p and
  2482. returns a pchar to it's value.
  2483. A pchar is used to accomodate for strings of length > 255
  2484. }
  2485. var
  2486. ep : ppchar;
  2487. found : boolean;
  2488. Begin
  2489. p:=p+'='; {Else HOST will also find HOSTNAME, etc}
  2490. ep:=envp;
  2491. found:=false;
  2492. if ep<>nil then
  2493. begin
  2494. while (not found) and (ep^<>nil) do
  2495. begin
  2496. if strlcomp(@p[1],(ep^),length(p))=0 then
  2497. found:=true
  2498. else
  2499. inc(ep);
  2500. end;
  2501. end;
  2502. if found then
  2503. getenv:=ep^+length(p)
  2504. else
  2505. getenv:=nil;
  2506. end;
  2507. {
  2508. Function GetDomainName:String;
  2509. {
  2510. Get machines domain name. Returns empty string if not set.
  2511. }
  2512. Var
  2513. Sysn : utsname;
  2514. begin
  2515. Uname(Sysn);
  2516. linuxerror:=errno;
  2517. If linuxerror<>0 then
  2518. getdomainname:=''
  2519. else
  2520. getdomainname:=strpas(@Sysn.domainname[0]);
  2521. end;
  2522. Function GetHostName:String;
  2523. {
  2524. Get machines name. Returns empty string if not set.
  2525. }
  2526. Var
  2527. Sysn : utsname;
  2528. begin
  2529. uname(Sysn);
  2530. linuxerror:=errno;
  2531. If linuxerror<>0 then
  2532. gethostname:=''
  2533. else
  2534. gethostname:=strpas(@Sysn.nodename[0]);
  2535. end;
  2536. }
  2537. {******************************************************************************
  2538. Signal handling calls
  2539. ******************************************************************************}
  2540. Function Kill(Pid:longint;Sig:integer):integer;
  2541. {
  2542. Send signal 'sig' to a process, or a group of processes.
  2543. If Pid > 0 then the signal is sent to pid
  2544. pid=-1 to all processes except process 1
  2545. pid < -1 to process group -pid
  2546. Return value is zero, except for case three, where the return value
  2547. is the number of processes to which the signal was sent.
  2548. }
  2549. var retval : LONGINT;
  2550. begin
  2551. asm
  2552. push Sig
  2553. push Pid
  2554. mov $37,%eax
  2555. int $0x80
  2556. addl $8,%esp
  2557. mov %eax,retval
  2558. end;
  2559. Kill:=checkreturnvalue(retval,retval);
  2560. if kill<0 THEN
  2561. Kill:=0;
  2562. LinuxError:=Errno;
  2563. end;
  2564. Procedure SigAction(Signum:Integer;Var Act,OldAct:PSigActionRec );
  2565. {
  2566. Change action of process upon receipt of a signal.
  2567. Signum specifies the signal (all except SigKill and SigStop).
  2568. If Act is non-nil, it is used to specify the new action.
  2569. If OldAct is non-nil the previous action is saved there.
  2570. }
  2571. var retval : LONGINT;
  2572. begin
  2573. asm
  2574. push oldact
  2575. push act
  2576. push signum
  2577. mov $46,%eax
  2578. int $0x80
  2579. addl $12,%esp
  2580. mov %eax,retval
  2581. end;
  2582. checkreturnvalue(retval,retval);
  2583. LinuxError:=Errno;
  2584. end;
  2585. Procedure SigProcMask(How:Integer;SSet,OldSSet:PSigSet);
  2586. {
  2587. Change the list of currently blocked signals.
  2588. How determines which signals will be blocked :
  2589. SigBlock : Add SSet to the current list of blocked signals
  2590. SigUnBlock : Remove the signals in SSet from the list of blocked signals.
  2591. SigSetMask : Set the list of blocked signals to SSet
  2592. if OldSSet is non-null, the old set will be saved there.
  2593. }
  2594. VAR retval : LONGINT;
  2595. begin
  2596. asm
  2597. push OldSSet
  2598. push SSet
  2599. push How
  2600. mov $48,%eax
  2601. int $0x80
  2602. addl $12,%esp
  2603. mov %eax,retval
  2604. end;
  2605. checkreturnvalue(retval,retval);
  2606. LinuxError:=Errno;
  2607. end;
  2608. Function SigPending:SigSet;
  2609. {
  2610. Allows examination of pending signals. The signal mask of pending
  2611. signals is set in SSet
  2612. }
  2613. Var
  2614. dummy : Sigset;
  2615. retval: LONGINT;
  2616. begin
  2617. asm
  2618. push dummy
  2619. mov $52,%eax
  2620. int $0x80
  2621. addl $4,%esp
  2622. mov %eax,retval
  2623. end;
  2624. sigpending:=checkreturnvalue(retval,dummy);
  2625. LinuxError:=Errno;
  2626. end;
  2627. Procedure SigSuspend(Mask:Sigset);
  2628. {
  2629. Set the signal mask with Mask, and suspend the program until a signal
  2630. is received.
  2631. }
  2632. Var
  2633. retval: LONGINT;
  2634. begin
  2635. asm
  2636. push mask
  2637. mov $111,%eax
  2638. int $0x80
  2639. addl $4,%esp
  2640. mov %eax,retval
  2641. end;
  2642. checkreturnvalue(retval,retval);
  2643. LinuxError:=Errno;
  2644. end;
  2645. {
  2646. Function Signal(Signum:Integer;Handler:SignalHandler):SignalHandler;
  2647. {
  2648. Install a new handler for signal Signum.
  2649. The old signal handler is returned.
  2650. This call does, in fact, the same as SigAction.
  2651. }
  2652. begin
  2653. sr.reg2:=signum;
  2654. sr.reg3:=longint(handler);
  2655. Linuxerror:=SysCall(Syscall_nr_signal,sr);
  2656. If linuxerror=Sig_Err then
  2657. begin
  2658. Signal:=nil;
  2659. Linuxerror:=errno;
  2660. end
  2661. else
  2662. begin
  2663. Signal:=signalhandler(Linuxerror);
  2664. linuxerror:=0;
  2665. end;
  2666. end;
  2667. }
  2668. procedure SigRaise(sig:integer);
  2669. begin
  2670. Kill(GetPid,Sig);
  2671. end;
  2672. {
  2673. Function Alarm(Sec : Longint) : longint;
  2674. Var Sr : Syscallregs;
  2675. begin
  2676. sr.reg2:=Sec;
  2677. Alarm:=Syscall(syscall_nr_alarm,sr);
  2678. end;
  2679. Procedure Pause;
  2680. Var Sr : Syscallregs;
  2681. begin
  2682. syscall(syscall_nr_pause,sr);
  2683. end;
  2684. }
  2685. {******************************************************************************
  2686. IOCtl and Termios calls
  2687. ******************************************************************************}
  2688. Function IOCtl(Handle,Ndx: Longint;Data: Pointer):boolean;
  2689. {
  2690. Interface to Unix ioctl call.
  2691. Performs various operations on the filedescriptor Handle.
  2692. Ndx describes the operation to perform.
  2693. Data points to data needed for the Ndx function. The structure of this
  2694. data is function-dependent.
  2695. }
  2696. var
  2697. retval : longint;
  2698. begin
  2699. asm
  2700. push data
  2701. push ndx
  2702. push handle
  2703. mov $54,%eax
  2704. int $0x80
  2705. addl $12,%esp
  2706. mov %eax,retval
  2707. end;
  2708. IOctl:=checkreturnvalue(retval,retval)=0;
  2709. LinuxError:=Errno;
  2710. end;
  2711. Function TCGetAttr(fd:longint;var tios:TermIOS):boolean;
  2712. begin
  2713. TCGetAttr:=IOCtl(fd,TCGETS,@tios);
  2714. end;
  2715. Function TCSetAttr(fd:longint;OptAct:longint;var tios:TermIOS):boolean;
  2716. var
  2717. nr:longint;
  2718. begin
  2719. case OptAct of
  2720. TCSANOW : nr:=TCSETS;
  2721. TCSADRAIN : nr:=TCSETSW;
  2722. TCSAFLUSH : nr:=TCSETSF;
  2723. else
  2724. begin
  2725. ErrNo:=Sys_EINVAL;
  2726. TCSetAttr:=false;
  2727. exit;
  2728. end;
  2729. end;
  2730. TCSetAttr:=IOCtl(fd,nr,@Tios);
  2731. end;
  2732. Procedure CFSetISpeed(var tios:TermIOS;speed:Longint);
  2733. begin
  2734. tios.c_cflag:=(tios.c_cflag and (not CBAUD)) or speed;
  2735. end;
  2736. Procedure CFSetOSpeed(var tios:TermIOS;speed:Longint);
  2737. begin
  2738. CFSetISpeed(tios,speed);
  2739. end;
  2740. Procedure CFMakeRaw(var tios:TermIOS);
  2741. begin
  2742. with tios do
  2743. begin
  2744. c_iflag:=c_iflag and (not (IGNBRK or BRKINT or PARMRK or ISTRIP or
  2745. INLCR or IGNCR or ICRNL or IXON));
  2746. c_oflag:=c_oflag and (not OPOST);
  2747. c_lflag:=c_lflag and (not (ECHO or ECHONL or ICANON or ISIG or IEXTEN));
  2748. c_cflag:=(c_cflag and (not (CSIZE or PARENB))) or CS8;
  2749. end;
  2750. end;
  2751. Function TCSendBreak(fd,duration:longint):boolean;
  2752. begin
  2753. TCSendBreak:=IOCtl(fd,TCSBRK,pointer(duration));
  2754. end;
  2755. Function TCSetPGrp(fd,id:longint):boolean;
  2756. begin
  2757. TCSetPGrp:=IOCtl(fd,TIOCSPGRP,pointer(id));
  2758. end;
  2759. Function TCGetPGrp(fd:longint;var id:longint):boolean;
  2760. begin
  2761. TCGetPGrp:=IOCtl(fd,TIOCGPGRP,@id);
  2762. end;
  2763. Function TCDrain(fd:longint):boolean;
  2764. begin
  2765. TCDrain:=IOCtl(fd,TCSBRK,pointer(1));
  2766. end;
  2767. Function TCFlow(fd,act:longint):boolean;
  2768. begin
  2769. TCFlow:=IOCtl(fd,TCXONC,pointer(act));
  2770. end;
  2771. Function TCFlush(fd,qsel:longint):boolean;
  2772. begin
  2773. TCFlush:=IOCtl(fd,TCFLSH,pointer(qsel));
  2774. end;
  2775. Function IsATTY(Handle:Longint):Boolean;
  2776. {
  2777. Check if the filehandle described by 'handle' is a TTY (Terminal)
  2778. }
  2779. var
  2780. t : Termios;
  2781. begin
  2782. IsAtty:=TCGetAttr(Handle,t);
  2783. end;
  2784. Function IsATTY(f: text):Boolean;
  2785. {
  2786. Idem as previous, only now for text variables.
  2787. }
  2788. begin
  2789. IsATTY:=IsaTTY(textrec(f).handle);
  2790. end;
  2791. function TTYName(Handle:Longint):string;
  2792. {
  2793. Return the name of the current tty described by handle f.
  2794. returns empty string in case of an error.
  2795. }
  2796. Const
  2797. dev='/dev';
  2798. var
  2799. name : string;
  2800. st : stat;
  2801. mydev,
  2802. myino : longint;
  2803. dirstream : pdir;
  2804. d : pdirent;
  2805. begin
  2806. TTYName:='';
  2807. fstat(handle,st);
  2808. if (errno<>0) and isatty (handle) then
  2809. exit;
  2810. mydev:=st.dev;
  2811. myino:=st.ino;
  2812. dirstream:=opendir(dev);
  2813. if (linuxerror<>0) then
  2814. exit;
  2815. d:=Readdir(dirstream);
  2816. while (d<>nil) do
  2817. begin
  2818. if (d^.ino=myino) then
  2819. begin
  2820. name:=dev+'/'+strpas(@(d^.name));
  2821. fstat(name,st);
  2822. if (linuxerror=0) and (st.dev=mydev) then
  2823. begin
  2824. closedir(dirstream);
  2825. ttyname:=name;
  2826. exit;
  2827. end;
  2828. end;
  2829. d:=Readdir(dirstream);
  2830. end;
  2831. closedir(dirstream);
  2832. end;
  2833. function TTYName(var F:Text):string;
  2834. {
  2835. Idem as previous, only now for text variables;
  2836. }
  2837. begin
  2838. TTYName:=TTYName(textrec(f).handle);
  2839. end;
  2840. {******************************************************************************
  2841. Utility calls
  2842. ******************************************************************************}
  2843. Function Octal(l:longint):longint;
  2844. {
  2845. Convert an octal specified number to decimal;
  2846. }
  2847. var
  2848. octnr,
  2849. oct : longint;
  2850. begin
  2851. octnr:=0;
  2852. oct:=0;
  2853. while (l>0) do
  2854. begin
  2855. oct:=oct or ((l mod 10) shl octnr);
  2856. l:=l div 10;
  2857. inc(octnr,3);
  2858. end;
  2859. Octal:=oct;
  2860. end;
  2861. Function StringToPPChar(Var S:STring):ppchar;
  2862. {
  2863. Create a PPChar to structure of pchars which are the arguments specified
  2864. in the string S. Especially usefull for creating an ArgV for Exec-calls
  2865. }
  2866. var
  2867. nr : longint;
  2868. Buf : ^char;
  2869. p : ppchar;
  2870. begin
  2871. s:=s+#0;
  2872. buf:=@s[1];
  2873. nr:=0;
  2874. while(buf^<>#0) do
  2875. begin
  2876. while (buf^ in [' ',#8,#10]) do
  2877. inc(buf);
  2878. inc(nr);
  2879. while not (buf^ in [' ',#0,#8,#10]) do
  2880. inc(buf);
  2881. end;
  2882. getmem(p,nr*4);
  2883. StringToPPChar:=p;
  2884. if p=nil then
  2885. begin
  2886. LinuxError:=sys_enomem;
  2887. exit;
  2888. end;
  2889. buf:=@s[1];
  2890. while (buf^<>#0) do
  2891. begin
  2892. while (buf^ in [' ',#8,#10]) do
  2893. begin
  2894. buf^:=#0;
  2895. inc(buf);
  2896. end;
  2897. p^:=buf;
  2898. inc(p);
  2899. p^:=nil;
  2900. while not (buf^ in [' ',#0,#8,#10]) do
  2901. inc(buf);
  2902. end;
  2903. end;
  2904. Function FExpand(Const Path:PathStr):PathStr;
  2905. var
  2906. temp : pathstr;
  2907. i,j : longint;
  2908. p : pchar;
  2909. Begin
  2910. {Remove eventual drive - doesn't exist in Linux}
  2911. if path[2]=':' then
  2912. i:=3
  2913. else
  2914. i:=1;
  2915. temp:='';
  2916. {Replace ~/ with $HOME}
  2917. if (path[i]='~') and ((i+1>length(path)) or (path[i+1]='/')) then
  2918. begin
  2919. p:=getenv('HOME');
  2920. if not (p=nil) then
  2921. Insert(StrPas(p),temp,i);
  2922. i:=1;
  2923. temp:=temp+Copy(Path,2,255);
  2924. end;
  2925. {Do we have an absolute path ? No - prefix the current dir}
  2926. if temp='' then
  2927. begin
  2928. if path[i]<>'/' then
  2929. begin
  2930. {$I-}
  2931. getdir(0,temp);
  2932. {$I+}
  2933. if ioresult<>0 then;
  2934. end
  2935. else
  2936. inc(i);
  2937. temp:=temp+'/'+copy(path,i,length(path)-i+1)+'/';
  2938. end;
  2939. {First remove all references to '/./'}
  2940. while pos('/./',temp)<>0 do
  2941. delete(temp,pos('/./',temp),2);
  2942. {Now remove also all references to '/../' + of course previous dirs..}
  2943. repeat
  2944. i:=pos('/../',temp);
  2945. {Find the pos of the previous dir}
  2946. if i>1 then
  2947. begin
  2948. j:=i-1;
  2949. while (j>1) and (temp[j]<>'/') do
  2950. dec (j);{temp[1] is always '/'}
  2951. delete(temp,j,i-j+3);
  2952. end
  2953. else
  2954. if i=1 then {i=1, so we have temp='/../something', just delete '/../'}
  2955. delete(temp,1,3);
  2956. until i=0;
  2957. { Remove ending /.. }
  2958. i:=pos('/..',temp);
  2959. if (i<>0) and (i =length(temp)-2) then
  2960. begin
  2961. j:=i-1;
  2962. while (j>1) and (temp[j]<>'/') do
  2963. dec (j);
  2964. delete (temp,j,i-j+3);
  2965. end;
  2966. { if last character is / then remove it - dir is also a file :-) }
  2967. if (length(temp)>0) and (temp[length(temp)]='/') then
  2968. dec(byte(temp[0]));
  2969. fexpand:=temp;
  2970. End;
  2971. Function FSearch(const path:pathstr;dirlist:string):pathstr;
  2972. {
  2973. Searches for a file 'path' in the list of direcories in 'dirlist'.
  2974. returns an empty string if not found. Wildcards are NOT allowed.
  2975. If dirlist is empty, it is set to '.'
  2976. }
  2977. Var
  2978. NewDir : PathStr;
  2979. p1 : Longint;
  2980. Info : Stat;
  2981. Begin
  2982. {Replace ':' with ';'}
  2983. for p1:=1to length(dirlist) do
  2984. if dirlist[p1]=':' then
  2985. dirlist[p1]:=';';
  2986. {Check for WildCards}
  2987. If (Pos('?',Path) <> 0) or (Pos('*',Path) <> 0) Then
  2988. FSearch:='' {No wildcards allowed in these things.}
  2989. Else
  2990. Begin
  2991. Dirlist:='.;'+dirlist;{Make sure current dir is first to be searched.}
  2992. Repeat
  2993. p1:=Pos(';',DirList);
  2994. If p1=0 Then
  2995. p1:=255;
  2996. NewDir:=Copy(DirList,1,P1 - 1);
  2997. if NewDir[Length(NewDir)]<>'/' then
  2998. NewDir:=NewDir+'/';
  2999. NewDir:=NewDir+Path;
  3000. Delete(DirList,1,p1);
  3001. if FStat(NewDir,Info) then
  3002. Begin
  3003. If Pos('./',NewDir)=1 Then
  3004. Delete(NewDir,1,2);
  3005. {DOS strips off an initial .\}
  3006. End
  3007. Else
  3008. NewDir:='';
  3009. Until (DirList='') or (Length(NewDir) > 0);
  3010. FSearch:=NewDir;
  3011. End;
  3012. End;
  3013. Procedure FSplit(const Path:PathStr;Var Dir:DirStr;Var Name:NameStr;Var Ext:ExtStr);
  3014. Var
  3015. DotPos,SlashPos,i : longint;
  3016. Begin
  3017. SlashPos:=0;
  3018. DotPos:=256;
  3019. i:=Length(Path);
  3020. While (i>0) and (SlashPos=0) Do
  3021. Begin
  3022. If (DotPos=256) and (Path[i]='.') Then
  3023. DotPos:=i;
  3024. If (Path[i]='/') Then
  3025. SlashPos:=i;
  3026. Dec(i);
  3027. End;
  3028. Ext:=Copy(Path,DotPos,255);
  3029. Dir:=Copy(Path,1,SlashPos);
  3030. Name:=Copy(Path,SlashPos + 1,DotPos - SlashPos - 1);
  3031. End;
  3032. Function Dirname(Const path:pathstr):pathstr;
  3033. {
  3034. This function returns the directory part of a complete path.
  3035. Unless the directory is root '/', The last character is not
  3036. a slash.
  3037. }
  3038. var
  3039. Dir : PathStr;
  3040. Name : NameStr;
  3041. Ext : ExtStr;
  3042. begin
  3043. FSplit(Path,Dir,Name,Ext);
  3044. if length(Dir)>1 then
  3045. Delete(Dir,length(Dir),1);
  3046. DirName:=Dir;
  3047. end;
  3048. Function Basename(Const path:pathstr;Const suf:pathstr):pathstr;
  3049. {
  3050. This function returns the filename part of a complete path. If suf is
  3051. supplied, it is cut off the filename.
  3052. }
  3053. var
  3054. Dir : PathStr;
  3055. Name : NameStr;
  3056. Ext : ExtStr;
  3057. begin
  3058. FSplit(Path,Dir,Name,Ext);
  3059. if Suf<>Ext then
  3060. Name:=Name+Ext;
  3061. BaseName:=Name;
  3062. end;
  3063. Function FNMatch(const Pattern,Name:string):Boolean;
  3064. Var
  3065. LenPat,LenName : longint;
  3066. Function DoFNMatch(i,j:longint):Boolean;
  3067. Var
  3068. Found : boolean;
  3069. Begin
  3070. Found:=true;
  3071. While Found and (i<=LenPat) Do
  3072. Begin
  3073. Case Pattern[i] of
  3074. '?' : Found:=(j<=LenName);
  3075. '*' : Begin
  3076. {find the next character in pattern, different of ? and *}
  3077. while Found and (i<LenPat) do
  3078. begin
  3079. inc(i);
  3080. case Pattern[i] of
  3081. '*' : ;
  3082. '?' : begin
  3083. inc(j);
  3084. Found:=(j<=LenName);
  3085. end;
  3086. else
  3087. Found:=false;
  3088. end;
  3089. end;
  3090. {Now, find in name the character which i points to, if the * or ?
  3091. wasn't the last character in the pattern, else, use up all the
  3092. chars in name}
  3093. Found:=true;
  3094. if (i<=LenPat) then
  3095. begin
  3096. repeat
  3097. {find a letter (not only first !) which maches pattern[i]}
  3098. while (j<=LenName) and (name[j]<>pattern[i]) do
  3099. inc (j);
  3100. if (j<LenName) then
  3101. begin
  3102. if DoFnMatch(i+1,j+1) then
  3103. begin
  3104. i:=LenPat;
  3105. j:=LenName;{we can stop}
  3106. Found:=true;
  3107. end
  3108. else
  3109. inc(j);{We didn't find one, need to look further}
  3110. end;
  3111. until (j>=LenName);
  3112. end
  3113. else
  3114. j:=LenName;{we can stop}
  3115. end;
  3116. else {not a wildcard character in pattern}
  3117. Found:=(j<=LenName) and (pattern[i]=name[j]);
  3118. end;
  3119. inc(i);
  3120. inc(j);
  3121. end;
  3122. DoFnMatch:=Found and (j>LenName);
  3123. end;
  3124. Begin {start FNMatch}
  3125. LenPat:=Length(Pattern);
  3126. LenName:=Length(Name);
  3127. FNMatch:=DoFNMatch(1,1);
  3128. End;
  3129. Procedure Globfree(var p : pglob);
  3130. {
  3131. Release memory occupied by pglob structure, and names in it.
  3132. sets p to nil.
  3133. }
  3134. var
  3135. temp : pglob;
  3136. begin
  3137. while p<>nil do
  3138. begin
  3139. temp:=p^.next;
  3140. if p^.name<>nil then
  3141. freemem(p^.name,strlen(p^.name)+1);
  3142. dispose(p);
  3143. p:=temp;
  3144. end;
  3145. end;
  3146. Function Glob(Const path:pathstr):pglob;
  3147. {
  3148. Fills a tglob structure with entries matching path,
  3149. and returns a pointer to it. Returns nil on error,
  3150. linuxerror is set accordingly.
  3151. }
  3152. var
  3153. temp : string[255];
  3154. thedir : pdir;
  3155. buffer : pdirent;
  3156. root,run : pglob;
  3157. begin
  3158. { Get directory }
  3159. if dirname(path)='' then
  3160. temp:='.'
  3161. else
  3162. temp:=dirname(path);
  3163. temp:=temp+#0;
  3164. thedir:=opendir(@temp[1]);
  3165. if thedir=nil then
  3166. begin
  3167. glob:=nil;
  3168. linuxerror:=errno;
  3169. exit;
  3170. end;
  3171. temp:=basename(path,'');{ get the pattern }
  3172. if thedir^.fd<0 then
  3173. begin
  3174. linuxerror:=errno;
  3175. glob:=nil;
  3176. exit;
  3177. end;
  3178. {get the entries}
  3179. new(root);
  3180. root^.next:=nil;
  3181. root^.name:=nil;
  3182. run:=root;
  3183. repeat
  3184. buffer:=Sys_readdir(thedir);
  3185. if buffer<>nil then
  3186. begin
  3187. if fnmatch(temp,strpas(@(buffer^.name[0]))) then
  3188. begin
  3189. { get memory for pglob }
  3190. new(run^.next);
  3191. if run^.next=nil then
  3192. begin
  3193. linuxerror:=Sys_ENOMEM;
  3194. globfree(root);
  3195. glob:=nil;
  3196. exit;
  3197. end
  3198. else
  3199. begin
  3200. run:=run^.next;
  3201. run^.next:=nil;
  3202. end;
  3203. { Get memory for name }
  3204. getmem(run^.name,strlen(@(buffer^.name[0]))+1);
  3205. if run^.name=nil then
  3206. begin
  3207. linuxerror:=Sys_ENOMEM;
  3208. globfree(root);
  3209. glob:=nil;
  3210. exit;
  3211. end;
  3212. move(buffer^.name[0],run^.name^,strlen(@(buffer^.name[0]))+1);
  3213. end;{ if fnmatch }
  3214. end { buffer <> nil }
  3215. else
  3216. begin
  3217. run:=root;
  3218. if root^.next<>nil then
  3219. root:=root^.next;{ put root on first entry}
  3220. if run<>nil then
  3221. begin
  3222. run^.next:=nil;
  3223. globfree(run);
  3224. end;
  3225. end;
  3226. until buffer=nil;
  3227. if root^.name=nil then
  3228. begin
  3229. dispose(root);
  3230. linuxerror:=0;
  3231. glob:=nil;
  3232. end
  3233. else
  3234. glob:=root;
  3235. end;
  3236. {--------------------------------
  3237. FiledescriptorSets
  3238. --------------------------------}
  3239. Procedure FD_Zero(var fds:fdSet);
  3240. {
  3241. Clear the set of filedescriptors
  3242. }
  3243. begin
  3244. FillChar(fds,sizeof(fdSet),0);
  3245. end;
  3246. Procedure FD_Clr(fd:longint;var fds:fdSet);
  3247. {
  3248. Remove fd from the set of filedescriptors
  3249. }
  3250. begin
  3251. fds[fd shr 5]:=fds[fd shr 5] and (not (1 shl (fd and 31)));
  3252. end;
  3253. Procedure FD_Set(fd:longint;var fds:fdSet);
  3254. {
  3255. Add fd to the set of filedescriptors
  3256. }
  3257. begin
  3258. fds[fd shr 5]:=fds[fd shr 5] or (1 shl (fd and 31));
  3259. end;
  3260. Function FD_IsSet(fd:longint;var fds:fdSet):boolean;
  3261. {
  3262. Test if fd is part of the set of filedescriptors
  3263. }
  3264. begin
  3265. FD_IsSet:=((fds[fd shr 5] and (1 shl (fd and 31)))<>0);
  3266. end;
  3267. Function GetFS (var T:Text):longint;
  3268. {
  3269. Get File Descriptor of a text file.
  3270. }
  3271. begin
  3272. if textrec(t).mode=fmclosed then
  3273. exit(-1)
  3274. else
  3275. GETFS:=textrec(t).Handle
  3276. end;
  3277. Function GetFS(Var F:File):longint;
  3278. {
  3279. Get File Descriptor of an unTyped file.
  3280. }
  3281. begin
  3282. { Handle and mode are on the same place in textrec and filerec. }
  3283. if filerec(f).mode=fmclosed then
  3284. exit(-1)
  3285. else
  3286. GETFS:=filerec(f).Handle
  3287. end;
  3288. {--------------------------------
  3289. Stat.Mode Macro's
  3290. --------------------------------}
  3291. Function S_ISLNK(m:word):boolean;
  3292. {
  3293. Check mode field of inode for link.
  3294. }
  3295. begin
  3296. S_ISLNK:=(m and STAT_IFMT)=STAT_IFLNK;
  3297. end;
  3298. Function S_ISREG(m:word):boolean;
  3299. {
  3300. Check mode field of inode for regular file.
  3301. }
  3302. begin
  3303. S_ISREG:=(m and STAT_IFMT)=STAT_IFREG;
  3304. end;
  3305. Function S_ISDIR(m:word):boolean;
  3306. {
  3307. Check mode field of inode for directory.
  3308. }
  3309. begin
  3310. S_ISDIR:=(m and STAT_IFMT)=STAT_IFDIR;
  3311. end;
  3312. Function S_ISCHR(m:word):boolean;
  3313. {
  3314. Check mode field of inode for character device.
  3315. }
  3316. begin
  3317. S_ISCHR:=(m and STAT_IFMT)=STAT_IFCHR;
  3318. end;
  3319. Function S_ISBLK(m:word):boolean;
  3320. {
  3321. Check mode field of inode for block device.
  3322. }
  3323. begin
  3324. S_ISBLK:=(m and STAT_IFMT)=STAT_IFBLK;
  3325. end;
  3326. Function S_ISFIFO(m:word):boolean;
  3327. {
  3328. Check mode field of inode for named pipe (FIFO).
  3329. }
  3330. begin
  3331. S_ISFIFO:=(m and STAT_IFMT)=STAT_IFIFO;
  3332. end;
  3333. Function S_ISSOCK(m:word):boolean;
  3334. {
  3335. Check mode field of inode for socket.
  3336. }
  3337. begin
  3338. S_ISSOCK:=(m and STAT_IFMT)=STAT_IFSOCK;
  3339. end;
  3340. {--------------------------------
  3341. Memory functions
  3342. --------------------------------}
  3343. function MMap(const m:tmmapargs):longint;
  3344. Var
  3345. Retval : longint;
  3346. begin
  3347. asm
  3348. push $0
  3349. mov m,%esi
  3350. push tmmapargs.offset(%esi)
  3351. push tmmapargs.fd(%esi)
  3352. push tmmapargs.flags(%esi)
  3353. push tmmapargs.prot(%esi)
  3354. push tmmapargs.size(%esi)
  3355. push tmmapargs.address(%esi)
  3356. mov $197,%eax
  3357. int $0x80
  3358. addl $28,%esp
  3359. mov %eax,retval
  3360. end;
  3361. checkreturnvalue(retval,retval);
  3362. LinuxError:=Errno;
  3363. end;
  3364. {--------------------------------
  3365. Port IO functions
  3366. --------------------------------}
  3367. {
  3368. Function IOperm (From,Num : Cardinal; Value : Longint) : boolean;
  3369. {
  3370. Set permissions on NUM ports starting with port FROM to VALUE
  3371. this works ONLY as root.
  3372. }
  3373. Var
  3374. Sr : Syscallregs;
  3375. begin
  3376. Sr.Reg2:=From;
  3377. Sr.Reg3:=Num;
  3378. Sr.Reg4:=Value;
  3379. IOPerm:=Syscall(Syscall_nr_ioperm,sr)=0;
  3380. LinuxError:=Errno;
  3381. end;
  3382. }
  3383. {$IFDEF I386}
  3384. {$asmmode direct}
  3385. Procedure WritePort (Port : Longint; Value : Byte);
  3386. {
  3387. Writes 'Value' to port 'Port'
  3388. }
  3389. begin
  3390. asm
  3391. movl 8(%ebp),%edx
  3392. movb 12(%ebp),%al
  3393. outb %al,%dx
  3394. end ['EAX','EDX'];
  3395. end;
  3396. Procedure WritePort (Port : Longint; Value : Word);
  3397. {
  3398. Writes 'Value' to port 'Port'
  3399. }
  3400. begin
  3401. asm
  3402. movl 8(%ebp),%edx
  3403. movw 12(%ebp),%ax
  3404. outw %ax,%dx
  3405. end ['EAX','EDX'];
  3406. end;
  3407. Procedure WritePort (Port : Longint; Value : Longint);
  3408. {
  3409. Writes 'Value' to port 'Port'
  3410. }
  3411. begin
  3412. asm
  3413. movl 8(%ebp),%edx
  3414. movl 12(%ebp),%eax
  3415. outl %eax,%dx
  3416. end ['EAX','EDX'];
  3417. end;
  3418. Procedure WritePortl (Port : Longint; Var Buf; Count: longint);
  3419. {
  3420. Writes 'Count' longints from 'Buf' to Port
  3421. }
  3422. begin
  3423. asm
  3424. movl 16(%ebp),%ecx
  3425. movl 12(%ebp),%esi
  3426. movl 8(%ebp),%edx
  3427. cld
  3428. rep
  3429. outsl
  3430. end ['ECX','ESI','EDX'];
  3431. end;
  3432. Procedure WritePortW (Port : Longint; Var Buf; Count: longint);
  3433. {
  3434. Writes 'Count' words from 'Buf' to Port
  3435. }
  3436. begin
  3437. asm
  3438. movl 16(%ebp),%ecx
  3439. movl 12(%ebp),%esi
  3440. movl 8(%ebp),%edx
  3441. cld
  3442. rep
  3443. outsw
  3444. end ['ECX','ESI','EDX'];
  3445. end;
  3446. Procedure WritePortB (Port : Longint; Var Buf; Count: longint);
  3447. {
  3448. Writes 'Count' bytes from 'Buf' to Port
  3449. }
  3450. begin
  3451. asm
  3452. movl 16(%ebp),%ecx
  3453. movl 12(%ebp),%esi
  3454. movl 8(%ebp),%edx
  3455. cld
  3456. rep
  3457. outsb
  3458. end ['ECX','ESI','EDX'];
  3459. end;
  3460. Procedure ReadPort (Port : Longint; Var Value : Byte);
  3461. {
  3462. Reads 'Value' from port 'Port'
  3463. }
  3464. begin
  3465. asm
  3466. movl 8(%ebp),%edx
  3467. inb %dx,%al
  3468. andl $255,%eax
  3469. movl %eax,12(%ebp)
  3470. end ['EAX','EDX'];
  3471. end;
  3472. Procedure ReadPort (Port : Longint; Var Value : Word);
  3473. {
  3474. Reads 'Value' from port 'Port'
  3475. }
  3476. begin
  3477. asm
  3478. movl 8(%ebp),%edx
  3479. inw %dx,%ax
  3480. andl $65535,%eax
  3481. movl %eax,12(%ebp)
  3482. end ['EAX','EDX'];
  3483. end;
  3484. Procedure ReadPort (Port : Longint; Var Value : Longint);
  3485. {
  3486. Reads 'Value' from port 'Port'
  3487. }
  3488. begin
  3489. asm
  3490. movl 8(%ebp),%edx
  3491. inl %dx,%eax
  3492. movl %eax,12(%ebp)
  3493. end ['EAX','EDX'];
  3494. end;
  3495. Procedure ReadPortL (Port : Longint; Var Buf; Count: longint);
  3496. {
  3497. Reads 'Count' longints from port 'Port' to 'Buf'.
  3498. }
  3499. begin
  3500. asm
  3501. movl 16(%ebp),%ecx
  3502. movl 12(%ebp),%edi
  3503. movl 8(%ebp),%edx
  3504. cld
  3505. rep
  3506. insl
  3507. end ['ECX','EDI','EDX'];
  3508. end;
  3509. Procedure ReadPortW (Port : Longint; Var Buf; Count: longint);
  3510. {
  3511. Reads 'Count' words from port 'Port' to 'Buf'.
  3512. }
  3513. begin
  3514. asm
  3515. movl 16(%ebp),%ecx
  3516. movl 12(%ebp),%edi
  3517. movl 8(%ebp),%edx
  3518. cld
  3519. rep
  3520. insw
  3521. end ['ECX','EDI','EDX'];
  3522. end;
  3523. Procedure ReadPortB (Port : Longint; Var Buf; Count: longint);
  3524. {
  3525. Reads 'Count' bytes from port 'Port' to 'Buf'.
  3526. }
  3527. begin
  3528. asm
  3529. movl 16(%ebp),%ecx
  3530. movl 12(%ebp),%edi
  3531. movl 8(%ebp),%edx
  3532. cld
  3533. rep
  3534. insb
  3535. end ['ECX','EDI','EDX'];
  3536. end;
  3537. {$ENDIF}
  3538. Initialization
  3539. InitLocalTime;
  3540. finalization
  3541. DoneLocalTime;
  3542. End.
  3543. {
  3544. $Log$
  3545. Revision 1.3 2000-02-04 16:53:26 marco
  3546. * Finished Linux (and rest syscalls) roughly. Some things still need to be
  3547. tested, and checked (off_t calls specially)
  3548. Revision 1.2 2000/02/04 12:05:04 marco
  3549. * a few functions added.
  3550. Revision 1.1 2000/02/03 17:03:36 marco
  3551. * initial version. Ported till line +/- 2000
  3552. }