sysutils.pp 15 KB

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