2
0

sysutils.pp 21 KB

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