sysutils.pp 16 KB

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