sysutils.pp 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857
  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. {$IFDEF UNICODERTL}
  18. {$MODESWITCH UNICODESTRINGS}
  19. {$ELSE}
  20. {$H+}
  21. {$ENDIF}
  22. {$modeswitch typehelpers}
  23. {$modeswitch advancedrecords}
  24. {OS has only 1 byte version for ExecuteProcess}
  25. {$define executeprocuni}
  26. uses
  27. MacOSTP;
  28. {$DEFINE HAS_SLEEP} {Dummy implementation: TODO }
  29. //{$DEFINE HAS_OSERROR} TODO
  30. //{$DEFINE HAS_OSCONFIG} TODO
  31. type
  32. //TODO Check pad and size
  33. //TODO unify with Dos.SearchRec
  34. PMacOSFindData = ^TMacOSFindData;
  35. TMacOSFindData = record
  36. {MacOS specific params, private, do not use:}
  37. paramBlock: CInfoPBRec;
  38. searchFSSpec: FSSpec;
  39. searchAttr: Byte; {attribute we are searching for}
  40. exactMatch: Boolean;
  41. end;
  42. { used OS file system APIs use ansistring }
  43. {$define SYSUTILS_HAS_ANSISTR_FILEUTIL_IMPL}
  44. { OS has an ansistring/single byte environment variable API }
  45. {$define SYSUTILS_HAS_ANSISTR_ENVVAR_IMPL}
  46. { Include platform independent interface part }
  47. {$i sysutilh.inc}
  48. implementation
  49. uses
  50. Dos, Sysconst, macutils; // For some included files.
  51. {$DEFINE FPC_FEXPAND_VOLUMES}
  52. {$DEFINE FPC_FEXPAND_NO_DEFAULT_PATHS}
  53. {$DEFINE FPC_FEXPAND_DRIVESEP_IS_ROOT}
  54. {$DEFINE FPC_FEXPAND_NO_DOTS_UPDIR}
  55. {$DEFINE FPC_FEXPAND_NO_CURDIR}
  56. { Include platform independent implementation part }
  57. {$i sysutils.inc}
  58. {****************************************************************************
  59. File Functions
  60. ****************************************************************************}
  61. Function FileOpen (Const FileName : rawbytestring; Mode : Integer) : Longint;
  62. Var LinuxFlags : longint;
  63. SystemFileName: RawByteString;
  64. begin
  65. (* TODO fix
  66. SystemFileName:=ToSingleByteFileSystemEncodedFileName(FileName);
  67. LinuxFlags:=0;
  68. Case (Mode and 3) of
  69. 0 : LinuxFlags:=LinuxFlags or Open_RdOnly;
  70. 1 : LinuxFlags:=LinuxFlags or Open_WrOnly;
  71. 2 : LinuxFlags:=LinuxFlags or Open_RdWr;
  72. end;
  73. FileOpen:=fdOpen (FileName,LinuxFlags);
  74. //!! We need to set locking based on Mode !!
  75. *)
  76. end;
  77. Function FileCreate (Const FileName : RawByteString) : Longint;
  78. begin
  79. (* TODO fix
  80. FileCreate:=fdOpen(FileName,Open_RdWr or Open_Creat or Open_Trunc);
  81. *)
  82. end;
  83. Function FileCreate (Const FileName : RawByteString;Rights : Longint) : Longint;
  84. Var LinuxFlags : longint;
  85. BEGIN
  86. (* TODO fix
  87. LinuxFlags:=0;
  88. Case (Mode and 3) of
  89. 0 : LinuxFlags:=LinuxFlags or Open_RdOnly;
  90. 1 : LinuxFlags:=LinuxFlags or Open_WrOnly;
  91. 2 : LinuxFlags:=LinuxFlags or Open_RdWr;
  92. end;
  93. FileCreate:=fdOpen(FileName,LinuxFlags or Open_Creat or Open_Trunc);
  94. *)
  95. end;
  96. Function FileCreate (Const FileName : RawByteString;ShareMode : Longint; Rights : Longint) : Longint;
  97. Var LinuxFlags : longint;
  98. BEGIN
  99. (* TODO fix
  100. LinuxFlags:=0;
  101. Case (Mode and 3) of
  102. 0 : LinuxFlags:=LinuxFlags or Open_RdOnly;
  103. 1 : LinuxFlags:=LinuxFlags or Open_WrOnly;
  104. 2 : LinuxFlags:=LinuxFlags or Open_RdWr;
  105. end;
  106. FileCreate:=fdOpen(FileName,LinuxFlags or Open_Creat or Open_Trunc);
  107. *)
  108. end;
  109. Function FileRead (Handle : Longint; out Buffer; Count : longint) : Longint;
  110. begin
  111. (* TODO fix
  112. FileRead:=fdRead (Handle,Buffer,Count);
  113. *)
  114. end;
  115. Function FileWrite (Handle : Longint; const Buffer; Count : Longint) : Longint;
  116. begin
  117. (* TODO fix
  118. FileWrite:=fdWrite (Handle,Buffer,Count);
  119. *)
  120. end;
  121. Function FileSeek (Handle,FOffset,Origin : Longint) : Longint;
  122. begin
  123. (* TODO fix
  124. FileSeek:=fdSeek (Handle,FOffset,Origin);
  125. *)
  126. end;
  127. Function FileSeek (Handle : Longint; FOffset: Int64; Origin : Longint) : Int64;
  128. begin
  129. (* TODO fix
  130. {$warning need to add 64bit call }
  131. FileSeek:=fdSeek (Handle,FOffset,Origin);
  132. *)
  133. end;
  134. Procedure FileClose (Handle : Longint);
  135. begin
  136. (* TODO fix
  137. fdclose(Handle);
  138. *)
  139. end;
  140. Function FileTruncate (Handle: THandle; Size: Int64) : boolean;
  141. begin
  142. (* TODO fix
  143. FileTruncate:=fdtruncate(Handle,Size);
  144. *)
  145. end;
  146. Function FileAge (Const FileName : RawByteString): Int64;
  147. (*
  148. Var Info : Stat;
  149. Y,M,D,hh,mm,ss : word;
  150. *)
  151. begin
  152. (* TODO fix
  153. If not fstat (FileName,Info) then
  154. exit(-1)
  155. else
  156. begin
  157. EpochToLocal(info.mtime,y,m,d,hh,mm,ss);
  158. Result:=DateTimeToFileDate(EncodeDate(y,m,d)+EncodeTime(hh,mm,ss,0));
  159. end;
  160. *)
  161. end;
  162. function FileGetSymLinkTarget(const FileName: RawByteString; out SymLinkRec: TRawbyteSymLinkRec): Boolean;
  163. begin
  164. Result := False;
  165. end;
  166. Function FileExists (Const FileName : RawByteString; FollowLink : Boolean) : Boolean;
  167. (*
  168. Var Info : Stat;
  169. *)
  170. begin
  171. (* TODO fix
  172. FileExists:=fstat(filename,Info);
  173. *)
  174. end;
  175. Function DirectoryExists (Const Directory : RawByteString; FollowLink : Boolean) : Boolean;
  176. (*
  177. Var Info : Stat;
  178. *)
  179. begin
  180. (* TODO fix
  181. DirectoryExists:=fstat(Directory,Info) and
  182. ((info.mode and STAT_IFMT)=STAT_IFDIR);
  183. *)
  184. end;
  185. (*
  186. Function LinuxToWinAttr (FN : PAnsiChar; Const Info : Stat) : Longint;
  187. begin
  188. Result:=faArchive;
  189. If (Info.Mode and STAT_IFDIR)=STAT_IFDIR then
  190. Result:=Result or faDirectory;
  191. If (FN[0]='.') and (not (FN[1] in [#0,'.'])) then
  192. Result:=Result or faHidden;
  193. If (Info.Mode and STAT_IWUSR)=0 Then
  194. Result:=Result or faReadOnly;
  195. If (Info.Mode and
  196. (STAT_IFSOCK or STAT_IFBLK or STAT_IFCHR or STAT_IFIFO))<>0 then
  197. Result:=Result or faSysFile;
  198. end;
  199. {
  200. GlobToSearch takes a glob entry, stats the file.
  201. The glob entry is removed.
  202. If FileAttributes match, the entry is reused
  203. }
  204. Type
  205. TGlobSearchRec = Record
  206. Path : String;
  207. GlobHandle : PGlob;
  208. end;
  209. PGlobSearchRec = ^TGlobSearchRec;
  210. Function GlobToTSearchRec (Var Info : TSearchRec) : Boolean;
  211. Var SInfo : Stat;
  212. p : Pglob;
  213. GlobSearchRec : PGlobSearchrec;
  214. begin
  215. GlobSearchRec:=PGlobSearchrec(Info.FindHandle);
  216. P:=GlobSearchRec^.GlobHandle;
  217. Result:=P<>Nil;
  218. If Result then
  219. begin
  220. GlobSearchRec^.GlobHandle:=P^.Next;
  221. Result:=Fstat(GlobSearchRec^.Path+StrPas(p^.name),SInfo);
  222. If Result then
  223. begin
  224. Info.Attr:=LinuxToWinAttr(p^.name,SInfo);
  225. Result:=(Info.ExcludeAttr and Info.Attr)=0;
  226. If Result Then
  227. With Info do
  228. begin
  229. Attr:=Info.Attr;
  230. If P^.Name<>Nil then
  231. Name:=strpas(p^.name);
  232. Time:=Sinfo.mtime;
  233. Size:=Sinfo.Size;
  234. end;
  235. end;
  236. P^.Next:=Nil;
  237. GlobFree(P);
  238. end;
  239. end;
  240. *)
  241. procedure DoFind (var F: TSearchRec; var retname: RawByteString; firstTime: Boolean);
  242. var
  243. err: OSErr;
  244. s: Str255;
  245. begin
  246. (* TODO fix
  247. with Rslt, findData, paramBlock do
  248. begin
  249. ioVRefNum := searchFSSpec.vRefNum;
  250. if firstTime then
  251. ioFDirIndex := 0;
  252. while true do
  253. begin
  254. s := '';
  255. ioDirID := searchFSSpec.parID;
  256. ioFDirIndex := ioFDirIndex + 1;
  257. ioNamePtr := @s;
  258. err := PBGetCatInfoSync(@paramBlock);
  259. if err <> noErr then
  260. begin
  261. if err = fnfErr then
  262. DosError := 18
  263. else
  264. DosError := MacOSErr2RTEerr(err);
  265. break;
  266. end;
  267. attr := GetFileAttrFromPB(Rslt.paramBlock);
  268. if ((Attr and not(searchAttr)) = 0) then
  269. begin
  270. retname := s;
  271. SetCodePage(retname, DefaultFileSystemCodePage, false);
  272. UpperString(s, true);
  273. if FNMatch(Rslt.searchFSSpec.name, s) then
  274. begin
  275. size := GetFileSizeFromPB(paramBlock);
  276. time := MacTimeToDosPackedTime(ioFlMdDat);
  277. Result := 0;
  278. break;
  279. end;
  280. end;
  281. end;
  282. end;
  283. *)
  284. end;
  285. Function InternalFindFirst (Const Path : RawByteString; Attr : Longint; out Rslt : TAbstractSearchRec; var Name: RawByteString) : Longint;
  286. var
  287. s: Str255;
  288. begin
  289. (* TODO fix
  290. if path = '' then
  291. begin
  292. Result := 3;
  293. Exit;
  294. end;
  295. {We always also search for readonly and archive, regardless of Attr.}
  296. Rslt.searchAttr := (Attr or (archive or readonly));
  297. { TODO: convert PathArgToFSSpec (and the routines it calls) to rawbytestring }
  298. Result := PathArgToFSSpec(path, Rslt.searchFSSpec);
  299. with Rslt do
  300. if (Result = 0) or (Result = 2) then
  301. begin
  302. { FIXME: SearchSpec is a shortstring -> ignores encoding }
  303. SearchSpec := path;
  304. NamePos := Length(path) - Length(searchFSSpec.name);
  305. if (Pos('?', searchFSSpec.name) = 0) and (Pos('*', searchFSSpec.name) = 0) then {No wildcards}
  306. begin {If exact match, we don't have to scan the directory}
  307. exactMatch := true;
  308. Result := DoFindOne(searchFSSpec, paramBlock);
  309. if Result = 0 then
  310. begin
  311. Attr := GetFileAttrFromPB(paramBlock);
  312. if ((Attr and not(searchAttr)) = 0) then
  313. begin
  314. name := searchFSSpec.name;
  315. SetCodePage(name, DefaultFileSystemCodePage, false);
  316. size := GetFileSizeFromPB(paramBlock);
  317. time := MacTimeToDosPackedTime(paramBlock.ioFlMdDat);
  318. end
  319. else
  320. Result := 18;
  321. end
  322. else if Result = 2 then
  323. Result := 18;
  324. end
  325. else
  326. begin
  327. exactMatch := false;
  328. s := searchFSSpec.name;
  329. UpperString(s, true);
  330. Rslt.searchFSSpec.name := s;
  331. DoFind(Rslt, name, true);
  332. end;
  333. end;
  334. *)
  335. end;
  336. Function InternalFindNext (var Rslt : TAbstractSearchRec; var Name : RawByteString) : Longint;
  337. begin
  338. (* TODO fix
  339. if F.exactMatch then
  340. Result := 18
  341. else
  342. Result:=DoFind (Rslt, Name, false);
  343. *)
  344. end;
  345. Procedure InternalFindClose (var Handle: THandle; var FindData: TFindData);
  346. (*
  347. Var
  348. GlobSearchRec : PGlobSearchRec;
  349. *)
  350. begin
  351. (* TODO fix
  352. GlobSearchRec:=PGlobSearchRec(Handle);
  353. GlobFree (GlobSearchRec^.GlobHandle);
  354. Dispose(GlobSearchRec);
  355. *)
  356. end;
  357. Function FileGetDate (Handle : Longint) : Int64;
  358. (*
  359. Var Info : Stat;
  360. *)
  361. begin
  362. (* TODO fix
  363. If Not(FStat(Handle,Info)) then
  364. Result:=-1
  365. else
  366. Result:=Info.Mtime;
  367. *)
  368. end;
  369. Function FileSetDate (Handle: Longint; Age: Int64) : Longint;
  370. begin
  371. // TODO fix
  372. // Impossible under Linux from FileHandle !!
  373. FileSetDate:=-1;
  374. end;
  375. Function FileGetAttr (Const FileName : RawByteString) : Longint;
  376. (*
  377. Var Info : Stat;
  378. *)
  379. begin
  380. (* TODO fix
  381. If Not FStat (FileName,Info) then
  382. Result:=-1
  383. Else
  384. Result:=LinuxToWinAttr(PAnsiChar(FileName),Info);
  385. *)
  386. end;
  387. Function FileSetAttr (Const Filename : RawByteString; Attr: longint) : Longint;
  388. begin
  389. Result:=-1;
  390. end;
  391. Function DeleteFile (Const FileName : RawByteString) : Boolean;
  392. begin
  393. (* TODO fix
  394. Result:=UnLink (FileName);
  395. *)
  396. end;
  397. Function RenameFile (Const OldName, NewName : RawByteString) : Boolean;
  398. begin
  399. (* TODO fix
  400. RenameFile:=Unix.FRename(OldNAme,NewName);
  401. *)
  402. end;
  403. {****************************************************************************
  404. Disk Functions
  405. ****************************************************************************}
  406. {
  407. The Diskfree and Disksize functions need a file on the specified drive, since this
  408. is required for the statfs system call.
  409. These filenames are set in drivestr[0..26], and have been preset to :
  410. 0 - '.' (default drive - hence current dir is ok.)
  411. 1 - '/fd0/.' (floppy drive 1 - should be adapted to local system )
  412. 2 - '/fd1/.' (floppy drive 2 - should be adapted to local system )
  413. 3 - '/' (C: equivalent of dos is the root partition)
  414. 4..26 (can be set by you're own applications)
  415. ! Use AddDisk() to Add new drives !
  416. They both return -1 when a failure occurs.
  417. }
  418. Const
  419. FixDriveStr : array[0..3] of PAnsiChar=(
  420. '.',
  421. '/fd0/.',
  422. '/fd1/.',
  423. '/.'
  424. );
  425. var
  426. Drives : byte;
  427. DriveStr : array[4..26] of PAnsiChar;
  428. Procedure AddDisk(const path:string);
  429. begin
  430. if not (DriveStr[Drives]=nil) then
  431. FreeMem(DriveStr[Drives],StrLen(DriveStr[Drives])+1);
  432. GetMem(DriveStr[Drives],length(Path)+1);
  433. StrPCopy(DriveStr[Drives],path);
  434. inc(Drives);
  435. if Drives>26 then
  436. Drives:=4;
  437. end;
  438. Function DiskFree(Drive: Byte): int64;
  439. (*
  440. var
  441. fs : tstatfs;
  442. *)
  443. Begin
  444. (* TODO fix
  445. if ((Drive<4) and (not (fixdrivestr[Drive]=nil)) and statfs(StrPas(fixdrivestr[drive]),fs)) or
  446. ((not (drivestr[Drive]=nil)) and statfs(StrPas(drivestr[drive]),fs)) then
  447. Diskfree:=int64(fs.bavail)*int64(fs.bsize)
  448. else
  449. Diskfree:=-1;
  450. *)
  451. End;
  452. Function DiskSize(Drive: Byte): int64;
  453. (*
  454. var
  455. fs : tstatfs;
  456. *)
  457. Begin
  458. (* TODO fix
  459. if ((Drive<4) and (not (fixdrivestr[Drive]=nil)) and statfs(StrPas(fixdrivestr[drive]),fs)) or
  460. ((not (drivestr[Drive]=nil)) and statfs(StrPas(drivestr[drive]),fs)) then
  461. DiskSize:=int64(fs.blocks)*int64(fs.bsize)
  462. else
  463. DiskSize:=-1;
  464. *)
  465. End;
  466. {****************************************************************************
  467. Locale Functions
  468. ****************************************************************************}
  469. Procedure GetLocalTime(var SystemTime: TSystemTime);
  470. begin
  471. (* TODO fix
  472. Unix.GetTime(SystemTime.Hour, SystemTime.Minute, SystemTime.Second);
  473. Unix.GetDate(SystemTime.Year, SystemTime.Month, SystemTime.Day);
  474. SystemTime.MilliSecond := 0;
  475. *)
  476. end ;
  477. Procedure InitAnsi;
  478. Var
  479. i : longint;
  480. begin
  481. { Fill table entries 0 to 127 }
  482. for i := 0 to 96 do
  483. UpperCaseTable[i] := chr(i);
  484. for i := 97 to 122 do
  485. UpperCaseTable[i] := chr(i - 32);
  486. for i := 123 to 191 do
  487. UpperCaseTable[i] := chr(i);
  488. Move (CPISO88591UCT,UpperCaseTable[192],SizeOf(CPISO88591UCT));
  489. for i := 0 to 64 do
  490. LowerCaseTable[i] := chr(i);
  491. for i := 65 to 90 do
  492. LowerCaseTable[i] := chr(i + 32);
  493. for i := 91 to 191 do
  494. LowerCaseTable[i] := chr(i);
  495. Move (CPISO88591LCT,UpperCaseTable[192],SizeOf(CPISO88591UCT));
  496. end;
  497. Procedure InitInternational;
  498. begin
  499. InitInternationalGeneric;
  500. InitAnsi;
  501. end;
  502. function SysErrorMessage(ErrorCode: Integer): String;
  503. begin
  504. (* TODO fix
  505. Result:=StrError(ErrorCode);
  506. *)
  507. end;
  508. {****************************************************************************
  509. OS utility functions
  510. ****************************************************************************}
  511. Function GetEnvironmentVariable(Const EnvVar : String) : String;
  512. begin
  513. (* TODO fix
  514. Result:=Unix.Getenv(PAnsiChar(EnvVar));
  515. *)
  516. end;
  517. Function GetEnvironmentVariableCount : Integer;
  518. begin
  519. // Result:=FPCCountEnvVar(EnvP);
  520. Result:=0;
  521. end;
  522. Function GetEnvironmentString(Index : Integer) : {$ifdef FPC_RTL_UNICODE}UnicodeString{$else}AnsiString{$endif};
  523. begin
  524. // Result:=FPCGetEnvStrFromP(Envp,Index);
  525. Result:='';
  526. end;
  527. { Create a DoScript AppleEvent that targets the given application with text as the direct object. }
  528. function CreateDoScriptEvent (applCreator: OSType; scriptText: PAnsiChar; var theEvent: AppleEvent): OSErr;
  529. var
  530. err: OSErr;
  531. targetAddress: AEDesc;
  532. s: signedByte;
  533. begin
  534. err := AECreateDesc(FourCharCodeToLongword(typeApplSignature), @applCreator, sizeof(applCreator), targetAddress);
  535. if err = noErr then
  536. begin
  537. err := AECreateAppleEvent(FourCharCodeToLongword('misc'), FourCharCodeToLongword('dosc'),
  538. targetAddress, kAutoGenerateReturnID, kAnyTransactionID, theEvent);
  539. if err = noErr then
  540. { Add script text as the direct object parameter. }
  541. err := AEPutParamPtr(theEvent, FourCharCodeToLongword('----'),
  542. FourCharCodeToLongword('TEXT'), scriptText, Length(scriptText));
  543. if err <> noErr then
  544. AEDisposeDesc(theEvent);
  545. AEDisposeDesc(targetAddress);
  546. end;
  547. CreateDoScriptEvent := err;
  548. end;
  549. Procedure Fpc_WriteBuffer(var f:Text;const b;len:longint);[external name 'FPC_WRITEBUFFER'];
  550. {declared in text.inc}
  551. procedure WriteAEDescTypeCharToFile(desc: AEDesc; var f: Text);
  552. begin
  553. if desc.descriptorType = FourCharCodeToLongword(typeChar) then
  554. begin
  555. HLock(desc.dataHandle);
  556. Fpc_WriteBuffer(f, PAnsiChar(desc.dataHandle^)^, GetHandleSize(desc.dataHandle));
  557. Flush(f);
  558. HUnLock(desc.dataHandle);
  559. end;
  560. end;
  561. function ExecuteToolserverScript(scriptText: PAnsiChar; var statusCode: Longint): OSErr;
  562. var
  563. err: OSErr;
  564. err2: OSErr; {Non serious error}
  565. theEvent: AppleEvent;
  566. reply: AppleEvent;
  567. aresult: AEDesc;
  568. applFileSpec: FSSpec;
  569. p: SignedByte;
  570. const
  571. applCreator = 'MPSX'; {Toolserver}
  572. begin
  573. statusCode:= 3; //3 according to MPW.
  574. err:= CreateDoScriptEvent (FourCharCodeToLongword(applCreator), scriptText, theEvent);
  575. if err = noErr then
  576. begin
  577. err := AESend(theEvent, reply, kAEWaitReply, kAENormalPriority, kAEDefaultTimeOut, nil, nil);
  578. if err = connectionInvalid then { Toolserver not available }
  579. begin
  580. err := FindApplication(FourCharCodeToLongword(applCreator), applFileSpec);
  581. if err = noErr then
  582. err := LaunchFSSpec(false, applFileSpec);
  583. if err = noErr then
  584. err := AESend(theEvent, reply, kAEWaitReply, kAENormalPriority, kAEDefaultTimeOut, nil, nil);
  585. end;
  586. if err = noErr then
  587. begin
  588. err:= AEGetParamDesc(reply, FourCharCodeToLongword('stat'),
  589. FourCharCodeToLongword(typeLongInteger), aresult);
  590. if err = noErr then
  591. if aresult.descriptorType = FourCharCodeToLongword(typeLongInteger) then
  592. statusCode:= LongintPtr(aresult.dataHandle^)^;
  593. {If there is no output below, we get a non zero error code}
  594. err2:= AEGetParamDesc(reply, FourCharCodeToLongword('----'),
  595. FourCharCodeToLongword(typeChar), aresult);
  596. if err2 = noErr then
  597. WriteAEDescTypeCharToFile(aresult, stdout);
  598. err2:= AEGetParamDesc(reply, FourCharCodeToLongword('diag'),
  599. FourCharCodeToLongword(typeChar), aresult);
  600. if err2 = noErr then
  601. WriteAEDescTypeCharToFile(aresult, stderr);
  602. AEDisposeDesc(reply);
  603. {$IFDEF TARGET_API_MAC_CARBON }
  604. {$ERROR FIXME AEDesc data is not allowed to be directly accessed}
  605. {$ENDIF}
  606. end;
  607. AEDisposeDesc(theEvent);
  608. end;
  609. ExecuteToolserverScript:= err;
  610. end;
  611. function ExecuteProcess (const Path: RawByteString; const ComLine: RawByteString;Flags:TExecuteFlags=[]):
  612. integer;
  613. var
  614. s: AnsiString;
  615. wdpath: RawByteString;
  616. laststatuscode : longint;
  617. E: EOSError;
  618. Begin
  619. {Make ToolServers working directory in sync with our working directory}
  620. PathArgToFullPath(':', wdpath);
  621. wdpath:= 'Directory ' + wdpath;
  622. Result := ExecuteToolserverScript(PAnsiChar(wdpath), laststatuscode);
  623. {TODO Only change path when actually needed. But this requires some
  624. change counter to be incremented each time wd is changed. }
  625. s:= path + ' ' + comline;
  626. Result := ExecuteToolserverScript(PAnsiChar(s), laststatuscode);
  627. if Result = afpItemNotFound then
  628. Result := 900
  629. else
  630. Result := MacOSErr2RTEerr(Result);
  631. if Result <> 0 then
  632. begin
  633. E := EOSError.CreateFmt (SExecuteProcessFailed, [Comline, DosError]);
  634. E.ErrorCode := DosError;
  635. raise E;
  636. end;
  637. //TODO Better dos error codes
  638. if laststatuscode <> 0 then
  639. begin
  640. {MPW status might be 24 bits}
  641. Result := laststatuscode and $ffff;
  642. if Result = 0 then
  643. Result := 1;
  644. end
  645. else
  646. Result := 0;
  647. End;
  648. function ExecuteProcess (const Path: RawByteString;
  649. const ComLine: array of RawByteString;Flags:TExecuteFlags=[]): integer;
  650. var
  651. CommandLine: RawByteString;
  652. I: integer;
  653. begin
  654. Commandline := '';
  655. for I := 0 to High (ComLine) do
  656. if Pos (' ', ComLine [I]) <> 0 then
  657. CommandLine := CommandLine + ' ' + '"' + ToSingleByteFileSystemEncodedFileName(ComLine [I]) + '"'
  658. else
  659. CommandLine := CommandLine + ' ' + ToSingleByteFileSystemEncodedFileName(Comline [I]);
  660. ExecuteProcess := ExecuteProcess (Path, CommandLine);
  661. end;
  662. procedure C_usleep(val : uint32); external 'StdCLib' name 'usleep';
  663. procedure Sleep(milliseconds: Cardinal);
  664. begin
  665. C_usleep(milliseconds*1000);
  666. end;
  667. (*
  668. Function GetLastOSError : Integer;
  669. begin
  670. end;
  671. *)
  672. {****************************************************************************
  673. Initialization code
  674. ****************************************************************************}
  675. Initialization
  676. InitExceptions; { Initialize exceptions. OS independent }
  677. InitInternational; { Initialize internationalization settings }
  678. Finalization
  679. FreeTerminateProcs;
  680. DoneExceptions;
  681. end.