sysutils.pp 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744
  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. Function GetCurrentDir : String;
  445. begin
  446. GetDir (0,Result);
  447. end;
  448. Function SetCurrentDir (Const NewDir : String) : Boolean;
  449. begin
  450. {$I-}
  451. ChDir(NewDir);
  452. {$I+}
  453. result := (IOResult = 0);
  454. end;
  455. Function CreateDir (Const NewDir : String) : Boolean;
  456. begin
  457. {$I-}
  458. MkDir(NewDir);
  459. {$I+}
  460. result := (IOResult = 0);
  461. end;
  462. Function RemoveDir (Const Dir : String) : Boolean;
  463. begin
  464. {$I-}
  465. RmDir(Dir);
  466. {$I+}
  467. result := (IOResult = 0);
  468. end;
  469. {****************************************************************************
  470. Misc Functions
  471. ****************************************************************************}
  472. procedure Beep;
  473. begin
  474. //TODO fix
  475. end;
  476. {****************************************************************************
  477. Locale Functions
  478. ****************************************************************************}
  479. Procedure GetLocalTime(var SystemTime: TSystemTime);
  480. begin
  481. (* TODO fix
  482. Unix.GetTime(SystemTime.Hour, SystemTime.Minute, SystemTime.Second);
  483. Unix.GetDate(SystemTime.Year, SystemTime.Month, SystemTime.Day);
  484. SystemTime.MilliSecond := 0;
  485. *)
  486. end ;
  487. Procedure InitAnsi;
  488. Var
  489. i : longint;
  490. begin
  491. { Fill table entries 0 to 127 }
  492. for i := 0 to 96 do
  493. UpperCaseTable[i] := chr(i);
  494. for i := 97 to 122 do
  495. UpperCaseTable[i] := chr(i - 32);
  496. for i := 123 to 191 do
  497. UpperCaseTable[i] := chr(i);
  498. Move (CPISO88591UCT,UpperCaseTable[192],SizeOf(CPISO88591UCT));
  499. for i := 0 to 64 do
  500. LowerCaseTable[i] := chr(i);
  501. for i := 65 to 90 do
  502. LowerCaseTable[i] := chr(i + 32);
  503. for i := 91 to 191 do
  504. LowerCaseTable[i] := chr(i);
  505. Move (CPISO88591LCT,UpperCaseTable[192],SizeOf(CPISO88591UCT));
  506. end;
  507. Procedure InitInternational;
  508. begin
  509. InitInternationalGeneric;
  510. InitAnsi;
  511. end;
  512. function SysErrorMessage(ErrorCode: Integer): String;
  513. begin
  514. (* TODO fix
  515. Result:=StrError(ErrorCode);
  516. *)
  517. end;
  518. {****************************************************************************
  519. OS utility functions
  520. ****************************************************************************}
  521. Function GetEnvironmentVariable(Const EnvVar : String) : String;
  522. begin
  523. (* TODO fix
  524. Result:=StrPas(Unix.Getenv(PChar(EnvVar)));
  525. *)
  526. end;
  527. Function GetEnvironmentVariableCount : Integer;
  528. begin
  529. // Result:=FPCCountEnvVar(EnvP);
  530. Result:=0;
  531. end;
  532. Function GetEnvironmentString(Index : Integer) : String;
  533. begin
  534. // Result:=FPCGetEnvStrFromP(Envp,Index);
  535. Result:='';
  536. end;
  537. function ExecuteProcess(Const Path: AnsiString; Const ComLine: AnsiString;Flags:TExecuteFlags=[]):integer;
  538. var
  539. s: AnsiString;
  540. wdpath: AnsiString;
  541. laststatuscode : longint;
  542. Begin
  543. {Make ToolServers working directory in sync with our working directory}
  544. PathArgToFullPath(':', wdpath);
  545. wdpath:= 'Directory ' + wdpath;
  546. Result := ExecuteToolserverScript(PChar(wdpath), laststatuscode);
  547. {TODO Only change path when actually needed. But this requires some
  548. change counter to be incremented each time wd is changed. }
  549. s:= path + ' ' + comline;
  550. Result := ExecuteToolserverScript(PChar(s), laststatuscode);
  551. if Result = afpItemNotFound then
  552. Result := 900
  553. else
  554. Result := MacOSErr2RTEerr(Result);
  555. if Result <> 0
  556. then
  557. raise EOSErr;
  558. //TODO Better dos error codes
  559. if laststatuscode <> 0 then
  560. begin
  561. {MPW status might be 24 bits}
  562. Result := laststatuscode and $ffff;
  563. if Result = 0 then
  564. Result := 1;
  565. end
  566. else
  567. Result := 0;
  568. End;
  569. function ExecuteProcess(Const Path: AnsiString; Const ComLine: Array Of AnsiString;Flags:TExecuteFlags=[]):integer;
  570. begin
  571. end;
  572. procedure Sleep(milliseconds: Cardinal);
  573. begin
  574. end;
  575. (*
  576. Function GetLastOSError : Integer;
  577. begin
  578. end;
  579. *)
  580. {****************************************************************************
  581. Initialization code
  582. ****************************************************************************}
  583. Initialization
  584. InitExceptions; { Initialize exceptions. OS independent }
  585. InitInternational; { Initialize internationalization settings }
  586. Finalization
  587. DoneExceptions;
  588. end.