unix.pp 38 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427
  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. BSD parts (c) 2000 by Marco van de Voort
  6. members of the Free Pascal development team.
  7. See the file COPYING.FPC, included in this distribution,
  8. for details about the copyright.
  9. This program is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY;without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  12. **********************************************************************}
  13. Unit Unix;
  14. Interface
  15. Uses BaseUnix,UnixType;
  16. {$i aliasptp.inc}
  17. //type
  18. // pathstr = string[255];
  19. {$define POSIXWORKAROUND}
  20. { Get Types and Constants }
  21. {$i sysconst.inc}
  22. {Get error numbers, some more signal definitions and other OS dependant
  23. types (that are not POSIX) }
  24. {i errno.inc}
  25. {$I signal.inc}
  26. {$i ostypes.inc}
  27. // We init to zero to be able to put timezone stuff under IFDEF, and still
  28. // keep the code working.
  29. var
  30. Tzseconds : Longint {$ifndef ver1_0} = 0 {$endif};
  31. {********************
  32. File
  33. ********************}
  34. Const
  35. P_IN = 1; // pipes (?)
  36. P_OUT = 2;
  37. Const
  38. LOCK_SH = 1; // flock constants ?
  39. LOCK_EX = 2;
  40. LOCK_UN = 8;
  41. LOCK_NB = 4;
  42. Type
  43. Tpipe = baseunix.tfildes; // compability.
  44. {******************************************************************************
  45. Procedure/Functions
  46. ******************************************************************************}
  47. {**************************
  48. Time/Date Handling
  49. ***************************}
  50. var
  51. tzdaylight : boolean;
  52. tzname : array[boolean] of pchar;
  53. {$IFNDEF DONT_READ_TIMEZONE} // allows to disable linking in and trying for platforms
  54. // it doesn't (yet) work for.
  55. { timezone support }
  56. procedure GetLocalTimezone(timer:cint;var leap_correct,leap_hit:cint);
  57. procedure GetLocalTimezone(timer:cint);
  58. procedure ReadTimezoneFile(fn:string);
  59. function GetTimezoneFile:string;
  60. {$ENDIF}
  61. {**************************
  62. Process Handling
  63. ***************************}
  64. //
  65. // These are much better, in nearly all ways.
  66. //
  67. function FpExecLE (Const PathName:AnsiString;const S:Array Of AnsiString;MyEnv:ppchar):cint;
  68. function FpExecL(Const PathName:AnsiString;const S:Array Of AnsiString):cint;
  69. function FpExecLP(Const PathName:AnsiString;const S:Array Of AnsiString):cint;
  70. function FpExecV(Const PathName:AnsiString;args:ppchar):cint;
  71. function FpExecVP(Const PathName:AnsiString;args:ppchar):cint;
  72. function FpExecVPE(Const PathName:AnsiString;args,env:ppchar):cint;
  73. Function Shell (const Command:String):cint;
  74. Function Shell (const Command:AnsiString):cint;
  75. Function fpSystem(const Command:AnsiString):cint;
  76. Function WaitProcess (Pid:cint):cint; { like WaitPid(PID,@result,0) Handling of Signal interrupts (errno=EINTR), returning the Exitcode of Process (>=0) or -Status if terminated}
  77. Function WIFSTOPPED (Status: Integer): Boolean;
  78. Function W_EXITCODE (ReturnCode, Signal: Integer): Integer;
  79. Function W_STOPCODE (Signal: Integer): Integer;
  80. {**************************
  81. File Handling
  82. ***************************}
  83. {$ifndef FPC_USE_LIBC} // defined using cdecl for libc.
  84. Function fsync (fd : cint) : cint;
  85. Function fpFlock (fd,mode : cint) : cint ;
  86. Function fStatFS (Fd: cint;Var Info:tstatfs):cint;
  87. Function StatFS (Path:pchar;Var Info:tstatfs):cint;
  88. {$endif}
  89. Function fpFlock (var T : text;mode : cint) : cint;
  90. Function fpFlock (var F : File;mode : cint) : cint;
  91. Function SelectText (var T:Text;TimeOut :PTimeVal):cint;
  92. Function SelectText (var T:Text;TimeOut :cint):cint;
  93. {**************************
  94. Directory Handling
  95. ***************************}
  96. procedure SeekDir(p:pdir;loc:clong);
  97. function TellDir(p:pdir):clong;
  98. {**************************
  99. Pipe/Fifo/Stream
  100. ***************************}
  101. Function AssignPipe (var pipe_in,pipe_out:cint):cint;
  102. Function AssignPipe (var pipe_in,pipe_out:text):cint;
  103. Function AssignPipe (var pipe_in,pipe_out:file):cint;
  104. //Function PClose (Var F:text) : cint;
  105. //Function PClose (Var F:file) : cint;
  106. Function POpen (var F:text;const Prog:String;rw:char):cint;
  107. Function POpen (var F:file;const Prog:String;rw:char):cint;
  108. Function AssignStream(Var StreamIn,Streamout:text;Const Prog:ansiString;const args : array of ansistring) : cint;
  109. Function AssignStream(Var StreamIn,Streamout,streamerr:text;Const Prog:ansiString;const args : array of ansistring) : cint;
  110. Function GetDomainName:String;
  111. Function GetHostName:String;
  112. {**************************
  113. Memory functions
  114. ***************************}
  115. const
  116. PROT_READ = $1; { page can be read }
  117. PROT_WRITE = $2; { page can be written }
  118. PROT_EXEC = $4; { page can be executed }
  119. PROT_NONE = $0; { page can not be accessed }
  120. MAP_SHARED = $1; { Share changes }
  121. // MAP_PRIVATE = $2; { Changes are private }
  122. MAP_TYPE = $f; { Mask for type of mapping }
  123. MAP_FIXED = $10; { Interpret addr exactly }
  124. // MAP_ANONYMOUS = $20; { don't use a file }
  125. {$ifdef Linux}
  126. MAP_GROWSDOWN = $100; { stack-like segment }
  127. MAP_DENYWRITE = $800; { ETXTBSY }
  128. MAP_EXECUTABLE = $1000; { mark it as an executable }
  129. MAP_LOCKED = $2000; { pages are locked }
  130. MAP_NORESERVE = $4000; { don't check for reservations }
  131. {$else}
  132. {$ifdef FreeBSD}
  133. // FreeBSD defines MAP_COPY=MAP_PRIVATE=$2;
  134. MAP_FILE = $0000; { map from file (default) }
  135. MAP_ANON = $1000; { allocated from memory, swap space }
  136. MAP_RENAME = $0020; { Sun: rename private pages to file }
  137. MAP_NORESERVE = $0040; { Sun: don't reserve needed swap area }
  138. MAP_INHERIT = $0080; { region is retained after exec }
  139. MAP_NOEXTEND = $0100; { for MAP_FILE, don't change file size }
  140. MAP_HASSEMAPHORE = $0200; { region may contain semaphores }
  141. MAP_STACK = $0400; { region grows down, like a stack }
  142. MAP_NOSYNC = $0800; { page to but do not sync underlying file}
  143. MAP_NOCORE = $20000;{ dont include these pages in a coredump}
  144. {$endif}
  145. {$endif}
  146. {**************************
  147. Utility functions
  148. ***************************}
  149. Type
  150. TFSearchOption = (NoCurrentDirectory,
  151. CurrentDirectoryFirst,
  152. CurrentDirectoryLast);
  153. Function FSearch (const path:AnsiString;dirlist:Ansistring;CurrentDirStrategy:TFSearchOption):AnsiString;
  154. Function FSearch (const path:AnsiString;dirlist:AnsiString):AnsiString;
  155. procedure SigRaise (sig:integer);
  156. {$ifdef FPC_USE_LIBC}
  157. const clib = 'c';
  158. {$i unxdeclh.inc}
  159. {$else}
  160. {$i unxsysch.inc} // calls used in system and not reexported from baseunix
  161. {$endif}
  162. {******************************************************************************
  163. Implementation
  164. ******************************************************************************}
  165. {$i unxovlh.inc}
  166. Implementation
  167. Uses Strings{$ifndef FPC_USE_LIBC},Syscall{$endif};
  168. {$i unxovl.inc}
  169. {$ifndef FPC_USE_LIBC}
  170. {$i syscallh.inc}
  171. {$i ossysch.inc}
  172. {$i unxsysc.inc}
  173. {$endif}
  174. { Get the definitions of textrec and filerec }
  175. {$i textrec.inc}
  176. {$i filerec.inc}
  177. {$i unixfunc.inc} { Platform specific implementations }
  178. Function getenv(name:string):Pchar; external name 'FPC_SYSC_FPGETENV';
  179. {******************************************************************************
  180. Process related calls
  181. ******************************************************************************}
  182. { Most calls of WaitPID do not handle the result correctly, this funktion treats errors more correctly }
  183. Function WaitProcess(Pid:cint):cint; { like WaitPid(PID,@result,0) Handling of Signal interrupts (errno=EINTR), returning the Exitcode of Process (>=0) or -Status if terminated}
  184. var ret,r,s : cint;
  185. begin
  186. s:=$7F00;
  187. repeat
  188. r:=fpWaitPid(Pid,@s,0);
  189. if (r=-1) and (fpgeterrno=ESysEIntr) Then
  190. r:=0;
  191. until (r<>0);
  192. if (r=-1) or (r=0) then // 0 is not a valid return and should never occur (it means status invalid when using WNOHANG)
  193. WaitProcess:=-1 // return -1 to indicate an error. fpwaitpid updated it.
  194. else
  195. begin
  196. if wifexited(s) then
  197. WaitProcess:=wexitstatus(s)
  198. else if (s>0) then // Until now there is not use of the highest bit , but check this for the future
  199. WaitProcess:=-s // normal case
  200. else
  201. WaitProcess:=s; // s<0 should not occur, but wie return also a negativ value
  202. end;
  203. end;
  204. function intFpExecVEMaybeP (Const PathName:AnsiString;Args,MyEnv:ppchar;SearchPath:Boolean):cint;
  205. // does an ExecVE, but still has to handle P
  206. // execv variants call this directly, execl variants indirectly via
  207. // intfpexecl
  208. Var
  209. NewCmd : ansistring;
  210. ThePath : AnsiString;
  211. Error : cint;
  212. NrParam : longint;
  213. Begin
  214. If SearchPath and (pos('/',pathname)=0) Then
  215. Begin
  216. // The above could be better. (check if not escaped/quoted '/'s) ?
  217. // (Jilles says this is ok)
  218. // Stevens says only search if newcmd contains no '/'
  219. // fsearch is not ansistring clean yet.
  220. ThePath:=fpgetenv('PATH');
  221. if thepath='' then
  222. thepath:='.'; // FreeBSD uses _PATH_DEFPATH = /usr/bin:/bin
  223. // but a quick check showed that _PATH_DEFPATH
  224. // varied from OS to OS
  225. newcmd:=FSearch(pathname,thepath,NoCurrentDirectory);
  226. // FreeBSD libc keeps on trying till a file is successfully run.
  227. // Stevens says "try each path prefix"
  228. // execp puts newcmd here.
  229. args^:=pchar(newcmd);
  230. End else
  231. newcmd:=pathname;
  232. // repeat
  233. // if searchpath then args^:=pchar(commandtorun)
  234. IntFpExecVEMaybeP:=fpExecVE(newcmd,Args,MyEnv);
  235. {
  236. // Code that if exec fails due to permissions, tries to run it with sh
  237. // Should we deallocate p on fail? -> no fpexit is run no matter what
  238. //
  239. }
  240. // if intfpexecvemaybep=-1 then zoekvolgende file.
  241. // until (Goexit) or SearchExit;
  242. {
  243. If IntFpExec=-1 Then
  244. Begin
  245. Error:=fpGetErrno
  246. Case Error of
  247. ESysE2Big : Exit(-1);
  248. ESysELoop,
  249. : Exit(-1);
  250. }
  251. end;
  252. function intFpExecl (Const PathName:AnsiString;const s:array of ansistring;MyEnv:ppchar;SearchPath:Boolean):cint;
  253. { Handles the array of ansistring -> ppchar conversion.
  254. Base for the the "l" variants.
  255. }
  256. var p:ppchar;
  257. begin
  258. If PathName='' Then
  259. Begin
  260. fpsetErrno(ESysEnoEnt);
  261. Exit(-1); // Errno?
  262. End;
  263. p:=ArrayStringToPPchar(s,1);
  264. if p=NIL Then
  265. Begin
  266. GetMem(p,2*sizeof(pchar));
  267. if p=nil then
  268. begin
  269. {$ifdef xunix}
  270. fpseterrno(ESysEnoMem);
  271. {$endif}
  272. fpseterrno(ESysEnoEnt);
  273. exit(-1);
  274. end;
  275. p[1]:=nil;
  276. End;
  277. p^:=pchar(PathName);
  278. IntFPExecL:=intFpExecVEMaybeP(PathName,p,MyEnv,SearchPath);
  279. // If we come here, no attempts were executed successfully.
  280. Freemem(p);
  281. end;
  282. function FpExecLE (Const PathName:AnsiString;const S:Array Of AnsiString;MyEnv:ppchar):cint;
  283. Begin
  284. FpExecLE:=intFPExecl(PathName,s,MyEnv,false);
  285. End;
  286. function FpExecL(Const PathName:AnsiString;const S:Array Of AnsiString):cint;
  287. Begin
  288. FpExecL:=intFPExecl(PathName,S,EnvP,false);
  289. End;
  290. function FpExecLP(Const PathName:AnsiString;const S:Array Of AnsiString):cint;
  291. Begin
  292. FpExecLP:=intFPExecl(PathName,S,EnvP,True);
  293. End;
  294. function FpExecV(Const PathName:AnsiString;args:ppchar):cint;
  295. Begin
  296. fpexecV:=intFpExecVEMaybeP (PathName,args,envp,false);
  297. End;
  298. function FpExecVP(Const PathName:AnsiString;args:ppchar):cint;
  299. Begin
  300. fpexecVP:=intFpExecVEMaybeP (PathName,args,envp,true);
  301. End;
  302. function FpExecVPE(Const PathName:AnsiString;args,env:ppchar):cint;
  303. Begin
  304. fpexecVPE:=intFpExecVEMaybeP (PathName,args,env,true);
  305. End;
  306. // exect and execvP (ExecCapitalP) are not implement
  307. // Non POSIX anyway.
  308. // Exect turns on tracing for the process
  309. // execvP has the searchpath as array of ansistring ( const char *search_path)
  310. {$define FPC_USE_FPEXEC}
  311. Function Shell(const Command:String):cint;
  312. {
  313. Executes the shell, and passes it the string Command. (Through /bin/sh -c)
  314. The current environment is passed to the shell.
  315. It waits for the shell to exit, and returns its exit status.
  316. If the Exec call failed exit status 127 is reported.
  317. }
  318. { Changed the structure:
  319. - the previous version returns an undefinied value if fork fails
  320. - it returns the status of Waitpid instead of the Process returnvalue (see the doc to Shell)
  321. - it uses exit(127) not ExitProc (The Result in pp386: going on Compiling in 2 processes!)
  322. - ShellArgs are now released
  323. - The Old CreateShellArg gives back pointers to a local var
  324. }
  325. var
  326. {$ifndef FPC_USE_FPEXEC}
  327. p : ppchar;
  328. {$endif}
  329. pid : cint;
  330. begin
  331. {$ifndef FPC_USE_FPEXEC}
  332. p:=CreateShellArgv(command);
  333. {$endif}
  334. pid:=fpfork;
  335. if pid=0 then // We are in the Child
  336. begin
  337. {This is the child.}
  338. {$ifndef FPC_USE_FPEXEC}
  339. fpExecve(p^,p,envp);
  340. {$else}
  341. fpexecl('/bin/sh',['-c',Command]);
  342. {$endif}
  343. fpExit(127); // was Exit(127)
  344. end
  345. else if (pid<>-1) then // Successfull started
  346. Shell:=WaitProcess(pid)
  347. else // no success
  348. Shell:=-1; // indicate an error
  349. {$ifndef FPC_USE_FPEXEC}
  350. FreeShellArgV(p);
  351. {$endif}
  352. end;
  353. Function Shell(const Command:AnsiString):cint;
  354. {
  355. AnsiString version of Shell
  356. }
  357. var
  358. {$ifndef FPC_USE_FPEXEC}
  359. p : ppchar;
  360. {$endif}
  361. pid : cint;
  362. begin { Changes as above }
  363. {$ifndef FPC_USE_FPEXEC}
  364. p:=CreateShellArgv(command);
  365. {$endif}
  366. pid:=fpfork;
  367. if pid=0 then // We are in the Child
  368. begin
  369. {$ifdef FPC_USE_FPEXEC}
  370. fpexecl('/bin/sh',['-c',Command]);
  371. {$else}
  372. fpExecve(p^,p,envp);
  373. {$endif}
  374. fpExit(127); // was exit(127)!! We must exit the Process, not the function
  375. end
  376. else if (pid<>-1) then // Successfull started
  377. Shell:=WaitProcess(pid)
  378. else // no success
  379. Shell:=-1;
  380. {$ifndef FPC_USE_FPEXEC}
  381. FreeShellArgV(p);
  382. {$ENDIF}
  383. end;
  384. {$ifdef FPC_USE_LIBC}
  385. function xfpsystem(p:pchar):cint; cdecl; external clib name 'system';
  386. Function fpSystem(const Command:AnsiString):cint;
  387. begin
  388. fpsystem:=xfpsystem(pchar(command));
  389. end;
  390. {$else}
  391. Function fpSystem(const Command:AnsiString):cint;
  392. {
  393. AnsiString version of Shell
  394. }
  395. var
  396. pid,savedpid : cint;
  397. pstat : cint;
  398. ign,intact,
  399. quitact : SigactionRec;
  400. newsigblock,
  401. oldsigblock : tsigset;
  402. begin { Changes as above }
  403. if command='' then exit(1);
  404. ign.sa_handler:=SigActionHandler(SIG_IGN);
  405. fpsigemptyset(ign.sa_mask);
  406. ign.sa_flags:=0;
  407. fpsigaction(SIGINT, @ign, @intact);
  408. fpsigaction(SIGQUIT, @ign, @quitact);
  409. fpsigemptyset(newsigblock);
  410. fpsigaddset(newsigblock,SIGCHLD);
  411. fpsigprocmask(SIG_BLOCK,{$ifdef ver1_0}@{$endif}newsigblock,{$ifdef ver1_0}@{$endif}oldsigblock);
  412. pid:=fpfork;
  413. if pid=0 then // We are in the Child
  414. begin
  415. fpsigaction(SIGINT,@intact,NIL);
  416. fpsigaction(SIGQUIT,@quitact,NIL);
  417. fpsigprocmask(SIG_SETMASK,@oldsigblock,NIL);
  418. fpexecl('/bin/sh',['-c',Command]);
  419. fpExit(127); // was exit(127)!! We must exit the Process, not the function
  420. end
  421. else if (pid<>-1) then // Successfull started
  422. begin
  423. savedpid:=pid;
  424. repeat
  425. pid:=fpwaitpid(savedpid,@pstat,0);
  426. until (pid<>-1) and (fpgeterrno()<>ESysEintr);
  427. if pid=-1 Then
  428. fpsystem:=-1
  429. else
  430. fpsystem:=pstat;
  431. end
  432. else // no success
  433. fpsystem:=-1;
  434. fpsigaction(SIGINT,@intact,NIL);
  435. fpsigaction(SIGQUIT,@quitact,NIL);
  436. fpsigprocmask(SIG_SETMASK,@oldsigblock,NIL);
  437. end;
  438. {$endif}
  439. Function WIFSTOPPED(Status: Integer): Boolean;
  440. begin
  441. WIFSTOPPED:=((Status and $FF)=$7F);
  442. end;
  443. Function W_EXITCODE(ReturnCode, Signal: Integer): Integer;
  444. begin
  445. W_EXITCODE:=(ReturnCode shl 8) or Signal;
  446. end;
  447. Function W_STOPCODE(Signal: Integer): Integer;
  448. begin
  449. W_STOPCODE:=(Signal shl 8) or $7F;
  450. end;
  451. {$IFNDEF DONT_READ_TIMEZONE}
  452. { Include timezone handling routines which use /usr/share/timezone info }
  453. {$i timezone.inc}
  454. {$endif}
  455. {******************************************************************************
  456. FileSystem calls
  457. ******************************************************************************}
  458. Function fpFlock (var T : text;mode : cint) : cint;
  459. begin
  460. fpFlock:=fpFlock(TextRec(T).Handle,mode);
  461. end;
  462. Function fpFlock (var F : File;mode : cint) :cint;
  463. begin
  464. fpFlock:=fpFlock(FileRec(F).Handle,mode);
  465. end;
  466. Function SelectText(var T:Text;TimeOut :PTimeval):cint;
  467. Var
  468. F:TfdSet;
  469. begin
  470. if textrec(t).mode=fmclosed then
  471. begin
  472. fpseterrno(ESysEBADF);
  473. exit(-1);
  474. end;
  475. FpFD_ZERO(f);
  476. fpFD_SET(textrec(T).handle,f);
  477. if textrec(T).mode=fminput then
  478. SelectText:=fpselect(textrec(T).handle+1,@f,nil,nil,TimeOut)
  479. else
  480. SelectText:=fpselect(textrec(T).handle+1,nil,@f,nil,TimeOut);
  481. end;
  482. Function SelectText(var T:Text;TimeOut :cint):cint;
  483. var
  484. p : PTimeVal;
  485. tv : TimeVal;
  486. begin
  487. if TimeOut=-1 then
  488. p:=nil
  489. else
  490. begin
  491. tv.tv_Sec:=Timeout div 1000;
  492. tv.tv_Usec:=(Timeout mod 1000)*1000;
  493. p:=@tv;
  494. end;
  495. SelectText:=SelectText(T,p);
  496. end;
  497. {******************************************************************************
  498. Directory
  499. ******************************************************************************}
  500. procedure SeekDir(p:pdir;loc:clong);
  501. begin
  502. if p=nil then
  503. begin
  504. fpseterrno(ESysEBADF);
  505. exit;
  506. end;
  507. {$ifndef bsd}
  508. p^.dd_nextoff:=fplseek(p^.dd_fd,loc,seek_set);
  509. {$endif}
  510. p^.dd_size:=0;
  511. p^.dd_loc:=0;
  512. end;
  513. function TellDir(p:pdir):clong;
  514. begin
  515. if p=nil then
  516. begin
  517. fpseterrno(ESysEBADF);
  518. telldir:=-1;
  519. exit;
  520. end;
  521. telldir:=fplseek(p^.dd_fd,0,seek_cur)
  522. { We could try to use the nextoff field here, but on my 1.2.13
  523. kernel, this gives nothing... This may have to do with
  524. the readdir implementation of libc... I also didn't find any trace of
  525. the field in the kernel code itself, So I suspect it is an artifact of libc.
  526. Michael. }
  527. end;
  528. {******************************************************************************
  529. Pipes/Fifo
  530. ******************************************************************************}
  531. Procedure OpenPipe(var F:Text);
  532. begin
  533. case textrec(f).mode of
  534. fmoutput :
  535. if textrec(f).userdata[1]<>P_OUT then
  536. textrec(f).mode:=fmclosed;
  537. fminput :
  538. if textrec(f).userdata[1]<>P_IN then
  539. textrec(f).mode:=fmclosed;
  540. else
  541. textrec(f).mode:=fmclosed;
  542. end;
  543. end;
  544. Function IOPipe(var F:text):cint;
  545. begin
  546. IOPipe:=0;
  547. case textrec(f).mode of
  548. fmoutput :
  549. begin
  550. { first check if we need something to write, else we may
  551. get a SigPipe when Close() is called (PFV) }
  552. if textrec(f).bufpos>0 then
  553. IOPipe:=fpwrite(textrec(f).handle,pchar(textrec(f).bufptr),textrec(f).bufpos);
  554. end;
  555. fminput : Begin
  556. textrec(f).bufend:=fpread(textrec(f).handle,pchar(textrec(f).bufptr),textrec(f).bufsize);
  557. IOPipe:=textrec(f).bufend;
  558. End;
  559. end;
  560. textrec(f).bufpos:=0;
  561. end;
  562. Function FlushPipe(var F:Text):cint;
  563. begin
  564. FlushPipe:=0;
  565. if (textrec(f).mode=fmoutput) and (textrec(f).bufpos<>0) then
  566. FlushPipe:=IOPipe(f);
  567. textrec(f).bufpos:=0;
  568. end;
  569. Function ClosePipe(var F:text):cint;
  570. begin
  571. textrec(f).mode:=fmclosed;
  572. ClosePipe:=fpclose(textrec(f).handle);
  573. end;
  574. Function AssignPipe(var pipe_in,pipe_out:text):cint;
  575. {
  576. Sets up a pair of file variables, which act as a pipe. The first one can
  577. be read from, the second one can be written to.
  578. }
  579. var
  580. f_in,f_out : cint;
  581. begin
  582. if AssignPipe(f_in,f_out)=-1 then
  583. exit(-1);
  584. { Set up input }
  585. Assign(Pipe_in,'');
  586. Textrec(Pipe_in).Handle:=f_in;
  587. Textrec(Pipe_in).Mode:=fmInput;
  588. Textrec(Pipe_in).userdata[1]:=P_IN;
  589. TextRec(Pipe_in).OpenFunc:=@OpenPipe;
  590. TextRec(Pipe_in).InOutFunc:=@IOPipe;
  591. TextRec(Pipe_in).FlushFunc:=@FlushPipe;
  592. TextRec(Pipe_in).CloseFunc:=@ClosePipe;
  593. { Set up output }
  594. Assign(Pipe_out,'');
  595. Textrec(Pipe_out).Handle:=f_out;
  596. Textrec(Pipe_out).Mode:=fmOutput;
  597. Textrec(Pipe_out).userdata[1]:=P_OUT;
  598. TextRec(Pipe_out).OpenFunc:=@OpenPipe;
  599. TextRec(Pipe_out).InOutFunc:=@IOPipe;
  600. TextRec(Pipe_out).FlushFunc:=@FlushPipe;
  601. TextRec(Pipe_out).CloseFunc:=@ClosePipe;
  602. AssignPipe:=0;
  603. end;
  604. Function AssignPipe(var pipe_in,pipe_out:file):cint;
  605. {
  606. Sets up a pair of file variables, which act as a pipe. The first one can
  607. be read from, the second one can be written to.
  608. If the operation was unsuccesful,
  609. }
  610. var
  611. f_in,f_out : cint;
  612. begin
  613. if AssignPipe(f_in,f_out)=-1 then
  614. exit(-1);
  615. { Set up input }
  616. Assign(Pipe_in,'');
  617. Filerec(Pipe_in).Handle:=f_in;
  618. Filerec(Pipe_in).Mode:=fmInput;
  619. Filerec(Pipe_in).recsize:=1;
  620. Filerec(Pipe_in).userdata[1]:=P_IN;
  621. { Set up output }
  622. Assign(Pipe_out,'');
  623. Filerec(Pipe_out).Handle:=f_out;
  624. Filerec(Pipe_out).Mode:=fmoutput;
  625. Filerec(Pipe_out).recsize:=1;
  626. Filerec(Pipe_out).userdata[1]:=P_OUT;
  627. AssignPipe:=0;
  628. end;
  629. Function PCloseText(Var F:text):cint;
  630. {
  631. May not use @PClose due overloading
  632. }
  633. begin
  634. PCloseText:=PClose(f);
  635. end;
  636. function POpen(var F:text;const Prog:String;rw:char):cint;
  637. {
  638. Starts the program in 'Prog' and makes it's input or out put the
  639. other end of a pipe. If rw is 'w' or 'W', then whatever is written to
  640. F, will be read from stdin by the program in 'Prog'. The inverse is true
  641. for 'r' or 'R' : whatever the program in 'Prog' writes to stdout, can be
  642. read from 'f'.
  643. }
  644. var
  645. pipi,
  646. pipo : text;
  647. pid : pid_t;
  648. pl : ^cint;
  649. pp : ppchar;
  650. ret : cint;
  651. begin
  652. rw:=upcase(rw);
  653. if not (rw in ['R','W']) then
  654. begin
  655. FpSetErrno(ESysEnoent);
  656. exit(-1);
  657. end;
  658. if AssignPipe(pipi,pipo)=-1 Then
  659. Exit(-1);
  660. pid:=fpfork; // vfork in FreeBSD.
  661. if pid=-1 then
  662. begin
  663. close(pipi);
  664. close(pipo);
  665. exit(-1);
  666. end;
  667. if pid=0 then
  668. begin
  669. { We're in the child }
  670. if rw='W' then
  671. begin
  672. close(pipo);
  673. ret:=fpdup2(pipi,input);
  674. close(pipi);
  675. if ret=-1 then
  676. halt(127);
  677. end
  678. else
  679. begin
  680. close(pipi);
  681. ret:=fpdup2(pipo,output);
  682. close(pipo);
  683. if ret=-1 then
  684. halt(127);
  685. end;
  686. {$ifdef FPC_USE_FPEXEC}
  687. fpexecl('/bin/sh',['-c',Prog]);
  688. {$else}
  689. pp:=createshellargv(prog);
  690. fpExecve(pp^,pp,envp);
  691. {$endif}
  692. halt(127);
  693. end
  694. else
  695. begin
  696. { We're in the parent }
  697. if rw='W' then
  698. begin
  699. close(pipi);
  700. f:=pipo;
  701. textrec(f).bufptr:=@textrec(f).buffer;
  702. end
  703. else
  704. begin
  705. close(pipo);
  706. f:=pipi;
  707. textrec(f).bufptr:=@textrec(f).buffer;
  708. end;
  709. {Save the process ID - needed when closing }
  710. pl:=@(textrec(f).userdata[2]);
  711. pl^:=pid;
  712. textrec(f).closefunc:=@PCloseText;
  713. end;
  714. ret:=0;
  715. end;
  716. Function POpen(var F:file;const Prog:String;rw:char):cint;
  717. {
  718. Starts the program in 'Prog' and makes it's input or out put the
  719. other end of a pipe. If rw is 'w' or 'W', then whatever is written to
  720. F, will be read from stdin by the program in 'Prog'. The inverse is true
  721. for 'r' or 'R' : whatever the program in 'Prog' writes to stdout, can be
  722. read from 'f'.
  723. }
  724. var
  725. pipi,
  726. pipo : file;
  727. pid : cint;
  728. pl : ^cint;
  729. p,pp : ppchar;
  730. temp : string[255];
  731. ret : cint;
  732. begin
  733. rw:=upcase(rw);
  734. if not (rw in ['R','W']) then
  735. begin
  736. FpSetErrno(ESysEnoent);
  737. exit(-1);
  738. end;
  739. ret:=AssignPipe(pipi,pipo);
  740. if ret=-1 then
  741. exit(-1);
  742. pid:=fpfork;
  743. if pid=-1 then
  744. begin
  745. close(pipi);
  746. close(pipo);
  747. exit(-1);
  748. end;
  749. if pid=0 then
  750. begin
  751. { We're in the child }
  752. if rw='W' then
  753. begin
  754. close(pipo);
  755. ret:=fpdup2(filerec(pipi).handle,stdinputhandle);
  756. close(pipi);
  757. if ret=-1 then
  758. halt(127);
  759. end
  760. else
  761. begin
  762. close(pipi);
  763. ret:=fpdup2(filerec(pipo).handle,stdoutputhandle);
  764. close(pipo);
  765. if ret=1 then
  766. halt(127);
  767. end;
  768. {$ifdef FPC_USE_FPEXEC}
  769. fpexecl('/bin/sh',['-c',Prog]);
  770. {$else}
  771. getmem(pp,sizeof(pchar)*4);
  772. temp:='/bin/sh'#0'-c'#0+prog+#0;
  773. p:=pp;
  774. p^:=@temp[1];
  775. inc(p);
  776. p^:=@temp[9];
  777. inc(p);
  778. p^:=@temp[12];
  779. inc(p);
  780. p^:=Nil;
  781. fpExecve(ansistring('/bin/sh'),pp,envp);
  782. {$endif}
  783. halt(127);
  784. end
  785. else
  786. begin
  787. { We're in the parent }
  788. if rw='W' then
  789. begin
  790. close(pipi);
  791. f:=pipo;
  792. end
  793. else
  794. begin
  795. close(pipo);
  796. f:=pipi;
  797. end;
  798. {Save the process ID - needed when closing }
  799. pl:=@(filerec(f).userdata[2]);
  800. pl^:=pid;
  801. end;
  802. POpen:=0;
  803. end;
  804. Function AssignStream(Var StreamIn,Streamout:text;Const Prog:ansiString;const args : array of ansistring) : cint;
  805. {
  806. Starts the program in 'Prog' and makes its input and output the
  807. other end of two pipes, which are the stdin and stdout of a program
  808. specified in 'Prog'.
  809. streamout can be used to write to the program, streamin can be used to read
  810. the output of the program. See the following diagram :
  811. Parent Child
  812. STreamout --> Input
  813. Streamin <-- Output
  814. Return value is the process ID of the process being spawned, or -1 in case of failure.
  815. }
  816. var
  817. pipi,
  818. pipo : text;
  819. pid : cint;
  820. pl : ^cint;
  821. begin
  822. AssignStream:=-1;
  823. if AssignPipe(streamin,pipo)=-1 Then
  824. exit(-1);
  825. if AssignPipe(pipi,streamout)=-1 Then // shouldn't this close streamin and pipo?
  826. exit(-1);
  827. pid:=fpfork;
  828. if pid=-1 then
  829. begin
  830. close(pipi);
  831. close(pipo);
  832. close (streamin);
  833. close (streamout);
  834. exit;
  835. end;
  836. if pid=0 then
  837. begin
  838. { We're in the child }
  839. { Close what we don't need }
  840. close(streamout);
  841. close(streamin);
  842. if fpdup2(pipi,input)=-1 Then
  843. halt(127);
  844. close(pipi);
  845. If fpdup2(pipo,output)=-1 Then
  846. halt (127);
  847. close(pipo);
  848. fpExecl(Prog,args);
  849. halt(127);
  850. end
  851. else
  852. begin
  853. { we're in the parent}
  854. close(pipo);
  855. close(pipi);
  856. {Save the process ID - needed when closing }
  857. pl:=@(textrec(StreamIn).userdata[2]);
  858. pl^:=pid;
  859. textrec(StreamIn).closefunc:=@PCloseText;
  860. {Save the process ID - needed when closing }
  861. pl:=@(textrec(StreamOut).userdata[2]);
  862. pl^:=pid;
  863. textrec(StreamOut).closefunc:=@PCloseText;
  864. AssignStream:=Pid;
  865. end;
  866. end;
  867. Function AssignStream(Var StreamIn,Streamout,streamerr:text;Const Prog:ansiString;const args : array of ansistring) : cint;
  868. {
  869. Starts the program in 'prog' and makes its input, output and error output the
  870. other end of three pipes, which are the stdin, stdout and stderr of a program
  871. specified in 'prog'.
  872. StreamOut can be used to write to the program, StreamIn can be used to read
  873. the output of the program, StreamErr reads the error output of the program.
  874. See the following diagram :
  875. Parent Child
  876. StreamOut --> StdIn (input)
  877. StreamIn <-- StdOut (output)
  878. StreamErr <-- StdErr (error output)
  879. }
  880. var
  881. PipeIn, PipeOut, PipeErr: text;
  882. pid: cint;
  883. pl: ^cint;
  884. begin
  885. AssignStream := -1;
  886. // Assign pipes
  887. if AssignPipe(StreamIn, PipeOut)=-1 Then
  888. Exit(-1);
  889. If AssignPipe(StreamErr, PipeErr)=-1 Then
  890. begin
  891. Close(StreamIn);
  892. Close(PipeOut);
  893. exit(-1);
  894. end;
  895. if AssignPipe(PipeIn, StreamOut)=-1 Then
  896. begin
  897. Close(StreamIn);
  898. Close(PipeOut);
  899. Close(StreamErr);
  900. Close(PipeErr);
  901. exit(-1);
  902. end;
  903. // Fork
  904. pid := fpFork;
  905. if pid=-1 then begin
  906. Close(StreamIn);
  907. Close(PipeOut);
  908. Close(StreamErr);
  909. Close(PipeErr);
  910. Close(PipeIn);
  911. Close(StreamOut);
  912. exit(-1);
  913. end;
  914. if pid = 0 then begin
  915. // *** We are in the child ***
  916. // Close what we don not need
  917. Close(StreamOut);
  918. Close(StreamIn);
  919. Close(StreamErr);
  920. // Connect pipes
  921. if fpdup2(PipeIn, Input)=-1 Then
  922. Halt(127);
  923. Close(PipeIn);
  924. if fpdup2(PipeOut, Output)=-1 Then
  925. Halt(127);
  926. Close(PipeOut);
  927. if fpdup2(PipeErr, StdErr)=-1 Then
  928. Halt(127);
  929. Close(PipeErr);
  930. // Execute program
  931. fpExecl(Prog,args);
  932. Halt(127);
  933. end else begin
  934. // *** We are in the parent ***
  935. Close(PipeErr);
  936. Close(PipeOut);
  937. Close(PipeIn);
  938. // Save the process ID - needed when closing
  939. pl := @(TextRec(StreamIn).userdata[2]);
  940. pl^ := pid;
  941. TextRec(StreamIn).closefunc := @PCloseText;
  942. // Save the process ID - needed when closing
  943. pl := @(TextRec(StreamOut).userdata[2]);
  944. pl^ := pid;
  945. TextRec(StreamOut).closefunc := @PCloseText;
  946. // Save the process ID - needed when closing
  947. pl := @(TextRec(StreamErr).userdata[2]);
  948. pl^ := pid;
  949. TextRec(StreamErr).closefunc := @PCloseText;
  950. AssignStream := pid;
  951. end;
  952. end;
  953. {******************************************************************************
  954. General information calls
  955. ******************************************************************************}
  956. {$ifdef Linux}
  957. Function GetDomainName:String; { linux only!}
  958. // domainname is a glibc extension.
  959. {
  960. Get machines domain name. Returns empty string if not set.
  961. }
  962. Var
  963. Sysn : utsname;
  964. begin
  965. If fpUname(sysn)<>0 then
  966. getdomainname:=''
  967. else
  968. getdomainname:=strpas(@Sysn.domain[0]);
  969. end;
  970. {$endif}
  971. {$ifdef BSD}
  972. function intGetDomainName(Name:PChar; NameLen:Cint):cint;
  973. {$ifndef FPC_USE_LIBC}
  974. external name 'FPC_SYSC_GETDOMAINNAME';
  975. {$else FPC_USE_LIBC}
  976. cdecl; external clib name 'getdomainname';
  977. {$endif FPC_USE_LIBC}
  978. Function GetDomainName:String; { linux only!}
  979. // domainname is a glibc extension.
  980. {
  981. Get machines domain name. Returns empty string if not set.
  982. }
  983. begin
  984. if intGetDomainName(@getdomainname[1],255)=-1 then
  985. getdomainname:=''
  986. else
  987. getdomainname[0]:=chr(strlen(@getdomainname[1]));
  988. end;
  989. {$endif}
  990. Function GetHostName:String;
  991. {
  992. Get machines name. Returns empty string if not set.
  993. }
  994. Var
  995. Sysn : utsname;
  996. begin
  997. If fpuname(sysn)=-1 then
  998. gethostname:=''
  999. else
  1000. gethostname:=strpas(@Sysn.nodename[0]);
  1001. end;
  1002. {******************************************************************************
  1003. Signal handling calls
  1004. ******************************************************************************}
  1005. procedure SigRaise(sig:integer);
  1006. begin
  1007. fpKill(fpGetPid,Sig);
  1008. end;
  1009. {******************************************************************************
  1010. Utility calls
  1011. ******************************************************************************}
  1012. Function FSearch(const path:AnsiString;dirlist:Ansistring;CurrentDirStrategy:TFSearchOption):AnsiString;
  1013. {
  1014. Searches for a file 'path' in the list of direcories in 'dirlist'.
  1015. returns an empty string if not found. Wildcards are NOT allowed.
  1016. If dirlist is empty, it is set to '.'
  1017. This function tries to make FSearch use ansistrings, and decrease
  1018. stringhandling overhead at the same time.
  1019. }
  1020. Var
  1021. mydir,NewDir : ansistring;
  1022. p1 : cint;
  1023. Info : Stat;
  1024. i,j : cint;
  1025. p : pchar;
  1026. Begin
  1027. if CurrentDirStrategy=CurrentDirectoryFirst Then
  1028. Dirlist:='.:'+dirlist; {Make sure current dir is first to be searched.}
  1029. if CurrentDirStrategy=CurrentDirectoryLast Then
  1030. Dirlist:=dirlist+':.'; {Make sure current dir is last to be searched.}
  1031. {Replace ':' and ';' with #0}
  1032. for p1:=1 to length(dirlist) do
  1033. if (dirlist[p1]=':') or (dirlist[p1]=';') then
  1034. dirlist[p1]:=#0;
  1035. {Check for WildCards}
  1036. If (Pos('?',Path) <> 0) or (Pos('*',Path) <> 0) Then
  1037. FSearch:='' {No wildcards allowed in these things.}
  1038. Else
  1039. Begin
  1040. p:=pchar(dirlist);
  1041. i:=length(dirlist);
  1042. j:=1;
  1043. Repeat
  1044. mydir:=ansistring(p);
  1045. if (length(mydir)>0) and (mydir[length(mydir)]<>'/') then
  1046. mydir:=mydir+'/';
  1047. NewDir:=mydir+Path;
  1048. if (FpStat(NewDir,Info)>=0) and
  1049. (not fpS_ISDIR(Info.st_Mode)) then
  1050. Begin
  1051. If Pos('./',NewDir)=1 Then
  1052. Delete(NewDir,1,2);
  1053. {DOS strips off an initial .\}
  1054. End
  1055. Else
  1056. NewDir:='';
  1057. while (j<=i) and (p^<>#0) do begin inc(j); inc(p); end;
  1058. if p^=#0 then inc(p);
  1059. Until (j>=i) or (Length(NewDir) > 0);
  1060. FSearch:=NewDir;
  1061. End;
  1062. End;
  1063. Function FSearch(const path:AnsiString;dirlist:Ansistring):AnsiString;
  1064. Begin
  1065. FSearch:=FSearch(path,dirlist,CurrentDirectoryFirst);
  1066. End;
  1067. {--------------------------------
  1068. Stat.Mode Macro's
  1069. --------------------------------}
  1070. Initialization
  1071. {$IFNDEF DONT_READ_TIMEZONE}
  1072. InitLocalTime;
  1073. {$endif}
  1074. finalization
  1075. {$IFNDEF DONT_READ_TIMEZONE}
  1076. DoneLocalTime;
  1077. {$endif}
  1078. End.
  1079. {
  1080. $Log$
  1081. Revision 1.82 2005-02-13 20:01:38 peter
  1082. * include file cleanup
  1083. Revision 1.81 2005/02/06 11:20:52 peter
  1084. * threading in system unit
  1085. * removed systhrds unit
  1086. Revision 1.80 2005/01/30 18:01:15 peter
  1087. * signal cleanup for linux
  1088. * sigactionhandler instead of tsigaction for bsds
  1089. * sigcontext moved to cpu dir
  1090. Revision 1.79 2005/01/22 20:56:11 michael
  1091. + Patch for intFpExecVEMaybeP to use the right path (From Colin Western)
  1092. Revision 1.78 2004/11/21 11:28:21 peter
  1093. * fixed bootstrap with 1.0.10 and 1.9.4
  1094. Revision 1.77 2004/11/19 13:15:15 marco
  1095. * external rework. Mostly done.
  1096. Revision 1.76 2004/11/03 15:00:43 marco
  1097. * Pathstr eliminated
  1098. Revision 1.75 2004/10/30 20:55:54 marco
  1099. * unix interface cleanup
  1100. Revision 1.74 2004/07/18 14:54:42 jonas
  1101. * fixed BSD getdomainname for FPC_USE_LIBC
  1102. Revision 1.73 2004/07/18 11:27:54 marco
  1103. * small fix for BSD getdomainname. BSD version is based on Sysctl
  1104. Revision 1.72 2004/07/03 13:18:06 daniel
  1105. * Better fix.
  1106. Revision 1.71 2004/07/03 13:15:51 daniel
  1107. * Compilation fix in fsearch
  1108. Revision 1.70 2004/04/23 19:16:25 marco
  1109. * flock -> fpflock because of conflicting structure name
  1110. Revision 1.69 2004/04/22 17:17:13 peter
  1111. * x86-64 fixes
  1112. Revision 1.68 2004/03/04 22:15:17 marco
  1113. * UnixType changes. Please report problems to me.
  1114. Revision 1.66 2004/02/16 13:21:18 marco
  1115. * fpexec for popen
  1116. Revision 1.65 2004/02/14 21:12:14 marco
  1117. * provisorische fix voor Michael's problemen
  1118. Revision 1.64 2004/02/14 18:22:15 marco
  1119. * fpsystem, and some FPC_USE_LIBC fixes. (FreeBSD needs systypes.inc, also when FPC_USE_LIBC, it only contains types like statfs
  1120. Revision 1.63 2004/02/13 10:50:22 marco
  1121. * Hopefully last large changes to fpexec and friends.
  1122. - naming conventions changes from Michael.
  1123. - shell functions get alternative under ifdef.
  1124. - arraystring function moves to unixutil
  1125. - unixutil now regards quotes in stringtoppchar.
  1126. - sysutils/unix get executeprocess(ansi,array of ansi), and
  1127. both executeprocess functions are fixed
  1128. - Sysutils/win32 get executeprocess(ansi,array of ansi)
  1129. Revision 1.62 2004/02/12 16:20:58 marco
  1130. * currentpath stuff fixed for fsearch
  1131. Revision 1.61 2004/02/12 15:31:06 marco
  1132. * First version of fpexec change. Still under ifdef or silently overloaded
  1133. Revision 1.60 2004/01/23 08:11:18 jonas
  1134. * only include systypes.inc if FPC_USE_LIBC is not defined
  1135. Revision 1.59 2004/01/22 13:46:14 marco
  1136. bsd
  1137. Revision 1.58 2004/01/04 21:05:01 jonas
  1138. * declare C-library routines as external in libc so we generate proper
  1139. import entries for Darwin
  1140. Revision 1.57 2004/01/04 20:53:02 jonas
  1141. * don't use systypes if FPC_USE_LIBC is defined
  1142. Revision 1.56 2004/01/04 16:24:05 jonas
  1143. * fixed WaitProcess in case of SysEintr
  1144. Revision 1.55 2003/12/31 20:24:25 marco
  1145. * export statfs(pchar)
  1146. Revision 1.54 2003/12/30 15:43:20 marco
  1147. * linux now compiles with FPC_USE_LIBC
  1148. Revision 1.53 2003/12/30 12:24:01 marco
  1149. * FPC_USE_LIBC
  1150. Revision 1.52 2003/12/08 17:16:30 peter
  1151. * fsearch should only find files
  1152. Revision 1.51 2003/11/19 17:11:40 marco
  1153. * termio unit
  1154. Revision 1.50 2003/11/19 10:54:32 marco
  1155. * some simple restructures
  1156. Revision 1.49 2003/11/17 11:28:08 marco
  1157. * Clone moved to linux, + few small unit unix changes
  1158. Revision 1.48 2003/11/17 10:05:51 marco
  1159. * threads for FreeBSD. Not working tho
  1160. Revision 1.47 2003/11/14 17:30:14 marco
  1161. * weeehoo linuxerror is no more :-)
  1162. Revision 1.46 2003/11/14 16:44:48 marco
  1163. * stream functions converted to work without linuxerror
  1164. Revision 1.45 2003/11/13 18:44:06 marco
  1165. * small fi
  1166. Revision 1.44 2003/11/12 22:19:45 marco
  1167. * more linuxeror fixes
  1168. Revision 1.43 2003/11/03 09:42:28 marco
  1169. * Peter's Cardinal<->Longint fixes patch
  1170. Revision 1.42 2003/10/30 16:42:58 marco
  1171. * fixes for old syscall() convention removing
  1172. Revision 1.41 2003/10/12 19:40:43 marco
  1173. * ioctl fixes. IDE now starts, but
  1174. Revision 1.40 2003/09/29 14:36:06 peter
  1175. * fixed for stricter compiler
  1176. Revision 1.39 2003/09/27 12:51:33 peter
  1177. * fpISxxx macros renamed to C compliant fpS_ISxxx
  1178. Revision 1.38 2003/09/20 12:38:29 marco
  1179. * FCL now compiles for FreeBSD with new 1.1. Now Linux.
  1180. Revision 1.37 2003/09/17 19:07:44 marco
  1181. * more fixes for Unix<->unixutil
  1182. Revision 1.36 2003/09/17 17:30:46 marco
  1183. * Introduction of unixutil
  1184. Revision 1.35 2003/09/16 21:46:27 marco
  1185. * small fixes, checking things on linux
  1186. Revision 1.34 2003/09/16 20:52:24 marco
  1187. * small cleanups. Mostly killing of already commented code in unix etc
  1188. Revision 1.33 2003/09/16 16:13:56 marco
  1189. * fdset functions renamed to fp<posix name>
  1190. Revision 1.32 2003/09/15 20:08:49 marco
  1191. * small fixes. FreeBSD now cycles
  1192. Revision 1.31 2003/09/14 20:15:01 marco
  1193. * Unix reform stage two. Remove all calls from Unix that exist in Baseunix.
  1194. Revision 1.30 2003/07/08 21:23:24 peter
  1195. * sparc fixes
  1196. Revision 1.29 2003/05/30 19:58:40 marco
  1197. * Getting NetBSD/i386 to compile.
  1198. Revision 1.28 2003/05/29 19:16:16 marco
  1199. * fixed a small *BSD gotcha
  1200. Revision 1.27 2003/05/24 20:39:54 jonas
  1201. * fixed ExitCode translation in WaitProcess for Linux and Darwin (and
  1202. probably other BSD's as well)
  1203. Revision 1.26 2003/03/11 08:27:59 michael
  1204. * stringtoppchar should use tabs instead of backspace as delimiter
  1205. Revision 1.25 2002/12/18 16:50:39 marco
  1206. * Unix RTL generic parts. Linux working, *BSD will follow shortly
  1207. Revision 1.24 2002/09/07 16:01:28 peter
  1208. * old logs removed and tabs fixed
  1209. Revision 1.23 2002/08/06 13:30:46 sg
  1210. * replaced some Longints with Cardinals, to mach the C headers
  1211. * updated the termios record
  1212. Revision 1.22 2002/03/05 20:04:25 michael
  1213. + Patch from Sebastian for FCNTL call
  1214. Revision 1.21 2002/01/02 12:22:54 marco
  1215. * Removed ifdef arround getepoch.
  1216. }