unix.pp 38 KB

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