sysutils.pp 20 KB

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