linux.pp 86 KB

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