2
0

sysutils.pp 16 KB

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