sysutils.pp 21 KB

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