unix.pp 38 KB

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