sysutils.pp 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817
  1. {
  2. $Id$
  3. This file is part of the Free Pascal run time library.
  4. Copyright (c) 1999-2000 by Florian Klaempfl
  5. member of the Free Pascal development team
  6. Sysutils unit for OS/2
  7. See the file COPYING.FPC, included in this distribution,
  8. for details about the copyright.
  9. This program is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  12. **********************************************************************}
  13. unit sysutils;
  14. interface
  15. {$MODE objfpc}
  16. { force ansistrings }
  17. {$H+}
  18. uses
  19. doscalls,dos;
  20. { Include platform independent interface part }
  21. {$i sysutilh.inc}
  22. implementation
  23. { Include platform independent implementation part }
  24. {$i sysutils.inc}
  25. {****************************************************************************
  26. File Functions
  27. ****************************************************************************}
  28. {This is the correct way to call external assembler procedures.}
  29. procedure syscall;external name '___SYSCALL';
  30. const
  31. ofRead = $0000; {Open for reading}
  32. ofWrite = $0001; {Open for writing}
  33. ofReadWrite = $0002; {Open for reading/writing}
  34. doDenyRW = $0010; {DenyAll (no sharing)}
  35. faCreateNew = $00010000; {Create if file does not exist}
  36. faOpenReplace = $00040000; {Truncate if file exists}
  37. faCreate = $00050000; {Create if file does not exist, truncate otherwise}
  38. {$ASMMODE INTEL}
  39. function FileOpen (const FileName: string; Mode: integer): longint;
  40. {$IFOPT H+}
  41. assembler;
  42. {$ELSE}
  43. var FN: string;
  44. begin
  45. FN := FileName + #0;
  46. {$ENDIF}
  47. asm
  48. mov eax, Mode
  49. (* DenyAll if sharing not specified. *)
  50. test eax, 112
  51. jnz @FOpen1
  52. or eax, 16
  53. @FOpen1:
  54. mov ecx, eax
  55. mov eax, 7F2Bh
  56. {$IFOPT H+}
  57. mov edx, FileName
  58. {$ELSE}
  59. lea edx, FN
  60. inc edx
  61. {$ENDIF}
  62. call syscall
  63. {$IFOPT H-}
  64. mov [ebp - 4], eax
  65. end;
  66. {$ENDIF}
  67. end;
  68. function FileCreate (const FileName: string): longint;
  69. {$IFOPT H+}
  70. assembler;
  71. {$ELSE}
  72. var FN: string;
  73. begin
  74. FN := FileName + #0;
  75. {$ENDIF}
  76. asm
  77. mov eax, 7F2Bh
  78. mov ecx, ofReadWrite or faCreate or doDenyRW (* Sharing to DenyAll *)
  79. {$IFOPT H+}
  80. mov edx, FileName
  81. {$ELSE}
  82. lea edx, FN
  83. inc edx
  84. {$ENDIF}
  85. call syscall
  86. {$IFOPT H-}
  87. mov [ebp - 4], eax
  88. end;
  89. {$ENDIF}
  90. end;
  91. function FileRead (Handle: longint; var Buffer; Count: longint): longint;
  92. assembler;
  93. asm
  94. mov eax, 3F00h
  95. mov ebx, Handle
  96. mov ecx, Count
  97. mov edx, Buffer
  98. call syscall
  99. jnc @FReadEnd
  100. mov eax, -1
  101. @FReadEnd:
  102. end;
  103. function FileWrite (Handle: longint; const Buffer; Count: longint): longint;
  104. assembler;
  105. asm
  106. mov eax, 4000h
  107. mov ebx, Handle
  108. mov ecx, Count
  109. mov edx, Buffer
  110. call syscall
  111. jnc @FWriteEnd
  112. mov eax, -1
  113. @FWriteEnd:
  114. end;
  115. function FileSeek (Handle, FOffset, Origin: longint): longint; assembler;
  116. asm
  117. mov eax, Origin
  118. mov ah, 42h
  119. mov ebx, Handle
  120. mov edx, FOffset
  121. call syscall
  122. jnc @FSeekEnd
  123. mov eax, -1
  124. @FSeekEnd:
  125. end;
  126. procedure FileClose (Handle: longint);
  127. begin
  128. if (Handle <= 4) or (os_mode = osOS2) and (Handle <= 2) then
  129. asm
  130. mov eax, 3E00h
  131. mov ebx, Handle
  132. call syscall
  133. end;
  134. end;
  135. function FileTruncate (Handle, Size: longint): boolean; assembler;
  136. asm
  137. mov eax, 7F25h
  138. mov ebx, Handle
  139. mov edx, Size
  140. call syscall
  141. jc @FTruncEnd
  142. mov eax, 4202h
  143. mov ebx, Handle
  144. mov edx, 0
  145. call syscall
  146. mov eax, 0
  147. jnc @FTruncEnd
  148. dec eax
  149. @FTruncEnd:
  150. end;
  151. function FileAge (const FileName: string): longint;
  152. var Handle: longint;
  153. begin
  154. Handle := FileOpen (FileName, 0);
  155. if Handle <> -1 then
  156. begin
  157. Result := FileGetDate (Handle);
  158. FileClose (Handle);
  159. end
  160. else
  161. Result := -1;
  162. end;
  163. function FileExists (const FileName: string): boolean;
  164. {$IFOPT H+}
  165. assembler;
  166. {$ELSE}
  167. var FN: string;
  168. begin
  169. FN := FileName + #0;
  170. {$ENDIF}
  171. asm
  172. mov ax, 4300h
  173. {$IFOPT H+}
  174. mov edx, FileName
  175. {$ELSE}
  176. lea edx, FN
  177. inc edx
  178. {$ENDIF}
  179. call syscall
  180. mov eax, 0
  181. jc @FExistsEnd
  182. test cx, 18h
  183. jnz @FExistsEnd
  184. inc eax
  185. @FExistsEnd:
  186. {$IFOPT H-}
  187. end;
  188. {$ENDIF}
  189. end;
  190. type TRec = record
  191. T, D: word;
  192. end;
  193. PSearchRec = ^SearchRec;
  194. function FindFirst (const Path: string; Attr: longint; var Rslt: TSearchRec): longint;
  195. var SR: PSearchRec;
  196. FStat: PFileFindBuf3;
  197. Count: longint;
  198. Err: longint;
  199. begin
  200. if os_mode = osOS2 then
  201. begin
  202. New (FStat);
  203. Rslt.FindHandle := $FFFFFFFF;
  204. Count := 1;
  205. Err := DosFindFirst (Path, Rslt.FindHandle, Attr, FStat,
  206. SizeOf (FStat^), Count, ilStandard);
  207. if (Err = 0) and (Count = 0) then Err := 18;
  208. FindFirst := -Err;
  209. if Err = 0 then
  210. begin
  211. Rslt.Name := FStat^.Name;
  212. Rslt.Size := FStat^.FileSize;
  213. Rslt.Attr := FStat^.AttrFile;
  214. Rslt.ExcludeAttr := 0;
  215. TRec (Rslt.Time).T := FStat^.TimeLastWrite;
  216. TRec (Rslt.Time).D := FStat^.DateLastWrite;
  217. end;
  218. Dispose (FStat);
  219. end
  220. else
  221. begin
  222. GetMem (SR, SizeOf (SearchRec));
  223. Rslt.FindHandle := longint(SR);
  224. DOS.FindFirst (Path, Attr, SR^);
  225. FindFirst := -DosError;
  226. if DosError = 0 then
  227. begin
  228. Rslt.Time := SR^.Time;
  229. Rslt.Size := SR^.Size;
  230. Rslt.Attr := SR^.Attr;
  231. Rslt.ExcludeAttr := 0;
  232. Rslt.Name := SR^.Name;
  233. end;
  234. end;
  235. end;
  236. function FindNext (var Rslt: TSearchRec): longint;
  237. var SR: PSearchRec;
  238. FStat: PFileFindBuf3;
  239. Count: longint;
  240. Err: longint;
  241. begin
  242. if os_mode = osOS2 then
  243. begin
  244. New (FStat);
  245. Count := 1;
  246. Err := DosFindNext (Rslt.FindHandle, FStat, SizeOf (FStat), Count);
  247. if (Err = 0) and (Count = 0) then Err := 18;
  248. FindNext := -Err;
  249. if Err = 0 then
  250. begin
  251. Rslt.Name := FStat^.Name;
  252. Rslt.Size := FStat^.FileSize;
  253. Rslt.Attr := FStat^.AttrFile;
  254. Rslt.ExcludeAttr := 0;
  255. TRec (Rslt.Time).T := FStat^.TimeLastWrite;
  256. TRec (Rslt.Time).D := FStat^.DateLastWrite;
  257. end;
  258. Dispose (FStat);
  259. end
  260. else
  261. begin
  262. SR := PSearchRec (Rslt.FindHandle);
  263. if SR <> nil then
  264. begin
  265. DOS.FindNext (SR^);
  266. FindNext := -DosError;
  267. if DosError = 0 then
  268. begin
  269. Rslt.Time := SR^.Time;
  270. Rslt.Size := SR^.Size;
  271. Rslt.Attr := SR^.Attr;
  272. Rslt.ExcludeAttr := 0;
  273. Rslt.Name := SR^.Name;
  274. end;
  275. end;
  276. end;
  277. end;
  278. procedure FindClose (var F: TSearchrec);
  279. var SR: PSearchRec;
  280. begin
  281. if os_mode = osOS2 then
  282. begin
  283. DosFindClose (F.FindHandle);
  284. end
  285. else
  286. begin
  287. SR := PSearchRec (F.FindHandle);
  288. DOS.FindClose (SR^);
  289. FreeMem (SR, SizeOf (SearchRec));
  290. end;
  291. F.FindHandle := 0;
  292. end;
  293. function FileGetDate (Handle: longint): longint; assembler;
  294. asm
  295. mov ax, 5700h
  296. mov ebx, Handle
  297. call syscall
  298. mov eax, -1
  299. jc @FGetDateEnd
  300. mov ax, dx
  301. shld eax, ecx, 16
  302. @FGetDateEnd:
  303. end;
  304. function FileSetDate (Handle, Age: longint): longint;
  305. var FStat: PFileStatus0;
  306. RC: longint;
  307. begin
  308. if os_mode = osOS2 then
  309. begin
  310. New (FStat);
  311. RC := DosQueryFileInfo (Handle, ilStandard, FStat,
  312. SizeOf (FStat^));
  313. if RC <> 0 then
  314. FileSetDate := -1
  315. else
  316. begin
  317. FStat^.DateLastAccess := Hi (Age);
  318. FStat^.DateLastWrite := Hi (Age);
  319. FStat^.TimeLastAccess := Lo (Age);
  320. FStat^.TimeLastWrite := Lo (Age);
  321. RC := DosSetFileInfo (Handle, ilStandard, FStat,
  322. SizeOf (FStat^));
  323. if RC <> 0 then
  324. FileSetDate := -1
  325. else
  326. FileSetDate := 0;
  327. end;
  328. Dispose (FStat);
  329. end
  330. else
  331. asm
  332. mov ax, 5701h
  333. mov ebx, Handle
  334. mov cx, word ptr [Age]
  335. mov dx, word ptr [Age + 2]
  336. call syscall
  337. jnc @FSetDateEnd
  338. mov eax, -1
  339. @FSetDateEnd:
  340. mov [ebp - 4], eax
  341. end;
  342. end;
  343. function FileGetAttr (const FileName: string): longint;
  344. {$IFOPT H+}
  345. assembler;
  346. {$ELSE}
  347. var FN: string;
  348. begin
  349. FN := FileName + #0;
  350. {$ENDIF}
  351. asm
  352. mov ax, 4300h
  353. {$IFOPT H+}
  354. mov edx, FileName
  355. {$ELSE}
  356. lea edx, FN
  357. inc edx
  358. {$ENDIF}
  359. call syscall
  360. jnc @FGetAttrEnd
  361. mov eax, -1
  362. @FGetAttrEnd:
  363. {$IFOPT H-}
  364. mov [ebp - 4], eax
  365. end;
  366. {$ENDIF}
  367. end;
  368. function FileSetAttr (const Filename: string; Attr: longint): longint;
  369. {$IFOPT H+}
  370. assembler;
  371. {$ELSE}
  372. var FN: string;
  373. begin
  374. FN := FileName + #0;
  375. {$ENDIF}
  376. asm
  377. mov ax, 4301h
  378. mov ecx, Attr
  379. {$IFOPT H+}
  380. mov edx, FileName
  381. {$ELSE}
  382. lea edx, FN
  383. inc edx
  384. {$ENDIF}
  385. call syscall
  386. mov eax, 0
  387. jnc @FSetAttrEnd
  388. mov eax, -1
  389. @FSetAttrEnd:
  390. {$IFOPT H-}
  391. mov [ebp - 4], eax
  392. end;
  393. {$ENDIF}
  394. end;
  395. function DeleteFile (const FileName: string): boolean;
  396. {$IFOPT H+}
  397. assembler;
  398. {$ELSE}
  399. var FN: string;
  400. begin
  401. FN := FileName + #0;
  402. {$ENDIF}
  403. asm
  404. mov ax, 4100h
  405. {$IFOPT H+}
  406. mov edx, FileName
  407. {$ELSE}
  408. lea edx, FN
  409. inc edx
  410. {$ENDIF}
  411. call syscall
  412. mov eax, 0
  413. jc @FDeleteEnd
  414. inc eax
  415. @FDeleteEnd:
  416. {$IFOPT H-}
  417. mov [ebp - 4], eax
  418. end;
  419. {$ENDIF}
  420. end;
  421. function RenameFile (const OldName, NewName: string): boolean;
  422. {$IFOPT H+}
  423. assembler;
  424. {$ELSE}
  425. var FN1, FN2: string;
  426. begin
  427. FN1 := OldName + #0;
  428. FN2 := NewName + #0;
  429. {$ENDIF}
  430. asm
  431. mov ax, 5600h
  432. {$IFOPT H+}
  433. mov edx, OldName
  434. mov edi, NewName
  435. {$ELSE}
  436. lea edx, FN1
  437. inc edx
  438. lea edi, FN2
  439. inc edi
  440. {$ENDIF}
  441. call syscall
  442. mov eax, 0
  443. jc @FRenameEnd
  444. inc eax
  445. @FRenameEnd:
  446. {$IFOPT H-}
  447. mov [ebp - 4], eax
  448. end;
  449. {$ENDIF}
  450. end;
  451. function FileSearch (const Name, DirList: string): string;
  452. begin
  453. Result := Dos.FSearch (Name, DirList);
  454. end;
  455. {****************************************************************************
  456. Disk Functions
  457. ****************************************************************************}
  458. {$ASMMODE ATT}
  459. function DiskFree (Drive: byte): int64;
  460. var FI: TFSinfo;
  461. RC: longint;
  462. begin
  463. if (os_mode = osDOS) or (os_mode = osDPMI) then
  464. {Function 36 is not supported in OS/2.}
  465. asm
  466. movb Drive,%dl
  467. movb $0x36,%ah
  468. call syscall
  469. cmpw $-1,%ax
  470. je .LDISKFREE1
  471. mulw %cx
  472. mulw %bx
  473. shll $16,%edx
  474. movw %ax,%dx
  475. movl $0,%eax
  476. xchgl %edx,%eax
  477. leave
  478. ret
  479. .LDISKFREE1:
  480. cltd
  481. leave
  482. ret
  483. end
  484. else
  485. {In OS/2, we use the filesystem information.}
  486. begin
  487. RC := DosQueryFSInfo (Drive, 1, FI, SizeOf (FI));
  488. if RC = 0 then
  489. DiskFree := int64 (FI.Free_Clusters) *
  490. int64 (FI.Sectors_Per_Cluster) * int64 (FI.Bytes_Per_Sector)
  491. else
  492. DiskFree := -1;
  493. end;
  494. end;
  495. function DiskSize (Drive: byte): int64;
  496. var FI: TFSinfo;
  497. RC: longint;
  498. begin
  499. if (os_mode = osDOS) or (os_mode = osDPMI) then
  500. {Function 36 is not supported in OS/2.}
  501. asm
  502. movb Drive,%dl
  503. movb $0x36,%ah
  504. call syscall
  505. movw %dx,%bx
  506. cmpw $-1,%ax
  507. je .LDISKSIZE1
  508. mulw %cx
  509. mulw %bx
  510. shll $16,%edx
  511. movw %ax,%dx
  512. movl $0,%eax
  513. xchgl %edx,%eax
  514. leave
  515. ret
  516. .LDISKSIZE1:
  517. cltd
  518. leave
  519. ret
  520. end
  521. else
  522. {In OS/2, we use the filesystem information.}
  523. begin
  524. RC := DosQueryFSinfo (Drive, 1, FI, SizeOf (FI));
  525. if RC = 0 then
  526. DiskSize := int64 (FI.Total_Clusters) *
  527. int64 (FI.Sectors_Per_Cluster) * int64 (FI.Bytes_Per_Sector)
  528. else
  529. DiskSize := -1;
  530. end;
  531. end;
  532. function GetCurrentDir: string;
  533. begin
  534. GetDir (0, Result);
  535. end;
  536. function SetCurrentDir (const NewDir: string): boolean;
  537. begin
  538. {$I-}
  539. ChDir (NewDir);
  540. Result := (IOResult = 0);
  541. {$I+}
  542. end;
  543. function CreateDir (const NewDir: string): boolean;
  544. begin
  545. {$I-}
  546. MkDir (NewDir);
  547. Result := (IOResult = 0);
  548. {$I+}
  549. end;
  550. function RemoveDir (const Dir: string): boolean;
  551. begin
  552. {$I-}
  553. RmDir (Dir);
  554. Result := (IOResult = 0);
  555. {$I+}
  556. end;
  557. {****************************************************************************
  558. Time Functions
  559. ****************************************************************************}
  560. {$asmmode intel}
  561. procedure GetLocalTime (var SystemTime: TSystemTime); assembler;
  562. asm
  563. (* Expects the default record alignment (word)!!! *)
  564. mov ah, 2Ah
  565. call syscall
  566. mov edi, SystemTime
  567. mov ax, cx
  568. stosw
  569. xor eax, eax
  570. mov al, dl
  571. shl eax, 16
  572. mov al, dh
  573. stosd
  574. push edi
  575. mov ah, 2Ch
  576. call syscall
  577. pop edi
  578. xor eax, eax
  579. mov al, cl
  580. shl eax, 16
  581. mov al, ch
  582. stosd
  583. mov al, dl
  584. shl eax, 16
  585. mov al, dh
  586. stosd
  587. end;
  588. {$asmmode default}
  589. {****************************************************************************
  590. Misc Functions
  591. ****************************************************************************}
  592. procedure Beep;
  593. begin
  594. end;
  595. {****************************************************************************
  596. Locale Functions
  597. ****************************************************************************}
  598. procedure InitAnsi;
  599. var I: byte;
  600. Country: TCountryCode;
  601. begin
  602. for I := 0 to 255 do
  603. UpperCaseTable [I] := Chr (I);
  604. Move (UpperCaseTable, LowerCaseTable, SizeOf (UpperCaseTable));
  605. if os_mode = osOS2 then
  606. begin
  607. FillChar (Country, SizeOf (Country), 0);
  608. DosMapCase (SizeOf (UpperCaseTable), Country, @UpperCaseTable);
  609. end
  610. else
  611. begin
  612. (* !!! TODO: DOS/DPMI mode support!!! *)
  613. end;
  614. for I := 0 to 255 do
  615. if UpperCaseTable [I] <> Chr (I) then
  616. LowerCaseTable [Ord (UpperCaseTable [I])] := Chr (I);
  617. end;
  618. procedure InitInternational;
  619. var Country: TCountryCode;
  620. CtryInfo: TCountryInfo;
  621. Size: longint;
  622. RC: longint;
  623. begin
  624. Size := 0;
  625. FillChar (Country, SizeOf (Country), 0);
  626. FillChar (CtryInfo, SizeOf (CtryInfo), 0);
  627. RC := DosQueryCtryInfo (SizeOf (CtryInfo), Country, CtryInfo, Size);
  628. if RC = 0 then
  629. begin
  630. DateSeparator := CtryInfo.DateSeparator;
  631. case CtryInfo.DateFormat of
  632. 1: begin
  633. ShortDateFormat := 'd/m/y';
  634. LongDateFormat := 'dd" "mmmm" "yyyy';
  635. end;
  636. 2: begin
  637. ShortDateFormat := 'y/m/d';
  638. LongDateFormat := 'yyyy" "mmmm" "dd';
  639. end;
  640. 3: begin
  641. ShortDateFormat := 'm/d/y';
  642. LongDateFormat := 'mmmm" "dd" "yyyy';
  643. end;
  644. end;
  645. TimeSeparator := CtryInfo.TimeSeparator;
  646. DecimalSeparator := CtryInfo.DecimalSeparator;
  647. ThousandSeparator := CtryInfo.ThousandSeparator;
  648. CurrencyFormat := CtryInfo.CurrencyFormat;
  649. CurrencyString := PChar (CtryInfo.CurrencyUnit);
  650. end;
  651. InitAnsi;
  652. end;
  653. function SysErrorMessage(ErrorCode: Integer): String;
  654. begin
  655. Result:=Format(SUnknownErrorCode,[ErrorCode]);
  656. end;
  657. {****************************************************************************
  658. OS Utils
  659. ****************************************************************************}
  660. Function GetEnvironmentVariable(Const EnvVar : String) : String;
  661. var P: PChar;
  662. begin
  663. if DosScanEnv (PChar (EnvVar), P) = 0
  664. then GetEnvironmentVariable := StrPas (P)
  665. else GetEnvironmentVariable := '';
  666. end;
  667. {****************************************************************************
  668. Initialization code
  669. ****************************************************************************}
  670. Initialization
  671. InitExceptions; { Initialize exceptions. OS independent }
  672. InitInternational; { Initialize internationalization settings }
  673. Finalization
  674. OutOfMemory.Free;
  675. InValidPointer.Free;
  676. end.
  677. {
  678. $Log$
  679. Revision 1.11 2001-05-21 20:50:19 hajny
  680. * silly mistyping corrected
  681. Revision 1.10 2001/05/20 18:40:33 hajny
  682. * merging Carl's fixes from the fixes branch
  683. Revision 1.9 2001/02/21 21:23:38 hajny
  684. * GetEnvironmentVariable now really merged
  685. Revision 1.8 2001/02/20 22:14:19 peter
  686. * merged getenvironmentvariable
  687. Revision 1.7 2001/01/13 11:10:59 hajny
  688. * FileCreate and GetLocalTime fixed
  689. Revision 1.6 2000/10/15 20:44:18 hajny
  690. * FindClose correction
  691. Revision 1.5 2000/09/29 21:49:41 jonas
  692. * removed warnings
  693. Revision 1.4 2000/08/30 06:30:55 michael
  694. + Merged syserrormsg fix
  695. Revision 1.3 2000/08/25 17:23:56 hajny
  696. * Sharing mode error fixed
  697. Revision 1.2 2000/08/20 15:46:46 peter
  698. * sysutils.pp moved to target and merged with disk.inc, filutil.inc
  699. Revision 1.1.2.3 2000/08/25 17:20:57 hajny
  700. * Sharing mode error fixed
  701. Revision 1.1.2.2 2000/08/22 19:21:48 michael
  702. + Implemented syserrormessage. Made dummies for go32v2 and OS/2
  703. * Changed linux/errors.pp so it uses pchars for storage.
  704. Revision 1.1.2.1 2000/08/20 15:08:32 peter
  705. * forgot the add command :(
  706. }