linux.pp 85 KB

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