sysutils.pp 19 KB

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