sysutils.pp 16 KB

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