sysutils.pp 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724
  1. {
  2. This file is part of the Free Pascal run time library.
  3. Copyright (c) 2004-2005 by Olle Raab
  4. Sysutils unit for Mac OS.
  5. NOTE !!! THIS FILE IS UNDER CONSTRUCTION AND DOES NOT WORK CURRENLY.
  6. THUS IT IS NOT BUILT BY THE MAKEFILES
  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. {$modeswitch out}
  17. { force ansistrings }
  18. {$H+}
  19. uses
  20. MacOSTP;
  21. //{$DEFINE HAS_SLEEP} TODO
  22. //{$DEFINE HAS_OSERROR} TODO
  23. //{$DEFINE HAS_OSCONFIG} TODO
  24. type
  25. //TODO Check pad and size
  26. //TODO unify with Dos.SearchRec
  27. PMacOSFindData = ^TMacOSFindData;
  28. TMacOSFindData = record
  29. {MacOS specific params, private, do not use:}
  30. paramBlock: CInfoPBRec;
  31. searchFSSpec: FSSpec;
  32. searchAttr: Byte; {attribute we are searching for}
  33. exactMatch: Boolean;
  34. end;
  35. { Include platform independent interface part }
  36. {$i sysutilh.inc}
  37. implementation
  38. uses
  39. Dos, Sysconst; // For some included files.
  40. {$DEFINE FPC_FEXPAND_VOLUMES}
  41. {$DEFINE FPC_FEXPAND_NO_DEFAULT_PATHS}
  42. {$DEFINE FPC_FEXPAND_DRIVESEP_IS_ROOT}
  43. {$DEFINE FPC_FEXPAND_NO_DOTS_UPDIR}
  44. {$DEFINE FPC_FEXPAND_NO_CURDIR}
  45. { Include platform independent implementation part }
  46. {$i sysutils.inc}
  47. {****************************************************************************
  48. File Functions
  49. ****************************************************************************}
  50. Function FileOpen (Const FileName : string; Mode : Integer) : Longint;
  51. Var LinuxFlags : longint;
  52. BEGIN
  53. (* TODO fix
  54. LinuxFlags:=0;
  55. Case (Mode and 3) of
  56. 0 : LinuxFlags:=LinuxFlags or Open_RdOnly;
  57. 1 : LinuxFlags:=LinuxFlags or Open_WrOnly;
  58. 2 : LinuxFlags:=LinuxFlags or Open_RdWr;
  59. end;
  60. FileOpen:=fdOpen (FileName,LinuxFlags);
  61. //!! We need to set locking based on Mode !!
  62. *)
  63. end;
  64. Function FileCreate (Const FileName : String) : Longint;
  65. begin
  66. (* TODO fix
  67. FileCreate:=fdOpen(FileName,Open_RdWr or Open_Creat or Open_Trunc);
  68. *)
  69. end;
  70. Function FileCreate (Const FileName : String;Mode : Longint) : Longint;
  71. Var LinuxFlags : longint;
  72. BEGIN
  73. (* TODO fix
  74. LinuxFlags:=0;
  75. Case (Mode and 3) of
  76. 0 : LinuxFlags:=LinuxFlags or Open_RdOnly;
  77. 1 : LinuxFlags:=LinuxFlags or Open_WrOnly;
  78. 2 : LinuxFlags:=LinuxFlags or Open_RdWr;
  79. end;
  80. FileCreate:=fdOpen(FileName,LinuxFlags or Open_Creat or Open_Trunc);
  81. *)
  82. end;
  83. Function FileRead (Handle : Longint; out Buffer; Count : longint) : Longint;
  84. begin
  85. (* TODO fix
  86. FileRead:=fdRead (Handle,Buffer,Count);
  87. *)
  88. end;
  89. Function FileWrite (Handle : Longint; const Buffer; Count : Longint) : Longint;
  90. begin
  91. (* TODO fix
  92. FileWrite:=fdWrite (Handle,Buffer,Count);
  93. *)
  94. end;
  95. Function FileSeek (Handle,FOffset,Origin : Longint) : Longint;
  96. begin
  97. (* TODO fix
  98. FileSeek:=fdSeek (Handle,FOffset,Origin);
  99. *)
  100. end;
  101. Function FileSeek (Handle : Longint; FOffset: Int64; Origin : Longint) : Int64;
  102. begin
  103. (* TODO fix
  104. {$warning need to add 64bit call }
  105. FileSeek:=fdSeek (Handle,FOffset,Origin);
  106. *)
  107. end;
  108. Procedure FileClose (Handle : Longint);
  109. begin
  110. (* TODO fix
  111. fdclose(Handle);
  112. *)
  113. end;
  114. Function FileTruncate (Handle: THandle; Size: Int64) : boolean;
  115. begin
  116. (* TODO fix
  117. FileTruncate:=fdtruncate(Handle,Size);
  118. *)
  119. end;
  120. Function FileAge (Const FileName : String): Longint;
  121. (*
  122. Var Info : Stat;
  123. Y,M,D,hh,mm,ss : word;
  124. *)
  125. begin
  126. (* TODO fix
  127. If not fstat (FileName,Info) then
  128. exit(-1)
  129. else
  130. begin
  131. EpochToLocal(info.mtime,y,m,d,hh,mm,ss);
  132. Result:=DateTimeToFileDate(EncodeDate(y,m,d)+EncodeTime(hh,mm,ss,0));
  133. end;
  134. *)
  135. end;
  136. Function FileExists (Const FileName : String) : Boolean;
  137. (*
  138. Var Info : Stat;
  139. *)
  140. begin
  141. (* TODO fix
  142. FileExists:=fstat(filename,Info);
  143. *)
  144. end;
  145. Function DirectoryExists (Const Directory : String) : Boolean;
  146. (*
  147. Var Info : Stat;
  148. *)
  149. begin
  150. (* TODO fix
  151. DirectoryExists:=fstat(Directory,Info) and
  152. ((info.mode and STAT_IFMT)=STAT_IFDIR);
  153. *)
  154. end;
  155. (*
  156. Function LinuxToWinAttr (FN : Pchar; Const Info : Stat) : Longint;
  157. begin
  158. Result:=faArchive;
  159. If (Info.Mode and STAT_IFDIR)=STAT_IFDIR then
  160. Result:=Result or faDirectory;
  161. If (FN[0]='.') and (not (FN[1] in [#0,'.'])) then
  162. Result:=Result or faHidden;
  163. If (Info.Mode and STAT_IWUSR)=0 Then
  164. Result:=Result or faReadOnly;
  165. If (Info.Mode and
  166. (STAT_IFSOCK or STAT_IFBLK or STAT_IFCHR or STAT_IFIFO))<>0 then
  167. Result:=Result or faSysFile;
  168. end;
  169. {
  170. GlobToSearch takes a glob entry, stats the file.
  171. The glob entry is removed.
  172. If FileAttributes match, the entry is reused
  173. }
  174. Type
  175. TGlobSearchRec = Record
  176. Path : String;
  177. GlobHandle : PGlob;
  178. end;
  179. PGlobSearchRec = ^TGlobSearchRec;
  180. Function GlobToTSearchRec (Var Info : TSearchRec) : Boolean;
  181. Var SInfo : Stat;
  182. p : Pglob;
  183. GlobSearchRec : PGlobSearchrec;
  184. begin
  185. GlobSearchRec:=PGlobSearchrec(Info.FindHandle);
  186. P:=GlobSearchRec^.GlobHandle;
  187. Result:=P<>Nil;
  188. If Result then
  189. begin
  190. GlobSearchRec^.GlobHandle:=P^.Next;
  191. Result:=Fstat(GlobSearchRec^.Path+StrPas(p^.name),SInfo);
  192. If Result then
  193. begin
  194. Info.Attr:=LinuxToWinAttr(p^.name,SInfo);
  195. Result:=(Info.ExcludeAttr and Info.Attr)=0;
  196. If Result Then
  197. With Info do
  198. begin
  199. Attr:=Info.Attr;
  200. If P^.Name<>Nil then
  201. Name:=strpas(p^.name);
  202. Time:=Sinfo.mtime;
  203. Size:=Sinfo.Size;
  204. end;
  205. end;
  206. P^.Next:=Nil;
  207. GlobFree(P);
  208. end;
  209. end;
  210. *)
  211. procedure DoFind (var F: TSearchRec; firstTime: Boolean);
  212. var
  213. err: OSErr;
  214. s: Str255;
  215. begin
  216. with Rslt, findData, paramBlock do
  217. begin
  218. ioVRefNum := searchFSSpec.vRefNum;
  219. if firstTime then
  220. ioFDirIndex := 0;
  221. while true do
  222. begin
  223. s := '';
  224. ioDirID := searchFSSpec.parID;
  225. ioFDirIndex := ioFDirIndex + 1;
  226. ioNamePtr := @s;
  227. err := PBGetCatInfoSync(@paramBlock);
  228. if err <> noErr then
  229. begin
  230. if err = fnfErr then
  231. DosError := 18
  232. else
  233. DosError := MacOSErr2RTEerr(err);
  234. break;
  235. end;
  236. attr := GetFileAttrFromPB(Rslt.paramBlock);
  237. if ((Attr and not(searchAttr)) = 0) then
  238. begin
  239. name := s;
  240. UpperString(s, true);
  241. if FNMatch(Rslt.searchFSSpec.name, s) then
  242. begin
  243. size := GetFileSizeFromPB(paramBlock);
  244. time := MacTimeToDosPackedTime(ioFlMdDat);
  245. Result := 0;
  246. break;
  247. end;
  248. end;
  249. end;
  250. end;
  251. end;
  252. Function FindFirst (Const Path : String; Attr : Longint; out Rslt : TSearchRec) : Longint;
  253. var
  254. s: Str255;
  255. begin
  256. fillchar(Rslt, sizeof(Rslt), 0);
  257. if path = '' then
  258. begin
  259. Result := 3;
  260. Exit;
  261. end;
  262. {We always also search for readonly and archive, regardless of Attr.}
  263. Rslt.searchAttr := (Attr or (archive or readonly));
  264. Result := PathArgToFSSpec(path, Rslt.searchFSSpec);
  265. with Rslt do
  266. if (Result = 0) or (Result = 2) then
  267. begin
  268. SearchSpec := path;
  269. NamePos := Length(path) - Length(searchFSSpec.name);
  270. if (Pos('?', searchFSSpec.name) = 0) and (Pos('*', searchFSSpec.name) = 0) then {No wildcards}
  271. begin {If exact match, we don't have to scan the directory}
  272. exactMatch := true;
  273. Result := DoFindOne(searchFSSpec, paramBlock);
  274. if Result = 0 then
  275. begin
  276. Attr := GetFileAttrFromPB(paramBlock);
  277. if ((Attr and not(searchAttr)) = 0) then
  278. begin
  279. name := searchFSSpec.name;
  280. size := GetFileSizeFromPB(paramBlock);
  281. time := MacTimeToDosPackedTime(paramBlock.ioFlMdDat);
  282. end
  283. else
  284. Result := 18;
  285. end
  286. else if Result = 2 then
  287. Result := 18;
  288. end
  289. else
  290. begin
  291. exactMatch := false;
  292. s := searchFSSpec.name;
  293. UpperString(s, true);
  294. Rslt.searchFSSpec.name := s;
  295. DoFind(Rslt, true);
  296. end;
  297. end;
  298. end;
  299. Function FindNext (Var Rslt : TSearchRec) : Longint;
  300. begin
  301. if F.exactMatch then
  302. Result := 18
  303. else
  304. Result:=DoFind (Rslt);
  305. end;
  306. Procedure FindClose (Var F : TSearchrec);
  307. (*
  308. Var
  309. GlobSearchRec : PGlobSearchRec;
  310. *)
  311. begin
  312. (* TODO fix
  313. GlobSearchRec:=PGlobSearchRec(F.FindHandle);
  314. GlobFree (GlobSearchRec^.GlobHandle);
  315. Dispose(GlobSearchRec);
  316. *)
  317. end;
  318. Function FileGetDate (Handle : Longint) : Longint;
  319. (*
  320. Var Info : Stat;
  321. *)
  322. begin
  323. (* TODO fix
  324. If Not(FStat(Handle,Info)) then
  325. Result:=-1
  326. else
  327. Result:=Info.Mtime;
  328. *)
  329. end;
  330. Function FileSetDate (Handle,Age : Longint) : Longint;
  331. begin
  332. // TODO fix
  333. // Impossible under Linux from FileHandle !!
  334. FileSetDate:=-1;
  335. end;
  336. Function FileGetAttr (Const FileName : String) : Longint;
  337. (*
  338. Var Info : Stat;
  339. *)
  340. begin
  341. (* TODO fix
  342. If Not FStat (FileName,Info) then
  343. Result:=-1
  344. Else
  345. Result:=LinuxToWinAttr(Pchar(FileName),Info);
  346. *)
  347. end;
  348. Function FileSetAttr (Const Filename : String; Attr: longint) : Longint;
  349. begin
  350. Result:=-1;
  351. end;
  352. Function DeleteFile (Const FileName : String) : Boolean;
  353. begin
  354. (* TODO fix
  355. Result:=UnLink (FileName);
  356. *)
  357. end;
  358. Function RenameFile (Const OldName, NewName : String) : Boolean;
  359. begin
  360. (* TODO fix
  361. RenameFile:=Unix.FRename(OldNAme,NewName);
  362. *)
  363. end;
  364. {****************************************************************************
  365. Disk Functions
  366. ****************************************************************************}
  367. {
  368. The Diskfree and Disksize functions need a file on the specified drive, since this
  369. is required for the statfs system call.
  370. These filenames are set in drivestr[0..26], and have been preset to :
  371. 0 - '.' (default drive - hence current dir is ok.)
  372. 1 - '/fd0/.' (floppy drive 1 - should be adapted to local system )
  373. 2 - '/fd1/.' (floppy drive 2 - should be adapted to local system )
  374. 3 - '/' (C: equivalent of dos is the root partition)
  375. 4..26 (can be set by you're own applications)
  376. ! Use AddDisk() to Add new drives !
  377. They both return -1 when a failure occurs.
  378. }
  379. Const
  380. FixDriveStr : array[0..3] of pchar=(
  381. '.',
  382. '/fd0/.',
  383. '/fd1/.',
  384. '/.'
  385. );
  386. var
  387. Drives : byte;
  388. DriveStr : array[4..26] of pchar;
  389. Procedure AddDisk(const path:string);
  390. begin
  391. if not (DriveStr[Drives]=nil) then
  392. FreeMem(DriveStr[Drives],StrLen(DriveStr[Drives])+1);
  393. GetMem(DriveStr[Drives],length(Path)+1);
  394. StrPCopy(DriveStr[Drives],path);
  395. inc(Drives);
  396. if Drives>26 then
  397. Drives:=4;
  398. end;
  399. Function DiskFree(Drive: Byte): int64;
  400. (*
  401. var
  402. fs : tstatfs;
  403. *)
  404. Begin
  405. (* TODO fix
  406. if ((Drive<4) and (not (fixdrivestr[Drive]=nil)) and statfs(StrPas(fixdrivestr[drive]),fs)) or
  407. ((not (drivestr[Drive]=nil)) and statfs(StrPas(drivestr[drive]),fs)) then
  408. Diskfree:=int64(fs.bavail)*int64(fs.bsize)
  409. else
  410. Diskfree:=-1;
  411. *)
  412. End;
  413. Function DiskSize(Drive: Byte): int64;
  414. (*
  415. var
  416. fs : tstatfs;
  417. *)
  418. Begin
  419. (* TODO fix
  420. if ((Drive<4) and (not (fixdrivestr[Drive]=nil)) and statfs(StrPas(fixdrivestr[drive]),fs)) or
  421. ((not (drivestr[Drive]=nil)) and statfs(StrPas(drivestr[drive]),fs)) then
  422. DiskSize:=int64(fs.blocks)*int64(fs.bsize)
  423. else
  424. DiskSize:=-1;
  425. *)
  426. End;
  427. Function GetCurrentDir : String;
  428. begin
  429. GetDir (0,Result);
  430. end;
  431. Function SetCurrentDir (Const NewDir : String) : Boolean;
  432. begin
  433. {$I-}
  434. ChDir(NewDir);
  435. {$I+}
  436. result := (IOResult = 0);
  437. end;
  438. Function CreateDir (Const NewDir : String) : Boolean;
  439. begin
  440. {$I-}
  441. MkDir(NewDir);
  442. {$I+}
  443. result := (IOResult = 0);
  444. end;
  445. Function RemoveDir (Const Dir : String) : Boolean;
  446. begin
  447. {$I-}
  448. RmDir(Dir);
  449. {$I+}
  450. result := (IOResult = 0);
  451. end;
  452. {****************************************************************************
  453. Misc Functions
  454. ****************************************************************************}
  455. procedure Beep;
  456. begin
  457. //TODO fix
  458. end;
  459. {****************************************************************************
  460. Locale Functions
  461. ****************************************************************************}
  462. Procedure GetLocalTime(var SystemTime: TSystemTime);
  463. begin
  464. (* TODO fix
  465. Unix.GetTime(SystemTime.Hour, SystemTime.Minute, SystemTime.Second);
  466. Unix.GetDate(SystemTime.Year, SystemTime.Month, SystemTime.Day);
  467. SystemTime.MilliSecond := 0;
  468. *)
  469. end ;
  470. Procedure InitAnsi;
  471. Var
  472. i : longint;
  473. begin
  474. { Fill table entries 0 to 127 }
  475. for i := 0 to 96 do
  476. UpperCaseTable[i] := chr(i);
  477. for i := 97 to 122 do
  478. UpperCaseTable[i] := chr(i - 32);
  479. for i := 123 to 191 do
  480. UpperCaseTable[i] := chr(i);
  481. Move (CPISO88591UCT,UpperCaseTable[192],SizeOf(CPISO88591UCT));
  482. for i := 0 to 64 do
  483. LowerCaseTable[i] := chr(i);
  484. for i := 65 to 90 do
  485. LowerCaseTable[i] := chr(i + 32);
  486. for i := 91 to 191 do
  487. LowerCaseTable[i] := chr(i);
  488. Move (CPISO88591LCT,UpperCaseTable[192],SizeOf(CPISO88591UCT));
  489. end;
  490. Procedure InitInternational;
  491. begin
  492. InitInternationalGeneric;
  493. InitAnsi;
  494. end;
  495. function SysErrorMessage(ErrorCode: Integer): String;
  496. begin
  497. (* TODO fix
  498. Result:=StrError(ErrorCode);
  499. *)
  500. end;
  501. {****************************************************************************
  502. OS utility functions
  503. ****************************************************************************}
  504. Function GetEnvironmentVariable(Const EnvVar : String) : String;
  505. begin
  506. (* TODO fix
  507. Result:=StrPas(Unix.Getenv(PChar(EnvVar)));
  508. *)
  509. end;
  510. Function GetEnvironmentVariableCount : Integer;
  511. begin
  512. // Result:=FPCCountEnvVar(EnvP);
  513. Result:=0;
  514. end;
  515. Function GetEnvironmentString(Index : Integer) : String;
  516. begin
  517. // Result:=FPCGetEnvStrFromP(Envp,Index);
  518. Result:='';
  519. end;
  520. function ExecuteProcess(Const Path: AnsiString; Const ComLine: AnsiString;Flags:TExecuteFlags=[]):integer;
  521. var
  522. s: AnsiString;
  523. wdpath: AnsiString;
  524. laststatuscode : longint;
  525. Begin
  526. {Make ToolServers working directory in sync with our working directory}
  527. PathArgToFullPath(':', wdpath);
  528. wdpath:= 'Directory ' + wdpath;
  529. Result := ExecuteToolserverScript(PChar(wdpath), laststatuscode);
  530. {TODO Only change path when actually needed. But this requires some
  531. change counter to be incremented each time wd is changed. }
  532. s:= path + ' ' + comline;
  533. Result := ExecuteToolserverScript(PChar(s), laststatuscode);
  534. if Result = afpItemNotFound then
  535. Result := 900
  536. else
  537. Result := MacOSErr2RTEerr(Result);
  538. if Result <> 0
  539. then
  540. raise EOSErr;
  541. //TODO Better dos error codes
  542. if laststatuscode <> 0 then
  543. begin
  544. {MPW status might be 24 bits}
  545. Result := laststatuscode and $ffff;
  546. if Result = 0 then
  547. Result := 1;
  548. end
  549. else
  550. Result := 0;
  551. End;
  552. function ExecuteProcess(Const Path: AnsiString; Const ComLine: Array Of AnsiString;Flags:TExecuteFlags=[]):integer;
  553. begin
  554. end;
  555. procedure Sleep(milliseconds: Cardinal);
  556. begin
  557. end;
  558. (*
  559. Function GetLastOSError : Integer;
  560. begin
  561. end;
  562. *)
  563. {****************************************************************************
  564. Initialization code
  565. ****************************************************************************}
  566. Initialization
  567. InitExceptions; { Initialize exceptions. OS independent }
  568. InitInternational; { Initialize internationalization settings }
  569. Finalization
  570. DoneExceptions;
  571. end.