unix.pp 38 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442
  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. {$ifdef FreeBSD}
  426. ign.sa_handler:=TSigAction(SIG_IGN);
  427. {$else}
  428. ign.sa_handler:=SignalHandler(SIG_IGN);
  429. {$endif}
  430. fpsigemptyset(ign.sa_mask);
  431. ign.sa_flags:=0;
  432. fpsigaction(SIGINT, @ign, @intact);
  433. fpsigaction(SIGQUIT, @ign, @quitact);
  434. fpsigemptyset(newsigblock);
  435. fpsigaddset(newsigblock,SIGCHLD);
  436. fpsigprocmask(SIG_BLOCK,{$ifdef ver1_0}@{$endif}newsigblock,{$ifdef ver1_0}@{$endif}oldsigblock);
  437. pid:=fpfork;
  438. if pid=0 then // We are in the Child
  439. begin
  440. fpsigaction(SIGINT,@intact,NIL);
  441. fpsigaction(SIGQUIT,@quitact,NIL);
  442. fpsigprocmask(SIG_SETMASK,@oldsigblock,NIL);
  443. fpexecl('/bin/sh',['-c',Command]);
  444. fpExit(127); // was exit(127)!! We must exit the Process, not the function
  445. end
  446. else if (pid<>-1) then // Successfull started
  447. begin
  448. savedpid:=pid;
  449. repeat
  450. pid:=fpwaitpid(savedpid,@pstat,0);
  451. until (pid<>-1) and (fpgeterrno()<>ESysEintr);
  452. if pid=-1 Then
  453. fpsystem:=-1
  454. else
  455. fpsystem:=pstat;
  456. end
  457. else // no success
  458. fpsystem:=-1;
  459. fpsigaction(SIGINT,@intact,NIL);
  460. fpsigaction(SIGQUIT,@quitact,NIL);
  461. fpsigprocmask(SIG_SETMASK,@oldsigblock,NIL);
  462. end;
  463. {$endif}
  464. Function WIFSTOPPED(Status: Integer): Boolean;
  465. begin
  466. WIFSTOPPED:=((Status and $FF)=$7F);
  467. end;
  468. Function W_EXITCODE(ReturnCode, Signal: Integer): Integer;
  469. begin
  470. W_EXITCODE:=(ReturnCode shl 8) or Signal;
  471. end;
  472. Function W_STOPCODE(Signal: Integer): Integer;
  473. begin
  474. W_STOPCODE:=(Signal shl 8) or $7F;
  475. end;
  476. {$IFNDEF DONT_READ_TIMEZONE}
  477. { Include timezone handling routines which use /usr/share/timezone info }
  478. {$i timezone.inc}
  479. {$endif}
  480. {******************************************************************************
  481. FileSystem calls
  482. ******************************************************************************}
  483. Function fpFlock (var T : text;mode : cint) : cint;
  484. begin
  485. fpFlock:=fpFlock(TextRec(T).Handle,mode);
  486. end;
  487. Function fpFlock (var F : File;mode : cint) :cint;
  488. begin
  489. fpFlock:=fpFlock(FileRec(F).Handle,mode);
  490. end;
  491. Function SelectText(var T:Text;TimeOut :PTimeval):cint;
  492. Var
  493. F:TfdSet;
  494. begin
  495. if textrec(t).mode=fmclosed then
  496. begin
  497. fpseterrno(ESysEBADF);
  498. exit(-1);
  499. end;
  500. FpFD_ZERO(f);
  501. fpFD_SET(textrec(T).handle,f);
  502. if textrec(T).mode=fminput then
  503. SelectText:=fpselect(textrec(T).handle+1,@f,nil,nil,TimeOut)
  504. else
  505. SelectText:=fpselect(textrec(T).handle+1,nil,@f,nil,TimeOut);
  506. end;
  507. Function SelectText(var T:Text;TimeOut :cint):cint;
  508. var
  509. p : PTimeVal;
  510. tv : TimeVal;
  511. begin
  512. if TimeOut=-1 then
  513. p:=nil
  514. else
  515. begin
  516. tv.tv_Sec:=Timeout div 1000;
  517. tv.tv_Usec:=(Timeout mod 1000)*1000;
  518. p:=@tv;
  519. end;
  520. SelectText:=SelectText(T,p);
  521. end;
  522. {******************************************************************************
  523. Directory
  524. ******************************************************************************}
  525. procedure SeekDir(p:pdir;loc:clong);
  526. begin
  527. if p=nil then
  528. begin
  529. fpseterrno(ESysEBADF);
  530. exit;
  531. end;
  532. {$ifndef bsd}
  533. p^.dd_nextoff:=fplseek(p^.dd_fd,loc,seek_set);
  534. {$endif}
  535. p^.dd_size:=0;
  536. p^.dd_loc:=0;
  537. end;
  538. function TellDir(p:pdir):clong;
  539. begin
  540. if p=nil then
  541. begin
  542. fpseterrno(ESysEBADF);
  543. telldir:=-1;
  544. exit;
  545. end;
  546. telldir:=fplseek(p^.dd_fd,0,seek_cur)
  547. { We could try to use the nextoff field here, but on my 1.2.13
  548. kernel, this gives nothing... This may have to do with
  549. the readdir implementation of libc... I also didn't find any trace of
  550. the field in the kernel code itself, So I suspect it is an artifact of libc.
  551. Michael. }
  552. end;
  553. {******************************************************************************
  554. Pipes/Fifo
  555. ******************************************************************************}
  556. Procedure OpenPipe(var F:Text);
  557. begin
  558. case textrec(f).mode of
  559. fmoutput :
  560. if textrec(f).userdata[1]<>P_OUT then
  561. textrec(f).mode:=fmclosed;
  562. fminput :
  563. if textrec(f).userdata[1]<>P_IN then
  564. textrec(f).mode:=fmclosed;
  565. else
  566. textrec(f).mode:=fmclosed;
  567. end;
  568. end;
  569. Function IOPipe(var F:text):cint;
  570. begin
  571. IOPipe:=0;
  572. case textrec(f).mode of
  573. fmoutput :
  574. begin
  575. { first check if we need something to write, else we may
  576. get a SigPipe when Close() is called (PFV) }
  577. if textrec(f).bufpos>0 then
  578. IOPipe:=fpwrite(textrec(f).handle,pchar(textrec(f).bufptr),textrec(f).bufpos);
  579. end;
  580. fminput : Begin
  581. textrec(f).bufend:=fpread(textrec(f).handle,pchar(textrec(f).bufptr),textrec(f).bufsize);
  582. IOPipe:=textrec(f).bufend;
  583. End;
  584. end;
  585. textrec(f).bufpos:=0;
  586. end;
  587. Function FlushPipe(var F:Text):cint;
  588. begin
  589. FlushPipe:=0;
  590. if (textrec(f).mode=fmoutput) and (textrec(f).bufpos<>0) then
  591. FlushPipe:=IOPipe(f);
  592. textrec(f).bufpos:=0;
  593. end;
  594. Function ClosePipe(var F:text):cint;
  595. begin
  596. textrec(f).mode:=fmclosed;
  597. ClosePipe:=fpclose(textrec(f).handle);
  598. end;
  599. Function AssignPipe(var pipe_in,pipe_out:text):cint;
  600. {
  601. Sets up a pair of file variables, which act as a pipe. The first one can
  602. be read from, the second one can be written to.
  603. }
  604. var
  605. f_in,f_out : cint;
  606. begin
  607. if AssignPipe(f_in,f_out)=-1 then
  608. exit(-1);
  609. { Set up input }
  610. Assign(Pipe_in,'');
  611. Textrec(Pipe_in).Handle:=f_in;
  612. Textrec(Pipe_in).Mode:=fmInput;
  613. Textrec(Pipe_in).userdata[1]:=P_IN;
  614. TextRec(Pipe_in).OpenFunc:=@OpenPipe;
  615. TextRec(Pipe_in).InOutFunc:=@IOPipe;
  616. TextRec(Pipe_in).FlushFunc:=@FlushPipe;
  617. TextRec(Pipe_in).CloseFunc:=@ClosePipe;
  618. { Set up output }
  619. Assign(Pipe_out,'');
  620. Textrec(Pipe_out).Handle:=f_out;
  621. Textrec(Pipe_out).Mode:=fmOutput;
  622. Textrec(Pipe_out).userdata[1]:=P_OUT;
  623. TextRec(Pipe_out).OpenFunc:=@OpenPipe;
  624. TextRec(Pipe_out).InOutFunc:=@IOPipe;
  625. TextRec(Pipe_out).FlushFunc:=@FlushPipe;
  626. TextRec(Pipe_out).CloseFunc:=@ClosePipe;
  627. AssignPipe:=0;
  628. end;
  629. Function AssignPipe(var pipe_in,pipe_out:file):cint;
  630. {
  631. Sets up a pair of file variables, which act as a pipe. The first one can
  632. be read from, the second one can be written to.
  633. If the operation was unsuccesful,
  634. }
  635. var
  636. f_in,f_out : cint;
  637. begin
  638. if AssignPipe(f_in,f_out)=-1 then
  639. exit(-1);
  640. { Set up input }
  641. Assign(Pipe_in,'');
  642. Filerec(Pipe_in).Handle:=f_in;
  643. Filerec(Pipe_in).Mode:=fmInput;
  644. Filerec(Pipe_in).recsize:=1;
  645. Filerec(Pipe_in).userdata[1]:=P_IN;
  646. { Set up output }
  647. Assign(Pipe_out,'');
  648. Filerec(Pipe_out).Handle:=f_out;
  649. Filerec(Pipe_out).Mode:=fmoutput;
  650. Filerec(Pipe_out).recsize:=1;
  651. Filerec(Pipe_out).userdata[1]:=P_OUT;
  652. AssignPipe:=0;
  653. end;
  654. Function PCloseText(Var F:text):cint;
  655. {
  656. May not use @PClose due overloading
  657. }
  658. begin
  659. PCloseText:=PClose(f);
  660. end;
  661. function POpen(var F:text;const Prog:String;rw:char):cint;
  662. {
  663. Starts the program in 'Prog' and makes it's input or out put the
  664. other end of a pipe. If rw is 'w' or 'W', then whatever is written to
  665. F, will be read from stdin by the program in 'Prog'. The inverse is true
  666. for 'r' or 'R' : whatever the program in 'Prog' writes to stdout, can be
  667. read from 'f'.
  668. }
  669. var
  670. pipi,
  671. pipo : text;
  672. pid : pid_t;
  673. pl : ^cint;
  674. pp : ppchar;
  675. ret : cint;
  676. begin
  677. rw:=upcase(rw);
  678. if not (rw in ['R','W']) then
  679. begin
  680. FpSetErrno(ESysEnoent);
  681. exit(-1);
  682. end;
  683. if AssignPipe(pipi,pipo)=-1 Then
  684. Exit(-1);
  685. pid:=fpfork; // vfork in FreeBSD.
  686. if pid=-1 then
  687. begin
  688. close(pipi);
  689. close(pipo);
  690. exit(-1);
  691. end;
  692. if pid=0 then
  693. begin
  694. { We're in the child }
  695. if rw='W' then
  696. begin
  697. close(pipo);
  698. ret:=fpdup2(pipi,input);
  699. close(pipi);
  700. if ret=-1 then
  701. halt(127);
  702. end
  703. else
  704. begin
  705. close(pipi);
  706. ret:=fpdup2(pipo,output);
  707. close(pipo);
  708. if ret=-1 then
  709. halt(127);
  710. end;
  711. {$ifdef FPC_USE_FPEXEC}
  712. fpexecl('/bin/sh',['-c',Prog]);
  713. {$else}
  714. pp:=createshellargv(prog);
  715. fpExecve(pp^,pp,envp);
  716. {$endif}
  717. halt(127);
  718. end
  719. else
  720. begin
  721. { We're in the parent }
  722. if rw='W' then
  723. begin
  724. close(pipi);
  725. f:=pipo;
  726. textrec(f).bufptr:=@textrec(f).buffer;
  727. end
  728. else
  729. begin
  730. close(pipo);
  731. f:=pipi;
  732. textrec(f).bufptr:=@textrec(f).buffer;
  733. end;
  734. {Save the process ID - needed when closing }
  735. pl:=@(textrec(f).userdata[2]);
  736. pl^:=pid;
  737. textrec(f).closefunc:=@PCloseText;
  738. end;
  739. ret:=0;
  740. end;
  741. Function POpen(var F:file;const Prog:String;rw:char):cint;
  742. {
  743. Starts the program in 'Prog' and makes it's input or out put the
  744. other end of a pipe. If rw is 'w' or 'W', then whatever is written to
  745. F, will be read from stdin by the program in 'Prog'. The inverse is true
  746. for 'r' or 'R' : whatever the program in 'Prog' writes to stdout, can be
  747. read from 'f'.
  748. }
  749. var
  750. pipi,
  751. pipo : file;
  752. pid : cint;
  753. pl : ^cint;
  754. p,pp : ppchar;
  755. temp : string[255];
  756. ret : cint;
  757. begin
  758. rw:=upcase(rw);
  759. if not (rw in ['R','W']) then
  760. begin
  761. FpSetErrno(ESysEnoent);
  762. exit(-1);
  763. end;
  764. ret:=AssignPipe(pipi,pipo);
  765. if ret=-1 then
  766. exit(-1);
  767. pid:=fpfork;
  768. if pid=-1 then
  769. begin
  770. close(pipi);
  771. close(pipo);
  772. exit(-1);
  773. end;
  774. if pid=0 then
  775. begin
  776. { We're in the child }
  777. if rw='W' then
  778. begin
  779. close(pipo);
  780. ret:=fpdup2(filerec(pipi).handle,stdinputhandle);
  781. close(pipi);
  782. if ret=-1 then
  783. halt(127);
  784. end
  785. else
  786. begin
  787. close(pipi);
  788. ret:=fpdup2(filerec(pipo).handle,stdoutputhandle);
  789. close(pipo);
  790. if ret=1 then
  791. halt(127);
  792. end;
  793. {$ifdef FPC_USE_FPEXEC}
  794. fpexecl('/bin/sh',['-c',Prog]);
  795. {$else}
  796. getmem(pp,sizeof(pchar)*4);
  797. temp:='/bin/sh'#0'-c'#0+prog+#0;
  798. p:=pp;
  799. p^:=@temp[1];
  800. inc(p);
  801. p^:=@temp[9];
  802. inc(p);
  803. p^:=@temp[12];
  804. inc(p);
  805. p^:=Nil;
  806. fpExecve(ansistring('/bin/sh'),pp,envp);
  807. {$endif}
  808. halt(127);
  809. end
  810. else
  811. begin
  812. { We're in the parent }
  813. if rw='W' then
  814. begin
  815. close(pipi);
  816. f:=pipo;
  817. end
  818. else
  819. begin
  820. close(pipo);
  821. f:=pipi;
  822. end;
  823. {Save the process ID - needed when closing }
  824. pl:=@(filerec(f).userdata[2]);
  825. pl^:=pid;
  826. end;
  827. POpen:=0;
  828. end;
  829. Function AssignStream(Var StreamIn,Streamout:text;Const Prog:ansiString;const args : array of ansistring) : cint;
  830. {
  831. Starts the program in 'Prog' and makes its input and output the
  832. other end of two pipes, which are the stdin and stdout of a program
  833. specified in 'Prog'.
  834. streamout can be used to write to the program, streamin can be used to read
  835. the output of the program. See the following diagram :
  836. Parent Child
  837. STreamout --> Input
  838. Streamin <-- Output
  839. Return value is the process ID of the process being spawned, or -1 in case of failure.
  840. }
  841. var
  842. pipi,
  843. pipo : text;
  844. pid : cint;
  845. pl : ^cint;
  846. begin
  847. AssignStream:=-1;
  848. if AssignPipe(streamin,pipo)=-1 Then
  849. exit(-1);
  850. if AssignPipe(pipi,streamout)=-1 Then // shouldn't this close streamin and pipo?
  851. exit(-1);
  852. pid:=fpfork;
  853. if pid=-1 then
  854. begin
  855. close(pipi);
  856. close(pipo);
  857. close (streamin);
  858. close (streamout);
  859. exit;
  860. end;
  861. if pid=0 then
  862. begin
  863. { We're in the child }
  864. { Close what we don't need }
  865. close(streamout);
  866. close(streamin);
  867. if fpdup2(pipi,input)=-1 Then
  868. halt(127);
  869. close(pipi);
  870. If fpdup2(pipo,output)=-1 Then
  871. halt (127);
  872. close(pipo);
  873. fpExecl(Prog,args);
  874. halt(127);
  875. end
  876. else
  877. begin
  878. { we're in the parent}
  879. close(pipo);
  880. close(pipi);
  881. {Save the process ID - needed when closing }
  882. pl:=@(textrec(StreamIn).userdata[2]);
  883. pl^:=pid;
  884. textrec(StreamIn).closefunc:=@PCloseText;
  885. {Save the process ID - needed when closing }
  886. pl:=@(textrec(StreamOut).userdata[2]);
  887. pl^:=pid;
  888. textrec(StreamOut).closefunc:=@PCloseText;
  889. AssignStream:=Pid;
  890. end;
  891. end;
  892. Function AssignStream(Var StreamIn,Streamout,streamerr:text;Const Prog:ansiString;const args : array of ansistring) : cint;
  893. {
  894. Starts the program in 'prog' and makes its input, output and error output the
  895. other end of three pipes, which are the stdin, stdout and stderr of a program
  896. specified in 'prog'.
  897. StreamOut can be used to write to the program, StreamIn can be used to read
  898. the output of the program, StreamErr reads the error output of the program.
  899. See the following diagram :
  900. Parent Child
  901. StreamOut --> StdIn (input)
  902. StreamIn <-- StdOut (output)
  903. StreamErr <-- StdErr (error output)
  904. }
  905. var
  906. PipeIn, PipeOut, PipeErr: text;
  907. pid: cint;
  908. pl: ^cint;
  909. begin
  910. AssignStream := -1;
  911. // Assign pipes
  912. if AssignPipe(StreamIn, PipeOut)=-1 Then
  913. Exit(-1);
  914. If AssignPipe(StreamErr, PipeErr)=-1 Then
  915. begin
  916. Close(StreamIn);
  917. Close(PipeOut);
  918. exit(-1);
  919. end;
  920. if AssignPipe(PipeIn, StreamOut)=-1 Then
  921. begin
  922. Close(StreamIn);
  923. Close(PipeOut);
  924. Close(StreamErr);
  925. Close(PipeErr);
  926. exit(-1);
  927. end;
  928. // Fork
  929. pid := fpFork;
  930. if pid=-1 then begin
  931. Close(StreamIn);
  932. Close(PipeOut);
  933. Close(StreamErr);
  934. Close(PipeErr);
  935. Close(PipeIn);
  936. Close(StreamOut);
  937. exit(-1);
  938. end;
  939. if pid = 0 then begin
  940. // *** We are in the child ***
  941. // Close what we don not need
  942. Close(StreamOut);
  943. Close(StreamIn);
  944. Close(StreamErr);
  945. // Connect pipes
  946. if fpdup2(PipeIn, Input)=-1 Then
  947. Halt(127);
  948. Close(PipeIn);
  949. if fpdup2(PipeOut, Output)=-1 Then
  950. Halt(127);
  951. Close(PipeOut);
  952. if fpdup2(PipeErr, StdErr)=-1 Then
  953. Halt(127);
  954. Close(PipeErr);
  955. // Execute program
  956. fpExecl(Prog,args);
  957. Halt(127);
  958. end else begin
  959. // *** We are in the parent ***
  960. Close(PipeErr);
  961. Close(PipeOut);
  962. Close(PipeIn);
  963. // Save the process ID - needed when closing
  964. pl := @(TextRec(StreamIn).userdata[2]);
  965. pl^ := pid;
  966. TextRec(StreamIn).closefunc := @PCloseText;
  967. // Save the process ID - needed when closing
  968. pl := @(TextRec(StreamOut).userdata[2]);
  969. pl^ := pid;
  970. TextRec(StreamOut).closefunc := @PCloseText;
  971. // Save the process ID - needed when closing
  972. pl := @(TextRec(StreamErr).userdata[2]);
  973. pl^ := pid;
  974. TextRec(StreamErr).closefunc := @PCloseText;
  975. AssignStream := pid;
  976. end;
  977. end;
  978. {******************************************************************************
  979. General information calls
  980. ******************************************************************************}
  981. {$ifdef Linux}
  982. Function GetDomainName:String; { linux only!}
  983. // domainname is a glibc extension.
  984. {
  985. Get machines domain name. Returns empty string if not set.
  986. }
  987. Var
  988. Sysn : utsname;
  989. begin
  990. If fpUname(sysn)<>0 then
  991. getdomainname:=''
  992. else
  993. getdomainname:=strpas(@Sysn.domain[0]);
  994. end;
  995. {$endif}
  996. {$ifdef BSD}
  997. function intGetDomainName(Name:PChar; NameLen:Cint):cint;
  998. {$ifndef FPC_USE_LIBC}
  999. external name 'FPC_SYSC_GETDOMAINNAME';
  1000. {$else FPC_USE_LIBC}
  1001. cdecl; external clib name 'getdomainname';
  1002. {$endif FPC_USE_LIBC}
  1003. Function GetDomainName:String; { linux only!}
  1004. // domainname is a glibc extension.
  1005. {
  1006. Get machines domain name. Returns empty string if not set.
  1007. }
  1008. begin
  1009. if intGetDomainName(@getdomainname[1],255)=-1 then
  1010. getdomainname:=''
  1011. else
  1012. getdomainname[0]:=chr(strlen(@getdomainname[1]));
  1013. end;
  1014. {$endif}
  1015. Function GetHostName:String;
  1016. {
  1017. Get machines name. Returns empty string if not set.
  1018. }
  1019. Var
  1020. Sysn : utsname;
  1021. begin
  1022. If fpuname(sysn)=-1 then
  1023. gethostname:=''
  1024. else
  1025. gethostname:=strpas(@Sysn.nodename[0]);
  1026. end;
  1027. {******************************************************************************
  1028. Signal handling calls
  1029. ******************************************************************************}
  1030. procedure SigRaise(sig:integer);
  1031. begin
  1032. fpKill(fpGetPid,Sig);
  1033. end;
  1034. {******************************************************************************
  1035. Utility calls
  1036. ******************************************************************************}
  1037. Function FSearch(const path:AnsiString;dirlist:Ansistring;CurrentDirStrategy:TFSearchOption):AnsiString;
  1038. {
  1039. Searches for a file 'path' in the list of direcories in 'dirlist'.
  1040. returns an empty string if not found. Wildcards are NOT allowed.
  1041. If dirlist is empty, it is set to '.'
  1042. This function tries to make FSearch use ansistrings, and decrease
  1043. stringhandling overhead at the same time.
  1044. }
  1045. Var
  1046. mydir,NewDir : ansistring;
  1047. p1 : cint;
  1048. Info : Stat;
  1049. i,j : cint;
  1050. p : pchar;
  1051. Begin
  1052. if CurrentDirStrategy=CurrentDirectoryFirst Then
  1053. Dirlist:='.:'+dirlist; {Make sure current dir is first to be searched.}
  1054. if CurrentDirStrategy=CurrentDirectoryLast Then
  1055. Dirlist:=dirlist+':.'; {Make sure current dir is last to be searched.}
  1056. {Replace ':' and ';' with #0}
  1057. for p1:=1 to length(dirlist) do
  1058. if (dirlist[p1]=':') or (dirlist[p1]=';') then
  1059. dirlist[p1]:=#0;
  1060. {Check for WildCards}
  1061. If (Pos('?',Path) <> 0) or (Pos('*',Path) <> 0) Then
  1062. FSearch:='' {No wildcards allowed in these things.}
  1063. Else
  1064. Begin
  1065. p:=pchar(dirlist);
  1066. i:=length(dirlist);
  1067. j:=1;
  1068. Repeat
  1069. mydir:=ansistring(p);
  1070. if (length(mydir)>0) and (mydir[length(mydir)]<>'/') then
  1071. mydir:=mydir+'/';
  1072. NewDir:=mydir+Path;
  1073. if (FpStat(NewDir,Info)>=0) and
  1074. (not fpS_ISDIR(Info.st_Mode)) then
  1075. Begin
  1076. If Pos('./',NewDir)=1 Then
  1077. Delete(NewDir,1,2);
  1078. {DOS strips off an initial .\}
  1079. End
  1080. Else
  1081. NewDir:='';
  1082. while (j<=i) and (p^<>#0) do begin inc(j); inc(p); end;
  1083. if p^=#0 then inc(p);
  1084. Until (j>=i) or (Length(NewDir) > 0);
  1085. FSearch:=NewDir;
  1086. End;
  1087. End;
  1088. Function FSearch(const path:AnsiString;dirlist:Ansistring):AnsiString;
  1089. Begin
  1090. FSearch:=FSearch(path,dirlist,CurrentDirectoryFirst);
  1091. End;
  1092. {--------------------------------
  1093. Stat.Mode Macro's
  1094. --------------------------------}
  1095. Initialization
  1096. {$IFNDEF DONT_READ_TIMEZONE}
  1097. InitLocalTime;
  1098. {$endif}
  1099. finalization
  1100. {$IFNDEF DONT_READ_TIMEZONE}
  1101. DoneLocalTime;
  1102. {$endif}
  1103. End.
  1104. {
  1105. $Log$
  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. }