sysutils.pp 20 KB

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