sysutils.pp 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660
  1. {
  2. $Id$
  3. This file is part of the Free Pascal run time library.
  4. Copyright (c) 1999-2004 by the Free Pascal development team.
  5. Sysutils unit for netware (libc)
  6. See the file COPYING.FPC, included in this distribution,
  7. for details about the copyright.
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  11. **********************************************************************}
  12. unit sysutils;
  13. interface
  14. {$MODE objfpc}
  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. { Include platform independent interface part }
  30. {$i sysutilh.inc}
  31. { additional NetWare file flags}
  32. CONST
  33. faSHARE = M_A_SHARE shr 16; // Sharable file
  34. //faNO_SUBALLOC = $00000800; // Don't sub alloc. this file
  35. faTRANS = M_A_TRANS shr 16; // Transactional file (TTS usable)
  36. //faREADAUD = $00004000; // clib only: Read audit
  37. //faWRITAUD = $00008000; // clib only: Write audit
  38. faIMMPURG = M_A_IMMPURG shr 16; // Immediate purge
  39. faNORENAM = M_A_NORENAM shr 16; // Rename inhibit
  40. faNODELET = M_A_NODELET shr 16; // Delete inhibit
  41. faNOCOPY = M_A_NOCOPY shr 16; // Copy inhibit
  42. //faFILE_MIGRATED = $00400000; // clib only: File has been migrated
  43. //faDONT_MIGRATE = $00800000; // clib only: Don't migrate this file
  44. faIMMEDIATE_COMPRESS = M_A_IMMCOMPRESS shr 16; // Compress this file immediately
  45. faFILE_COMPRESSED = M_A_FILE_COMPRESSED shr 16; // File is compressed
  46. faDONT_COMPRESS = M_A_DONT_COMPRESS shr 16; // Don't compress this file
  47. faCANT_COMPRESS = M_A_CANT_COMPRESS shr 16; // Can't compress this file
  48. //faATTR_ARCHIVE = $40000000; // clib only: Entry has had an EA modified,
  49. // an ownerID changed, or trustee
  50. // info changed, etc.
  51. faSetNetwareAttrs = M_A_BITS_SIGNIFICANT; // if this is set, netware flags are changed also
  52. implementation
  53. uses
  54. sysconst;
  55. { Include platform independent implementation part }
  56. {$i sysutils.inc}
  57. {****************************************************************************
  58. File Functions
  59. ****************************************************************************}
  60. Function FileOpen (Const FileName : string; Mode : Integer) : Longint;
  61. VAR NWOpenFlags : longint;
  62. BEGIN
  63. NWOpenFlags:=0;
  64. Case (Mode and 3) of
  65. 0 : NWOpenFlags:=NWOpenFlags or O_RDONLY;
  66. 1 : NWOpenFlags:=NWOpenFlags or O_WRONLY;
  67. 2 : NWOpenFlags:=NWOpenFlags or O_RDWR;
  68. end;
  69. FileOpen := Fpopen (pchar(FileName),NWOpenFlags);
  70. //!! We need to set locking based on Mode !!
  71. end;
  72. Function FileCreate (Const FileName : String) : Longint;
  73. begin
  74. FileCreate:=Fpopen(Pchar(FileName),O_RdWr or O_Creat or O_Trunc or O_Binary);
  75. if FileCreate >= 0 then
  76. FileSetAttr (Filename, 0); // dont know why but open always sets ReadOnly flag
  77. end;
  78. Function FileCreate (Const FileName : String; mode:longint) : Longint;
  79. begin
  80. FileCreate:=FileCreate (FileName);
  81. end;
  82. Function FileRead (Handle : Longint; Var Buffer; Count : longint) : Longint;
  83. begin
  84. FileRead:=libc.fpread (Handle,@Buffer,Count);
  85. end;
  86. Function FileWrite (Handle : Longint; const Buffer; Count : Longint) : Longint;
  87. begin
  88. FileWrite:=libc.fpwrite (Handle,@Buffer,Count);
  89. end;
  90. Function FileSeek (Handle,FOffset,Origin : Longint) : Longint;
  91. begin
  92. FileSeek:=libc.fplseek (Handle,FOffset,Origin);
  93. end;
  94. Function FileSeek (Handle : Longint; FOffset,Origin : Int64) : Int64;
  95. begin
  96. FileSeek:=libc.fplseek64 (Handle,FOffset,Origin);
  97. end;
  98. Procedure FileClose (Handle : Longint);
  99. begin
  100. libc.fpclose(Handle);
  101. end;
  102. Function FileTruncate (Handle,Size: Longint) : boolean;
  103. begin
  104. FileTruncate:=(libc.fpchsize(Handle,Size) = 0);
  105. end;
  106. Function FileLock (Handle,FOffset,FLen : Longint) : Longint;
  107. begin
  108. {$warning FileLock not implemented}
  109. //FileLock := _lock (Handle,FOffset,FLen);
  110. FileLock := -1;
  111. end;
  112. Function FileLock (Handle : Longint; FOffset,FLen : Int64) : Longint;
  113. begin
  114. {$warning need to add 64bit FileLock call }
  115. //FileLock := FileLock (Handle, longint(FOffset),longint(FLen));
  116. FileLock := -1;
  117. end;
  118. Function FileUnlock (Handle,FOffset,FLen : Longint) : Longint;
  119. begin
  120. //FileUnlock := _unlock (Handle,FOffset,FLen);
  121. {$warning FileUnLock not implemented}
  122. FileUnlock := -1;
  123. end;
  124. Function FileUnlock (Handle : Longint; FOffset,FLen : Int64) : Longint;
  125. begin
  126. {$warning need to add 64bit FileUnlock call }
  127. //FileUnlock := FileUnlock (Handle, longint(FOffset),longint(FLen));
  128. FileUnlock := -1;
  129. end;
  130. Function FileAge (Const FileName : String): Longint;
  131. var Info : TStat;
  132. TM : TTM;
  133. begin
  134. If Fpstat (pchar(FileName),Info) <> 0 then
  135. exit(-1)
  136. else
  137. begin
  138. localtime_r (Info.st_mtim.tv_sec,tm);
  139. with TM do
  140. result:=DateTimeToFileDate(EncodeDate(tm_year+1900,tm_mon+1,tm_mday)+EncodeTime(tm_hour,tm_min,tm_sec,0));
  141. end;
  142. end;
  143. Function FileExists (Const FileName : String) : Boolean;
  144. VAR Info : TStat;
  145. begin
  146. FileExists:=(Fpstat(pchar(filename),Info) = 0);
  147. end;
  148. (*
  149. PROCEDURE find_setfields (VAR f : TsearchRec);
  150. VAR T : Dos.DateTime;
  151. BEGIN
  152. WITH F DO
  153. BEGIN
  154. IF FindData.Magic = $AD01 THEN
  155. BEGIN
  156. {attr := FindData.EntryP^.d_attr AND $FF;} // lowest 8 bit -> same as dos
  157. attr := FindData.EntryP^.d_flags; { return complete netware attributes }
  158. //!!UnpackTime(FindData.EntryP^.d_time + (LONGINT (FindData.EntryP^.d_date) SHL 16), T);
  159. //!!time := DateTimeToFileDate(EncodeDate(T.Year,T.Month,T.day)+EncodeTime(T.Hour,T.Min,T.Sec,0));
  160. size := FindData.EntryP^.d_size;
  161. name := strpas (FindData.EntryP^.d_name);
  162. END ELSE
  163. BEGIN
  164. FillChar (f,SIZEOF(f),0);
  165. END;
  166. END;
  167. END;*)
  168. Function UnixToWinAge(UnixAge : time_t): Longint;
  169. Var tm : TTm;
  170. begin
  171. libc.localtime_r (UnixAge, tm);
  172. with tm do
  173. Result:=DateTimeToFileDate(EncodeDate(tm_year+1900,tm_mon+1,tm_mday)+EncodeTime(tm_hour,tm_min,tm_sec,0));
  174. end;
  175. {returns true if attributes match}
  176. function find_setfields (var f : TsearchRec; var AttrsOk : boolean) : longint;
  177. var
  178. StatBuf : TStat;
  179. fname : string;
  180. begin
  181. result := 0;
  182. with F do
  183. begin
  184. if FindData.Magic = $AD02 then
  185. begin
  186. attr := (Pdirent(FindData.EntryP)^.d_mode shr 16) and $ffff;
  187. size := Pdirent(FindData.EntryP)^.d_size;
  188. name := strpas (Pdirent(FindData.EntryP)^.d_name);
  189. fname := FindData._dir + name;
  190. if Fpstat (pchar(fname),StatBuf) = 0 then
  191. time := UnixToWinAge (StatBuf.st_mtim.tv_sec)
  192. else
  193. time := 0;
  194. AttrsOk := false;
  195. if (f.FindData._attr and faHidden) = 0 then
  196. if attr and faHidden > 0 then exit;
  197. if (f.FindData._attr and faDirectory) = 0 then
  198. if attr and faDirectory > 0 then exit;
  199. if (f.FindData._attr and faSysFile) = 0 then
  200. if attr and faSysFile > 0 then exit;
  201. AttrsOk := true;
  202. end else
  203. begin
  204. FillChar (f,sizeof(f),0);
  205. result := 18;
  206. end;
  207. end;
  208. end;
  209. function findfirst(const path : string;attr : longint;var Rslt : TsearchRec) : longint;
  210. var
  211. path0 : string;
  212. p : longint;
  213. begin
  214. IF path = '' then
  215. begin
  216. result := 18;
  217. exit;
  218. end;
  219. Rslt.FindData._attr := attr;
  220. p := length (path);
  221. while (p > 0) and (not (path[p] in ['\','/'])) do
  222. dec (p);
  223. if p > 0 then
  224. begin
  225. Rslt.FindData._mask := copy (path,p+1,255);
  226. Rslt.FindData._dir := copy (path,1,p);
  227. end else
  228. begin
  229. Rslt.FindData._mask := path;
  230. Rslt.FindData._dir := GetCurrentDir;
  231. if (Rslt.FindData._dir[length(Rslt.FindData._dir)] <> '/') and
  232. (Rslt.FindData._dir[length(Rslt.FindData._dir)] <> '\') then
  233. Rslt.FindData._dir := Rslt.FindData._dir + '/';
  234. end;
  235. if Rslt.FindData._mask = '*' then Rslt.FindData._mask := '';
  236. if Rslt.FindData._mask = '*.*' then Rslt.FindData._mask := '';
  237. //writeln (stderr,'mask: "',Rslt._mask,'" dir:"',path0,'"');
  238. Pdirent(Rslt.FindData.DirP) := opendir (pchar(Rslt.FindData._dir));
  239. if Rslt.FindData.DirP = nil then
  240. result := 18
  241. else begin
  242. Rslt.FindData.Magic := $AD02;
  243. result := findnext (Rslt);
  244. end;
  245. end;
  246. function findnext(var Rslt : TsearchRec) : longint;
  247. var attrsOk : boolean;
  248. begin
  249. if Rslt.FindData.Magic <> $AD02 then
  250. begin
  251. result := 18;
  252. exit;
  253. end;
  254. result:=0;
  255. repeat
  256. Pdirent(Rslt.FindData.EntryP) := readdir (Pdirent(Rslt.FindData.DirP));
  257. if Rslt.FindData.EntryP = nil then
  258. result := 18
  259. else
  260. result := find_setfields (Rslt,attrsOk);
  261. if (result = 0) and (attrsOk) then
  262. begin
  263. if Rslt.FindData._mask = #0 then exit;
  264. if fnmatch(@Rslt.FindData._mask[1],Pdirent(Rslt.FindData.EntryP)^.d_name,FNM_CASEFOLD) = 0 then
  265. exit;
  266. end;
  267. until result <> 0;
  268. end;
  269. Procedure FindClose(Var f: TSearchRec);
  270. begin
  271. if F.FindData.Magic <> $AD02 then exit;
  272. doserror:=0;
  273. closedir (Pdirent(f.FindData.DirP));
  274. FillChar (f,sizeof(f),0);
  275. end;
  276. Function FileGetDate (Handle : Longint) : Longint;
  277. Var Info : TStat;
  278. _PTM : PTM;
  279. begin
  280. If Fpfstat(Handle,Info) <> 0 then
  281. Result:=-1
  282. else
  283. begin
  284. _PTM := localtime (Info.st_mtim.tv_sec);
  285. IF _PTM = NIL THEN
  286. exit(-1)
  287. else
  288. with _PTM^ do
  289. Result:=DateTimeToFileDate(EncodeDate(tm_year+1900,tm_mon+1,tm_mday)+EncodeTime(tm_hour,tm_min,tm_sec,0));
  290. end;
  291. end;
  292. Function FileSetDate (Handle,Age : Longint) : Longint;
  293. Begin
  294. {dont know how to do that, utime needs filename}
  295. result := -1;
  296. end;
  297. Function FileGetAttr (Const FileName : String) : Longint;
  298. Var Info : TStat;
  299. begin
  300. If Fpstat (pchar(FileName),Info) <> 0 then
  301. Result:=-1
  302. Else
  303. Result := (Info.st_mode shr 16) and $ffff;
  304. end;
  305. Function FileSetAttr (Const Filename : String; Attr: longint) : Longint;
  306. var
  307. StatBuf : TStat;
  308. newMode : longint;
  309. begin
  310. if Fpstat (pchar(Filename),StatBuf) = 0 then
  311. begin
  312. {what should i do here ?
  313. only support sysutils-standard attributes or also support the extensions defined
  314. only for netware libc ?
  315. For now i allow the complete attributes if the bit faSetNetwareAttrs is set. Otherwise
  316. only the standard attributes can be modified}
  317. if attr and faSetNetwareAttrs > 0 then
  318. begin
  319. newmode := ((attr shl 16) and $ffff0000) or M_A_BITS_SIGNIFICANT;
  320. end else
  321. begin
  322. attr := (attr and $2f) shl 16;
  323. newmode := StatBuf.st_mode and ($ffff0000-M_A_RDONLY-M_A_HIDDEN- M_A_SYSTEM-M_A_SUBDIR-M_A_ARCH);
  324. newmode := newmode or (attr shl 16) or M_A_BITS_SIGNIFICANT;
  325. end;
  326. if Fpchmod (pchar(Filename),newMode) < 0 then
  327. result := ___errno^ else
  328. result := 0;
  329. end else
  330. result := ___errno^;
  331. end;
  332. Function DeleteFile (Const FileName : String) : Boolean;
  333. begin
  334. Result:= (libc.UnLink (pchar(FileName)) = 0);
  335. end;
  336. Function RenameFile (Const OldName, NewName : String) : Boolean;
  337. begin
  338. RenameFile:=(libc.rename(pchar(OldName),pchar(NewName)) = 0);
  339. end;
  340. {****************************************************************************
  341. Disk Functions
  342. ****************************************************************************}
  343. {
  344. The Diskfree and Disksize functions need a file on the specified drive, since this
  345. is required for the statfs system call.
  346. These filenames are set in drivestr[0..26], and have been preset to :
  347. 0 - '.' (default drive - hence current dir is ok.)
  348. 1 - '/fd0/.' (floppy drive 1 - should be adapted to local system )
  349. 2 - '/fd1/.' (floppy drive 2 - should be adapted to local system )
  350. 3 - '/' (C: equivalent of dos is the root partition)
  351. 4..26 (can be set by you're own applications)
  352. ! Use AddDisk() to Add new drives !
  353. They both return -1 when a failure occurs.
  354. }
  355. Const
  356. FixDriveStr : array[0..3] of pchar=(
  357. '.',
  358. 'a:.',
  359. 'b:.',
  360. 'sys:/'
  361. );
  362. var
  363. Drives : byte;
  364. DriveStr : array[4..26] of pchar;
  365. Procedure AddDisk(const path:string);
  366. begin
  367. if not (DriveStr[Drives]=nil) then
  368. FreeMem(DriveStr[Drives],StrLen(DriveStr[Drives])+1);
  369. GetMem(DriveStr[Drives],length(Path)+1);
  370. StrPCopy(DriveStr[Drives],path);
  371. inc(Drives);
  372. if Drives>26 then
  373. Drives:=4;
  374. end;
  375. Function DiskFree(Drive: Byte): int64;
  376. //var fs : Tstatfs;
  377. Begin
  378. { if ((Drive<4) and (not (fixdrivestr[Drive]=nil)) and fsstat(StrPas(fixdrivestr[drive]),fs)) or
  379. ((not (drivestr[Drive]=nil)) and fsstat(StrPas(drivestr[drive]),fs)) then
  380. Diskfree:=int64(fs.bavail)*int64(fs.bsize)
  381. else
  382. Diskfree:=-1;}
  383. DiskFree := -1;
  384. ConsolePrintf ('warning: fpc sysutils.diskfree not implemented'#13#10);
  385. {$warning DiskFree not implemented (does it make sense ?) }
  386. End;
  387. Function DiskSize(Drive: Byte): int64;
  388. //var fs : statfs;
  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. DiskSize:=int64(fs.blocks)*int64(fs.bsize)
  393. else
  394. DiskSize:=-1;}
  395. DiskSize := -1;
  396. __ConsolePrintf ('warning: fpc sysutils.disksize not implemented'#13#10);
  397. {$warning DiskSize not implemented (does it make sense ?) }
  398. End;
  399. Function GetCurrentDir : String;
  400. begin
  401. GetDir (0,Result);
  402. end;
  403. Function SetCurrentDir (Const NewDir : String) : Boolean;
  404. begin
  405. Libc.FpChDir(pchar(NewDir));
  406. result := (___errno^ = 0);
  407. end;
  408. Function CreateDir (Const NewDir : String) : Boolean;
  409. begin
  410. Libc.FpMkDir(pchar(NewDir),0);
  411. result := (___errno^ = 0);
  412. end;
  413. Function RemoveDir (Const Dir : String) : Boolean;
  414. begin
  415. libc.FpRmDir(pchar(Dir));
  416. result := (___errno^ = 0);
  417. end;
  418. function DirectoryExists (const Directory: string): boolean;
  419. var Info : TStat;
  420. begin
  421. If Fpstat (pchar(Directory),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 Beep;
  430. begin
  431. RingBell;
  432. end;
  433. {****************************************************************************
  434. Locale Functions
  435. ****************************************************************************}
  436. Procedure GetLocalTime(var SystemTime: TSystemTime);
  437. var xx : word;
  438. begin
  439. Dos.GetTime(SystemTime.Hour, SystemTime.Minute, SystemTime.Second, xx);
  440. Dos.GetDate(SystemTime.Year, SystemTime.Month, SystemTime.Day, xx);
  441. SystemTime.MilliSecond := 0;
  442. end;
  443. Procedure InitAnsi;
  444. Var i : longint;
  445. begin
  446. { Fill table entries 0 to 127 }
  447. for i := 0 to 96 do
  448. UpperCaseTable[i] := chr(i);
  449. for i := 97 to 122 do
  450. UpperCaseTable[i] := chr(i - 32);
  451. for i := 123 to 191 do
  452. UpperCaseTable[i] := chr(i);
  453. Move (CPISO88591UCT,UpperCaseTable[192],SizeOf(CPISO88591UCT));
  454. for i := 0 to 64 do
  455. LowerCaseTable[i] := chr(i);
  456. for i := 65 to 90 do
  457. LowerCaseTable[i] := chr(i + 32);
  458. for i := 91 to 191 do
  459. LowerCaseTable[i] := chr(i);
  460. Move (CPISO88591LCT,UpperCaseTable[192],SizeOf(CPISO88591UCT));
  461. end;
  462. Procedure InitInternational;
  463. begin
  464. InitAnsi;
  465. end;
  466. function SysErrorMessage(ErrorCode: Integer): String;
  467. begin
  468. Result:=''; // only found perror that prints the message
  469. end;
  470. {****************************************************************************
  471. OS utility functions
  472. ****************************************************************************}
  473. Function GetEnvironmentVariable(Const EnvVar : String) : String;
  474. begin
  475. Result:=StrPas(libc.getenv(PChar(EnvVar)));
  476. end;
  477. function ExecuteProcess(Const Path: AnsiString; Const ComLine: AnsiString):integer;
  478. var
  479. e : EOSError;
  480. CommandLine: AnsiString;
  481. begin
  482. dos.exec(path,comline);
  483. if (Dos.DosError <> 0) then
  484. begin
  485. if ComLine <> '' then
  486. CommandLine := Path + ' ' + ComLine
  487. else
  488. CommandLine := Path;
  489. e:=EOSError.CreateFmt(SExecuteProcessFailed,[CommandLine,Dos.DosError]);
  490. e.ErrorCode:=Dos.DosError;
  491. raise e;
  492. end;
  493. Result := DosExitCode;
  494. end;
  495. function ExecuteProcess (const Path: AnsiString;
  496. const ComLine: array of AnsiString): integer;
  497. var
  498. CommandLine: AnsiString;
  499. I: integer;
  500. begin
  501. Commandline := '';
  502. for I := 0 to High (ComLine) do
  503. if Pos (' ', ComLine [I]) <> 0 then
  504. CommandLine := CommandLine + ' ' + '"' + ComLine [I] + '"'
  505. else
  506. CommandLine := CommandLine + ' ' + Comline [I];
  507. ExecuteProcess := ExecuteProcess (Path, CommandLine);
  508. end;
  509. {****************************************************************************
  510. Initialization code
  511. ****************************************************************************}
  512. Initialization
  513. InitExceptions; { Initialize exceptions. OS independent }
  514. InitInternational; { Initialize internationalization settings }
  515. Finalization
  516. DoneExceptions;
  517. end.
  518. {
  519. $Log$
  520. Revision 1.4 2004-09-26 19:23:34 armin
  521. * exiting threads at nlm unload
  522. * renamed some libc functions
  523. Revision 1.3 2004/09/19 20:06:37 armin
  524. * removed get/free video buf from video.pp
  525. * implemented sockets
  526. * basic library support
  527. * threadvar memory leak removed
  528. * fixes (ide now starts and editor is usable)
  529. * support for lineinfo
  530. Revision 1.2 2004/09/12 20:51:22 armin
  531. * added keyboard and video
  532. * a lot of fixes
  533. Revision 1.1 2004/09/05 20:58:47 armin
  534. * first rtl version for netwlibc
  535. }