unix.pp 38 KB

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