sysutils.pp 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587
  1. {
  2. This file is part of the Free Pascal run time library.
  3. Copyright (c) 2004 by Karoly Balogh
  4. Sysutils unit for MorphOS
  5. Based on Amiga version by Carl Eric Codere, and other
  6. parts of the RTL
  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. { Include platform independent interface part }
  19. {$i sysutilh.inc}
  20. { Platform dependent calls }
  21. Procedure AddDisk(const path:string);
  22. implementation
  23. uses dos,sysconst;
  24. {$DEFINE FPC_FEXPAND_VOLUMES} (* Full paths begin with drive specification *)
  25. {$DEFINE FPC_FEXPAND_DRIVESEP_IS_ROOT}
  26. {$DEFINE FPC_FEXPAND_NO_DEFAULT_PATHS}
  27. { Include platform independent implementation part }
  28. {$i sysutils.inc}
  29. { * Include MorphOS specific includes * }
  30. {$include execd.inc}
  31. {$include execf.inc}
  32. {$include timerd.inc}
  33. {$include doslibd.inc}
  34. {$include doslibf.inc}
  35. {$include utilf.inc}
  36. { * Followings are implemented in the system unit! * }
  37. function PathConv(path: shortstring): shortstring; external name 'PATHCONV';
  38. procedure AddToList(var l: Pointer; h: LongInt); external name 'ADDTOLIST';
  39. function RemoveFromList(var l: Pointer; h: LongInt): boolean; external name 'REMOVEFROMLIST';
  40. function CheckInList(var l: Pointer; h: LongInt): pointer; external name 'CHECKINLIST';
  41. var
  42. MOS_fileList: Pointer; external name 'MOS_FILELIST';
  43. {****************************************************************************
  44. File Functions
  45. ****************************************************************************}
  46. {$I-}{ Required for correct usage of these routines }
  47. (****** non portable routines ******)
  48. function FileOpen(const FileName: string; Mode: Integer): LongInt;
  49. var
  50. dosResult: LongInt;
  51. tmpStr : array[0..255] of char;
  52. begin
  53. {$WARNING FIX ME! To do: FileOpen Access Modes}
  54. tmpStr:=PathConv(FileName)+#0;
  55. dosResult:=Open(@tmpStr,MODE_OLDFILE);
  56. if dosResult=0 then
  57. dosResult:=-1
  58. else
  59. AddToList(MOS_fileList,dosResult);
  60. FileOpen:=dosResult;
  61. end;
  62. function FileGetDate(Handle: LongInt) : LongInt;
  63. begin
  64. end;
  65. function FileSetDate(Handle, Age: LongInt) : LongInt;
  66. begin
  67. // Impossible under unix from FileHandle !!
  68. FileSetDate:=-1;
  69. end;
  70. function FileCreate(const FileName: string) : LongInt;
  71. var
  72. dosResult: LongInt;
  73. tmpStr : array[0..255] of char;
  74. begin
  75. tmpStr:=PathConv(FileName)+#0;
  76. dosResult:=Open(@tmpStr,MODE_NEWFILE);
  77. if dosResult=0 then
  78. dosResult:=-1
  79. else
  80. AddToList(MOS_fileList,dosResult);
  81. FileCreate:=dosResult;
  82. end;
  83. function FileCreate(const FileName: string; Mode: integer): LongInt;
  84. begin
  85. {$WARNING FIX ME! To do: FileCreate Access Modes}
  86. FileCreate:=FileCreate(FileName);
  87. end;
  88. function FileRead(Handle: LongInt; var Buffer; Count: LongInt): LongInt;
  89. begin
  90. FileRead:=-1;
  91. if (Count<=0) or (Handle<=0) then exit;
  92. FileRead:=dosRead(Handle,@Buffer,Count);
  93. end;
  94. function FileWrite(Handle: LongInt; const Buffer; Count: LongInt): LongInt;
  95. begin
  96. FileWrite:=-1;
  97. if (Count<=0) or (Handle<=0) then exit;
  98. FileWrite:=dosWrite(Handle,@Buffer,Count);
  99. end;
  100. function FileSeek(Handle, FOffset, Origin: LongInt) : LongInt;
  101. var
  102. seekMode: LongInt;
  103. begin
  104. FileSeek:=-1;
  105. if (Handle<=0) then exit;
  106. case Origin of
  107. fsFromBeginning: seekMode:=OFFSET_BEGINNING;
  108. fsFromCurrent : seekMode:=OFFSET_CURRENT;
  109. fsFromEnd : seekMode:=OFFSET_END;
  110. end;
  111. FileSeek:=dosSeek(Handle, FOffset, seekMode);
  112. end;
  113. function FileSeek(Handle: LongInt; FOffset: Int64; Origin: Longint): Int64;
  114. begin
  115. {$WARNING Need to add 64bit call }
  116. FileSeek:=FileSeek(Handle,LongInt(FOffset),LongInt(Origin));
  117. end;
  118. procedure FileClose(Handle: LongInt);
  119. begin
  120. if (Handle<=0) then exit;
  121. dosClose(Handle);
  122. RemoveFromList(MOS_fileList,Handle);
  123. end;
  124. function FileTruncate(Handle, Size: LongInt): Boolean;
  125. var
  126. dosResult: LongInt;
  127. begin
  128. FileTruncate:=False;
  129. if (Handle<=0) then exit;
  130. dosResult:=SetFileSize(Handle, Size, OFFSET_BEGINNING);
  131. if (dosResult<0) then exit;
  132. FileTruncate:=True;
  133. end;
  134. function DeleteFile(const FileName: string) : Boolean;
  135. var
  136. tmpStr: array[0..255] of char;
  137. begin
  138. tmpStr:=PathConv(FileName)+#0;
  139. DeleteFile:=dosDeleteFile(@tmpStr);
  140. end;
  141. function RenameFile(const OldName, NewName: string): Boolean;
  142. var
  143. tmpOldName, tmpNewName: array[0..255] of char;
  144. begin
  145. tmpOldName:=PathConv(OldName)+#0;
  146. tmpNewName:=PathConv(NewName)+#0;
  147. RenameFile:=dosRename(tmpOldName, tmpNewName);
  148. end;
  149. (****** end of non portable routines ******)
  150. Function FileAge (Const FileName : String): Longint;
  151. var F: file;
  152. Time: longint;
  153. begin
  154. Assign(F,FileName);
  155. dos.GetFTime(F,Time);
  156. { Warning this is not compatible with standard routines
  157. since Double are not supported on m68k by default!
  158. }
  159. FileAge:=Time;
  160. end;
  161. Function FileExists (Const FileName : String) : Boolean;
  162. Var
  163. F: File;
  164. OldMode : Byte;
  165. Begin
  166. OldMode := FileMode;
  167. FileMode := fmOpenRead;
  168. Assign(F,FileName);
  169. Reset(F,1);
  170. FileMode := OldMode;
  171. If IOResult <> 0 then
  172. FileExists := FALSE
  173. else
  174. Begin
  175. FileExists := TRUE;
  176. Close(F);
  177. end;
  178. end;
  179. type
  180. PDOSSearchRec = ^SearchRec;
  181. Function FindFirst (Const Path : String; Attr : Longint; Out Rslt : TSearchRec) : Longint;
  182. Const
  183. faSpecial = faHidden or faSysFile or faVolumeID or faDirectory;
  184. var
  185. p : pDOSSearchRec;
  186. dosattr: word;
  187. DT: Datetime;
  188. begin
  189. dosattr:=0;
  190. if Attr and faHidden <> 0 then
  191. dosattr := dosattr or Hidden;
  192. if Attr and faSysFile <> 0 then
  193. dosattr := dosattr or SysFile;
  194. if Attr and favolumeID <> 0 then
  195. dosattr := dosattr or VolumeID;
  196. if Attr and faDirectory <> 0 then
  197. dosattr := dosattr or Directory;
  198. New(p);
  199. Rslt.FindHandle := THandle(p);
  200. dos.FindFirst(path,dosattr,p^);
  201. if DosError <> 0 then
  202. begin
  203. FindFirst := -1;
  204. end
  205. else
  206. begin
  207. Rslt.Name := p^.Name;
  208. { Not compatible with other platforms! }
  209. Rslt.Time:=p^.Time;
  210. Rslt.Attr := p^.Attr;
  211. Rslt.ExcludeAttr := not p^.Attr;
  212. Rslt.Size := p^.Size;
  213. FindFirst := 0;
  214. end;
  215. end;
  216. Function FindNext (Var Rslt : TSearchRec) : Longint;
  217. var
  218. p : pDOSSearchRec;
  219. DT: Datetime;
  220. begin
  221. p:= PDOsSearchRec(Rslt.FindHandle);
  222. if not assigned(p) then
  223. begin
  224. FindNext := -1;
  225. exit;
  226. end;
  227. Dos.FindNext(p^);
  228. if DosError <> 0 then
  229. begin
  230. FindNext := -1;
  231. end
  232. else
  233. begin
  234. Rslt.Name := p^.Name;
  235. UnpackTime(p^.Time, DT);
  236. { Warning: Not compatible with other platforms }
  237. Rslt.time := p^.Time;
  238. Rslt.Attr := p^.Attr;
  239. Rslt.ExcludeAttr := not p^.Attr;
  240. Rslt.Size := p^.Size;
  241. FindNext := 0;
  242. end;
  243. end;
  244. Procedure FindClose (Var F : TSearchrec);
  245. Var
  246. p : PDOSSearchRec;
  247. begin
  248. p:=PDOSSearchRec(f.FindHandle);
  249. if not assigned(p) then
  250. exit;
  251. Dos.FindClose(p^);
  252. if assigned(p) then
  253. Dispose(p);
  254. f.FindHandle := THandle(nil);
  255. end;
  256. Function FileGetAttr (Const FileName : String) : Longint;
  257. var
  258. F: file;
  259. attr: word;
  260. begin
  261. Assign(F,FileName);
  262. dos.GetFAttr(F,attr);
  263. if DosError <> 0 then
  264. FileGetAttr := -1
  265. else
  266. FileGetAttr := Attr;
  267. end;
  268. Function FileSetAttr (Const Filename : String; Attr: longint) : Longint;
  269. var
  270. F: file;
  271. begin
  272. Assign(F, FileName);
  273. Dos.SetFAttr(F, Attr and $ffff);
  274. FileSetAttr := DosError;
  275. end;
  276. {****************************************************************************
  277. Disk Functions
  278. ****************************************************************************}
  279. {
  280. The Diskfree and Disksize functions need a file on the specified drive, since this
  281. is required for the statfs system call.
  282. These filenames are set in drivestr[0..26], and have been preset to :
  283. 0 - '.' (default drive - hence current dir is ok.)
  284. 1 - '/fd0/.' (floppy drive 1 - should be adapted to local system )
  285. 2 - '/fd1/.' (floppy drive 2 - should be adapted to local system )
  286. 3 - '/' (C: equivalent of dos is the root partition)
  287. 4..26 (can be set by you're own applications)
  288. ! Use AddDisk() to Add new drives !
  289. They both return -1 when a failure occurs.
  290. }
  291. Const
  292. FixDriveStr : array[0..3] of pchar=(
  293. '.',
  294. '/fd0/.',
  295. '/fd1/.',
  296. '/.'
  297. );
  298. var
  299. Drives : byte;
  300. DriveStr : array[4..26] of pchar;
  301. Procedure AddDisk(const path:string);
  302. begin
  303. if not (DriveStr[Drives]=nil) then
  304. FreeMem(DriveStr[Drives],StrLen(DriveStr[Drives])+1);
  305. GetMem(DriveStr[Drives],length(Path)+1);
  306. StrPCopy(DriveStr[Drives],path);
  307. inc(Drives);
  308. if Drives>26 then
  309. Drives:=4;
  310. end;
  311. Function DiskFree(Drive: Byte): int64;
  312. Begin
  313. DiskFree := dos.diskFree(Drive);
  314. End;
  315. Function DiskSize(Drive: Byte): int64;
  316. Begin
  317. DiskSize := dos.DiskSize(Drive);
  318. End;
  319. Function GetCurrentDir : String;
  320. begin
  321. GetDir (0,Result);
  322. end;
  323. Function SetCurrentDir (Const NewDir : String) : Boolean;
  324. begin
  325. ChDir(NewDir);
  326. result := (IOResult = 0);
  327. end;
  328. Function CreateDir (Const NewDir : String) : Boolean;
  329. begin
  330. MkDir(NewDir);
  331. result := (IOResult = 0);
  332. end;
  333. Function RemoveDir (Const Dir : String) : Boolean;
  334. begin
  335. RmDir(Dir);
  336. result := (IOResult = 0);
  337. end;
  338. function DirectoryExists(const Directory: string): Boolean;
  339. var
  340. tmpStr : array[0..255] of Char;
  341. tmpLock: LongInt;
  342. FIB : PFileInfoBlock;
  343. begin
  344. DirectoryExists:=False;
  345. If (Directory='') or (InOutRes<>0) then exit;
  346. tmpStr:=PathConv(Directory)+#0;
  347. tmpLock:=0;
  348. tmpLock:=Lock(@tmpStr,SHARED_LOCK);
  349. if tmpLock=0 then exit;
  350. FIB:=nil; new(FIB);
  351. if (Examine(tmpLock,FIB)=True) and (FIB^.fib_DirEntryType>0) then begin
  352. DirectoryExists:=True;
  353. end;
  354. if tmpLock<>0 then Unlock(tmpLock);
  355. if assigned(FIB) then dispose(FIB);
  356. end;
  357. {****************************************************************************
  358. Misc Functions
  359. ****************************************************************************}
  360. procedure Beep;
  361. begin
  362. end;
  363. {****************************************************************************
  364. Locale Functions
  365. ****************************************************************************}
  366. Procedure GetLocalTime(var SystemTime: TSystemTime);
  367. var
  368. dayOfWeek: word;
  369. begin
  370. dos.GetTime(SystemTime.Hour, SystemTime.Minute, SystemTime.Second,SystemTime.Millisecond);
  371. dos.GetDate(SystemTime.Year, SystemTime.Month, SystemTime.Day, DayOfWeek);
  372. end ;
  373. Procedure InitAnsi;
  374. Var
  375. i : longint;
  376. begin
  377. { Fill table entries 0 to 127 }
  378. for i := 0 to 96 do
  379. UpperCaseTable[i] := chr(i);
  380. for i := 97 to 122 do
  381. UpperCaseTable[i] := chr(i - 32);
  382. for i := 123 to 191 do
  383. UpperCaseTable[i] := chr(i);
  384. Move (CPISO88591UCT,UpperCaseTable[192],SizeOf(CPISO88591UCT));
  385. for i := 0 to 64 do
  386. LowerCaseTable[i] := chr(i);
  387. for i := 65 to 90 do
  388. LowerCaseTable[i] := chr(i + 32);
  389. for i := 91 to 191 do
  390. LowerCaseTable[i] := chr(i);
  391. Move (CPISO88591LCT,UpperCaseTable[192],SizeOf(CPISO88591UCT));
  392. end;
  393. Procedure InitInternational;
  394. begin
  395. InitInternationalGeneric;
  396. InitAnsi;
  397. end;
  398. function SysErrorMessage(ErrorCode: Integer): String;
  399. begin
  400. { Result:=StrError(ErrorCode);}
  401. end;
  402. {****************************************************************************
  403. OS utility functions
  404. ****************************************************************************}
  405. Function GetEnvironmentVariable(Const EnvVar : String) : String;
  406. begin
  407. Result:=Dos.Getenv(shortstring(EnvVar));
  408. end;
  409. Function GetEnvironmentVariableCount : Integer;
  410. begin
  411. // Result:=FPCCountEnvVar(EnvP);
  412. Result:=Dos.envCount;
  413. end;
  414. Function GetEnvironmentString(Index : Integer) : String;
  415. begin
  416. // Result:=FPCGetEnvStrFromP(Envp,Index);
  417. Result:=Dos.EnvStr(Index);
  418. end;
  419. function ExecuteProcess (const Path: AnsiString; const ComLine: AnsiString):
  420. integer;
  421. var
  422. CommandLine: AnsiString;
  423. E: EOSError;
  424. begin
  425. Dos.Exec (Path, ComLine);
  426. if DosError <> 0 then begin
  427. if ComLine = '' then
  428. CommandLine := Path
  429. else
  430. CommandLine := Path + ' ' + ComLine;
  431. E := EOSError.CreateFmt (SExecuteProcessFailed, [CommandLine, DosError]);
  432. E.ErrorCode := DosError;
  433. raise E;
  434. end;
  435. end;
  436. function ExecuteProcess (const Path: AnsiString;
  437. const ComLine: array of AnsiString): integer;
  438. var
  439. CommandLine: AnsiString;
  440. I: integer;
  441. begin
  442. Commandline := '';
  443. for I := 0 to High (ComLine) do
  444. if Pos (' ', ComLine [I]) <> 0 then
  445. CommandLine := CommandLine + ' ' + '"' + ComLine [I] + '"'
  446. else
  447. CommandLine := CommandLine + ' ' + Comline [I];
  448. ExecuteProcess := ExecuteProcess (Path, CommandLine);
  449. end;
  450. {****************************************************************************
  451. Initialization code
  452. ****************************************************************************}
  453. Initialization
  454. InitExceptions;
  455. InitInternational; { Initialize internationalization settings }
  456. Finalization
  457. DoneExceptions;
  458. end.