sysutils.pp 21 KB

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