sysutils.pp 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702
  1. {
  2. This file is part of the Free Pascal run time library.
  3. Copyright (c) 1999-2004 by the Free Pascal development team.
  4. Sysutils unit for netware (libc)
  5. See the file COPYING.FPC, included in this distribution,
  6. for details about the copyright.
  7. This program is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  10. **********************************************************************}
  11. unit sysutils;
  12. interface
  13. {$MODE objfpc}
  14. { force ansistrings }
  15. {$H+}
  16. uses Libc,DOS;
  17. TYPE
  18. TNetwareLibcFindData =
  19. RECORD
  20. DirP : Pdirent; { used for opendir }
  21. EntryP: Pdirent; { and readdir }
  22. Magic : longint; { to avoid abends with uninitialized TSearchRec }
  23. _mask : string; { search mask i.e. *.* }
  24. _dir : string; { directory where to search }
  25. _attr : longint; { specified attribute }
  26. fname : string; { full pathname of found file }
  27. END;
  28. {$DEFINE HAS_SLEEP}
  29. { Include platform independent interface part }
  30. {$i sysutilh.inc}
  31. { additional NetWare file flags}
  32. CONST
  33. faSHARE = M_A_SHARE shr 16; // Sharable file
  34. //faNO_SUBALLOC = $00000800; // Don't sub alloc. this file
  35. faTRANS = M_A_TRANS shr 16; // Transactional file (TTS usable)
  36. //faREADAUD = $00004000; // clib only: Read audit
  37. //faWRITAUD = $00008000; // clib only: Write audit
  38. faIMMPURG = M_A_IMMPURG shr 16; // Immediate purge
  39. faNORENAM = M_A_NORENAM shr 16; // Rename inhibit
  40. faNODELET = M_A_NODELET shr 16; // Delete inhibit
  41. faNOCOPY = M_A_NOCOPY shr 16; // Copy inhibit
  42. //faFILE_MIGRATED = $00400000; // clib only: File has been migrated
  43. //faDONT_MIGRATE = $00800000; // clib only: Don't migrate this file
  44. faIMMEDIATE_COMPRESS = M_A_IMMCOMPRESS shr 16; // Compress this file immediately
  45. faFILE_COMPRESSED = M_A_FILE_COMPRESSED shr 16; // File is compressed
  46. faDONT_COMPRESS = M_A_DONT_COMPRESS shr 16; // Don't compress this file
  47. faCANT_COMPRESS = M_A_CANT_COMPRESS shr 16; // Can't compress this file
  48. //faATTR_ARCHIVE = $40000000; // clib only: Entry has had an EA modified,
  49. // an ownerID changed, or trustee
  50. // info changed, etc.
  51. faSetNetwareAttrs = M_A_BITS_SIGNIFICANT; // if this is set, netware flags are changed also
  52. implementation
  53. uses
  54. sysconst;
  55. {$DEFINE FPC_FEXPAND_DRIVES}
  56. {$DEFINE FPC_FEXPAND_VOLUMES}
  57. {$DEFINE FPC_FEXPAND_NO_DEFAULT_PATHS}
  58. { Include platform independent implementation part }
  59. {$i sysutils.inc}
  60. {****************************************************************************
  61. File Functions
  62. ****************************************************************************}
  63. Function FileOpen (Const FileName : string; Mode : Integer) : THandle;
  64. VAR NWOpenFlags : longint;
  65. BEGIN
  66. NWOpenFlags:=0;
  67. Case (Mode and 3) of
  68. 0 : NWOpenFlags:=NWOpenFlags or O_RDONLY;
  69. 1 : NWOpenFlags:=NWOpenFlags or O_WRONLY;
  70. 2 : NWOpenFlags:=NWOpenFlags or O_RDWR;
  71. end;
  72. FileOpen := Fpopen (pchar(FileName),NWOpenFlags);
  73. //!! We need to set locking based on Mode !!
  74. end;
  75. Function FileCreate (Const FileName : String) : THandle;
  76. begin
  77. FileCreate:=Fpopen(Pchar(FileName),O_RdWr or O_Creat or O_Trunc or O_Binary);
  78. if FileCreate >= 0 then
  79. FileSetAttr (Filename, 0); // dont know why but open always sets ReadOnly flag
  80. end;
  81. Function FileCreate (Const FileName : String; mode:longint) : THandle;
  82. begin
  83. FileCreate:=FileCreate (FileName);
  84. end;
  85. Function FileRead (Handle : THandle; Var Buffer; Count : longint) : Longint;
  86. begin
  87. FileRead:=libc.fpread (Handle,@Buffer,Count);
  88. end;
  89. Function FileWrite (Handle : THandle; const Buffer; Count : Longint) : Longint;
  90. begin
  91. FileWrite:=libc.fpwrite (Handle,@Buffer,Count);
  92. end;
  93. Function FileSeek (Handle : THandle; FOffset,Origin : Longint) : Longint;
  94. begin
  95. FileSeek:=libc.fplseek (Handle,FOffset,Origin);
  96. end;
  97. Function FileSeek (Handle : THandle; FOffset: Int64; Origin: Longint) : Int64;
  98. begin
  99. FileSeek:=libc.fplseek64 (Handle,FOffset,Origin);
  100. end;
  101. Procedure FileClose (Handle : THandle);
  102. begin
  103. libc.fpclose(Handle);
  104. end;
  105. Function FileTruncate (Handle : THandle; Size: Longint) : boolean;
  106. begin
  107. FileTruncate:=(libc.fpchsize(Handle,Size) = 0);
  108. end;
  109. Function FileLock (Handle : THandle; FOffset,FLen : Longint) : Longint;
  110. begin
  111. {$warning FileLock not implemented}
  112. //FileLock := _lock (Handle,FOffset,FLen);
  113. FileLock := -1;
  114. end;
  115. Function FileLock (Handle : THandle; FOffset,FLen : Int64) : Longint;
  116. begin
  117. {$warning need to add 64bit FileLock call }
  118. //FileLock := FileLock (Handle, longint(FOffset),longint(FLen));
  119. FileLock := -1;
  120. end;
  121. Function FileUnlock (Handle : THandle; FOffset,FLen : Longint) : Longint;
  122. begin
  123. //FileUnlock := _unlock (Handle,FOffset,FLen);
  124. {$warning FileUnLock not implemented}
  125. FileUnlock := -1;
  126. end;
  127. Function FileUnlock (Handle : THandle; FOffset,FLen : Int64) : Longint;
  128. begin
  129. {$warning need to add 64bit FileUnlock call }
  130. //FileUnlock := FileUnlock (Handle, longint(FOffset),longint(FLen));
  131. FileUnlock := -1;
  132. end;
  133. Function FileAge (Const FileName : String): Longint;
  134. var Info : TStat;
  135. TM : TTM;
  136. begin
  137. If Fpstat (pchar(FileName),Info) <> 0 then
  138. exit(-1)
  139. else
  140. begin
  141. localtime_r (Info.st_mtim.tv_sec,tm);
  142. with TM do
  143. result:=DateTimeToFileDate(EncodeDate(tm_year+1900,tm_mon+1,tm_mday)+EncodeTime(tm_hour,tm_min,tm_sec,0));
  144. end;
  145. end;
  146. Function FileExists (Const FileName : String) : Boolean;
  147. VAR Info : TStat;
  148. begin
  149. FileExists:=(Fpstat(pchar(filename),Info) = 0);
  150. end;
  151. Function UnixToWinAge(UnixAge : time_t): Longint;
  152. Var tm : TTm;
  153. begin
  154. libc.localtime_r (UnixAge, tm);
  155. with tm do
  156. Result:=DateTimeToFileDate(EncodeDate(tm_year+1900,tm_mon+1,tm_mday)+EncodeTime(tm_hour,tm_min,tm_sec,0));
  157. end;
  158. {returns true if attributes match}
  159. function find_setfields (var f : TsearchRec; var AttrsOk : boolean) : longint;
  160. var
  161. StatBuf : TStat;
  162. fname : string;
  163. begin
  164. result := 0;
  165. with F do
  166. begin
  167. if FindData.Magic = $AD02 then
  168. begin
  169. attr := (Pdirent(FindData.EntryP)^.d_mode shr 16) and $ffff;
  170. size := Pdirent(FindData.EntryP)^.d_size;
  171. name := strpas (Pdirent(FindData.EntryP)^.d_name);
  172. fname := FindData._dir + name;
  173. if Fpstat (pchar(fname),StatBuf) = 0 then
  174. time := UnixToWinAge (StatBuf.st_mtim.tv_sec)
  175. else
  176. time := 0;
  177. AttrsOk := false;
  178. if (f.FindData._attr and faHidden) = 0 then
  179. if attr and faHidden > 0 then exit;
  180. if (f.FindData._attr and faDirectory) = 0 then
  181. if attr and faDirectory > 0 then exit;
  182. if (f.FindData._attr and faSysFile) = 0 then
  183. if attr and faSysFile > 0 then exit;
  184. AttrsOk := true;
  185. end else
  186. begin
  187. FillChar (f,sizeof(f),0);
  188. result := 18;
  189. end;
  190. end;
  191. end;
  192. function findfirst(const path : string;attr : longint; out Rslt : TsearchRec) : longint;
  193. var
  194. path0 : string;
  195. p : longint;
  196. begin
  197. IF path = '' then
  198. begin
  199. result := 18;
  200. exit;
  201. end;
  202. Rslt.FindData._attr := attr;
  203. p := length (path);
  204. while (p > 0) and (not (path[p] in ['\','/'])) do
  205. dec (p);
  206. if p > 0 then
  207. begin
  208. Rslt.FindData._mask := copy (path,p+1,255);
  209. Rslt.FindData._dir := copy (path,1,p);
  210. end else
  211. begin
  212. Rslt.FindData._mask := path;
  213. Rslt.FindData._dir := GetCurrentDir;
  214. if (Rslt.FindData._dir[length(Rslt.FindData._dir)] <> '/') and
  215. (Rslt.FindData._dir[length(Rslt.FindData._dir)] <> '\') then
  216. Rslt.FindData._dir := Rslt.FindData._dir + '/';
  217. end;
  218. if Rslt.FindData._mask = '*' then Rslt.FindData._mask := '';
  219. if Rslt.FindData._mask = '*.*' then Rslt.FindData._mask := '';
  220. //writeln (stderr,'mask: "',Rslt._mask,'" dir:"',path0,'"');
  221. Pdirent(Rslt.FindData.DirP) := opendir (pchar(Rslt.FindData._dir));
  222. if Rslt.FindData.DirP = nil then
  223. result := 18
  224. else begin
  225. Rslt.FindData.Magic := $AD02;
  226. result := findnext (Rslt);
  227. end;
  228. end;
  229. function findnext(var Rslt : TsearchRec) : longint;
  230. var attrsOk : boolean;
  231. begin
  232. if Rslt.FindData.Magic <> $AD02 then
  233. begin
  234. result := 18;
  235. exit;
  236. end;
  237. result:=0;
  238. repeat
  239. Pdirent(Rslt.FindData.EntryP) := readdir (Pdirent(Rslt.FindData.DirP));
  240. if Rslt.FindData.EntryP = nil then
  241. result := 18
  242. else
  243. result := find_setfields (Rslt,attrsOk);
  244. if (result = 0) and (attrsOk) then
  245. begin
  246. if Rslt.FindData._mask = #0 then exit;
  247. if fnmatch(@Rslt.FindData._mask[1],Pdirent(Rslt.FindData.EntryP)^.d_name,FNM_CASEFOLD) = 0 then
  248. exit;
  249. end;
  250. until result <> 0;
  251. end;
  252. Procedure FindClose(Var f: TSearchRec);
  253. begin
  254. if F.FindData.Magic <> $AD02 then exit;
  255. doserror:=0;
  256. closedir (Pdirent(f.FindData.DirP));
  257. FillChar (f,sizeof(f),0);
  258. end;
  259. Function FileGetDate (Handle : THandle) : Longint;
  260. Var Info : TStat;
  261. _PTM : PTM;
  262. begin
  263. If Fpfstat(Handle,Info) <> 0 then
  264. Result:=-1
  265. else
  266. begin
  267. _PTM := localtime (Info.st_mtim.tv_sec);
  268. IF _PTM = NIL THEN
  269. exit(-1)
  270. else
  271. with _PTM^ do
  272. Result:=DateTimeToFileDate(EncodeDate(tm_year+1900,tm_mon+1,tm_mday)+EncodeTime(tm_hour,tm_min,tm_sec,0));
  273. end;
  274. end;
  275. Function FileSetDate (Handle : THandle; Age : Longint) : Longint;
  276. Begin
  277. {dont know how to do that, utime needs filename}
  278. result := -1;
  279. end;
  280. Function FileGetAttr (Const FileName : String) : Longint;
  281. Var Info : TStat;
  282. begin
  283. If Fpstat (pchar(FileName),Info) <> 0 then
  284. Result:=-1
  285. Else
  286. Result := (Info.st_mode shr 16) and $ffff;
  287. end;
  288. Function FileSetAttr (Const Filename : String; Attr: longint) : Longint;
  289. var
  290. StatBuf : TStat;
  291. newMode : longint;
  292. begin
  293. if Fpstat (pchar(Filename),StatBuf) = 0 then
  294. begin
  295. {what should i do here ?
  296. only support sysutils-standard attributes or also support the extensions defined
  297. only for netware libc ?
  298. For now i allow the complete attributes if the bit faSetNetwareAttrs is set. Otherwise
  299. only the standard attributes can be modified}
  300. if attr and faSetNetwareAttrs > 0 then
  301. begin
  302. newmode := ((attr shl 16) and $ffff0000) or M_A_BITS_SIGNIFICANT;
  303. end else
  304. begin
  305. attr := (attr and $2f) shl 16;
  306. newmode := StatBuf.st_mode and ($ffff0000-M_A_RDONLY-M_A_HIDDEN- M_A_SYSTEM-M_A_SUBDIR-M_A_ARCH);
  307. newmode := newmode or (attr shl 16) or M_A_BITS_SIGNIFICANT;
  308. end;
  309. if Fpchmod (pchar(Filename),newMode) < 0 then
  310. result := ___errno^ else
  311. result := 0;
  312. end else
  313. result := ___errno^;
  314. end;
  315. Function DeleteFile (Const FileName : String) : Boolean;
  316. begin
  317. Result:= (libc.UnLink (pchar(FileName)) = 0);
  318. end;
  319. Function RenameFile (Const OldName, NewName : String) : Boolean;
  320. begin
  321. RenameFile:=(libc.rename(pchar(OldName),pchar(NewName)) = 0);
  322. end;
  323. {****************************************************************************
  324. Disk Functions
  325. ****************************************************************************}
  326. {
  327. The Diskfree and Disksize functions need a file on the specified drive, since this
  328. is required for the statfs system call.
  329. These filenames are set in drivestr[0..26], and have been preset to :
  330. 0 - '.' (default drive - hence current dir is ok.)
  331. 1 - '/fd0/.' (floppy drive 1 - should be adapted to local system )
  332. 2 - '/fd1/.' (floppy drive 2 - should be adapted to local system )
  333. 3 - '/' (C: equivalent of dos is the root partition)
  334. 4..26 (can be set by you're own applications)
  335. ! Use AddDisk() to Add new drives !
  336. They both return -1 when a failure occurs.
  337. }
  338. Const
  339. FixDriveStr : array[0..3] of pchar=(
  340. '.',
  341. 'a:.',
  342. 'b:.',
  343. 'sys:/'
  344. );
  345. var
  346. Drives : byte;
  347. DriveStr : array[4..26] of pchar;
  348. Procedure AddDisk(const path:string);
  349. begin
  350. if not (DriveStr[Drives]=nil) then
  351. FreeMem(DriveStr[Drives],StrLen(DriveStr[Drives])+1);
  352. GetMem(DriveStr[Drives],length(Path)+1);
  353. StrPCopy(DriveStr[Drives],path);
  354. inc(Drives);
  355. if Drives>26 then
  356. Drives:=4;
  357. end;
  358. Function DiskFree(Drive: Byte): int64;
  359. //var fs : Tstatfs;
  360. Begin
  361. { if ((Drive<4) and (not (fixdrivestr[Drive]=nil)) and fsstat(StrPas(fixdrivestr[drive]),fs)) or
  362. ((not (drivestr[Drive]=nil)) and fsstat(StrPas(drivestr[drive]),fs)) then
  363. Diskfree:=int64(fs.bavail)*int64(fs.bsize)
  364. else
  365. Diskfree:=-1;}
  366. DiskFree := -1;
  367. ConsolePrintf ('warning: fpc sysutils.diskfree not implemented'#13#10);
  368. {$warning DiskFree not implemented (does it make sense ?) }
  369. End;
  370. Function DiskSize(Drive: Byte): int64;
  371. //var fs : statfs;
  372. Begin
  373. { if ((Drive<4) and (not (fixdrivestr[Drive]=nil)) and fsstat(StrPas(fixdrivestr[drive]),fs)) or
  374. ((not (drivestr[Drive]=nil)) and fsstat(StrPas(drivestr[drive]),fs)) then
  375. DiskSize:=int64(fs.blocks)*int64(fs.bsize)
  376. else
  377. DiskSize:=-1;}
  378. DiskSize := -1;
  379. ConsolePrintf ('warning: fpc sysutils.disksize not implemented'#13#10);
  380. {$warning DiskSize not implemented (does it make sense ?) }
  381. End;
  382. Function GetCurrentDir : String;
  383. begin
  384. GetDir (0,Result);
  385. end;
  386. Function SetCurrentDir (Const NewDir : String) : Boolean;
  387. begin
  388. Libc.FpChDir(pchar(NewDir));
  389. result := (___errno^ = 0);
  390. end;
  391. Function CreateDir (Const NewDir : String) : Boolean;
  392. begin
  393. Libc.FpMkDir(pchar(NewDir),0);
  394. result := (___errno^ = 0);
  395. end;
  396. Function RemoveDir (Const Dir : String) : Boolean;
  397. begin
  398. libc.FpRmDir(pchar(Dir));
  399. result := (___errno^ = 0);
  400. end;
  401. function DirectoryExists (const Directory: string): boolean;
  402. var Info : TStat;
  403. begin
  404. If Fpstat (pchar(Directory),Info) <> 0 then
  405. exit(false)
  406. else
  407. Exit ((Info.st_mode and M_A_SUBDIR) <> 0);
  408. end;
  409. {****************************************************************************
  410. Misc Functions
  411. ****************************************************************************}
  412. procedure Beep;
  413. begin
  414. RingBell;
  415. end;
  416. {****************************************************************************
  417. Locale Functions
  418. ****************************************************************************}
  419. Procedure GetLocalTime(var SystemTime: TSystemTime);
  420. var t : TTime;
  421. tm: Ttm;
  422. begin
  423. libc.time(t);
  424. libc.localtime_r(t,tm);
  425. with SystemTime do
  426. begin
  427. Hour := tm.tm_hour;
  428. Minute := tm.tm_min;
  429. Second := tm.tm_sec;
  430. MilliSecond := 0;
  431. Day := tm.tm_mday;
  432. Month := tm.tm_mon+1;
  433. Year := tm.tm_year+1900;
  434. end;
  435. end;
  436. Procedure InitAnsi;
  437. Var i : longint;
  438. begin
  439. { Fill table entries 0 to 127 }
  440. for i := 0 to 96 do
  441. UpperCaseTable[i] := chr(i);
  442. for i := 97 to 122 do
  443. UpperCaseTable[i] := chr(i - 32);
  444. for i := 123 to 191 do
  445. UpperCaseTable[i] := chr(i);
  446. Move (CPISO88591UCT,UpperCaseTable[192],SizeOf(CPISO88591UCT));
  447. for i := 0 to 64 do
  448. LowerCaseTable[i] := chr(i);
  449. for i := 65 to 90 do
  450. LowerCaseTable[i] := chr(i + 32);
  451. for i := 91 to 191 do
  452. LowerCaseTable[i] := chr(i);
  453. Move (CPISO88591LCT,UpperCaseTable[192],SizeOf(CPISO88591UCT));
  454. end;
  455. Procedure InitInternational;
  456. begin
  457. InitInternationalGeneric;
  458. InitAnsi;
  459. end;
  460. function SysErrorMessage(ErrorCode: Integer): String;
  461. begin
  462. Result:=''; // only found perror that prints the message
  463. end;
  464. {****************************************************************************
  465. OS utility functions
  466. ****************************************************************************}
  467. Function GetEnvironmentVariable(Const EnvVar : String) : String;
  468. begin
  469. Result:=StrPas(libc.getenv(PChar(EnvVar)));
  470. end;
  471. Function GetEnvironmentVariableCount : Integer;
  472. begin
  473. Result:=FPCCountEnvVar(EnvP);
  474. end;
  475. Function GetEnvironmentString(Index : Integer) : String;
  476. begin
  477. Result:=FPCGetEnvStrFromP(Envp,Index);
  478. end;
  479. function ExecuteProcess(Const Path: AnsiString; Const ComLine: AnsiString):integer;
  480. var
  481. params:array of AnsiString;
  482. count,i: longint;
  483. Buf : pchar;
  484. p : pchar;
  485. CLine: AnsiString;
  486. begin
  487. cLine := ComLine;
  488. buf:=pchar(CLine);
  489. count:=0;
  490. while(buf^<>#0) do
  491. begin
  492. while (buf^ in [' ',#9,#10]) do
  493. inc(buf);
  494. inc(count);
  495. while not (buf^ in [' ',#0,#9,#10]) do
  496. inc(buf);
  497. end;
  498. i := 0;
  499. setlength(params,count);
  500. buf:=pchar(CLine);
  501. while(buf^<>#0) do
  502. begin
  503. while (buf^ in [' ',#9,#10]) do
  504. inc(buf);
  505. p := buf;
  506. while not (buf^ in [' ',#0,#9,#10]) do
  507. inc(buf);
  508. if buf^ <> #0 then
  509. begin
  510. buf^ := #0;
  511. inc(buf);
  512. end;
  513. params[i]:=p;
  514. inc(i);
  515. end;
  516. result := ExecuteProcess (Path, params);
  517. end;
  518. {******************************************************************************
  519. --- Exec ---
  520. ******************************************************************************}
  521. const maxargs=256;
  522. function ExecuteProcess (const Path: AnsiString;
  523. const ComLine: array of AnsiString): integer;
  524. var c : comstr;
  525. i : integer;
  526. args : array[0..maxargs+1] of pchar;
  527. arg0 : string;
  528. numargs,wstat : integer;
  529. Wiring : TWiring;
  530. newPath : string;
  531. e : EOSError;
  532. begin
  533. if pos ('.',path) = 0 then
  534. arg0 := fexpand(path+'.nlm')
  535. else
  536. arg0 := fexpand (path);
  537. args[0] := pchar(arg0);
  538. numargs := 0;
  539. for I := 0 to High (ComLine) do
  540. if numargs < maxargs then
  541. begin
  542. inc(numargs);
  543. args[numargs] := pchar(ComLine[i]);
  544. end;
  545. args[numargs+1] := nil;
  546. Wiring.infd := StdInputHandle; //textrec(Stdin).Handle;
  547. Wiring.outfd:= textrec(stdout).Handle;
  548. Wiring.errfd:= textrec(stderr).Handle;
  549. i := procve(args[0],
  550. PROC_CURRENT_SPACE+PROC_INHERIT_CWD,
  551. envP, // const char * env[] If passed as NULL, the child process inherits the parent.s environment at the time of the call.
  552. @Wiring, // wiring_t *wiring, Pass NULL to inherit system defaults for wiring.
  553. nil, // struct fd_set *fds, Not currently implemented. Pass in NULL.
  554. nil, // void *appdata, Not currently implemented. Pass in NULL.
  555. 0, // size_t appdata_size, Not currently implemented. Pass in 0
  556. nil, // void *reserved, Reserved. Pass NULL.
  557. @args); // const char *argv[]
  558. if i <> -1 then
  559. begin
  560. Fpwaitpid(i,@wstat,0);
  561. result := wstat;
  562. end else
  563. begin
  564. e:=EOSError.CreateFmt(SExecuteProcessFailed,[arg0,___errno^]);
  565. e.ErrorCode:=___errno^;
  566. raise e;
  567. end;
  568. end;
  569. procedure Sleep(milliseconds: Cardinal);
  570. begin
  571. libc._delay (milliseconds);
  572. end;
  573. {****************************************************************************
  574. Initialization code
  575. ****************************************************************************}
  576. Initialization
  577. InitExceptions; { Initialize exceptions. OS independent }
  578. InitInternational; { Initialize internationalization settings }
  579. Finalization
  580. DoneExceptions;
  581. end.