sysutils.pp 15 KB

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