sysutils.pp 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844
  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} 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): Longint;
  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 FileExists (Const FileName : RawByteString) : Boolean;
  160. (*
  161. Var Info : Stat;
  162. *)
  163. begin
  164. (* TODO fix
  165. FileExists:=fstat(filename,Info);
  166. *)
  167. end;
  168. Function DirectoryExists (Const Directory : RawByteString) : Boolean;
  169. (*
  170. Var Info : Stat;
  171. *)
  172. begin
  173. (* TODO fix
  174. DirectoryExists:=fstat(Directory,Info) and
  175. ((info.mode and STAT_IFMT)=STAT_IFDIR);
  176. *)
  177. end;
  178. (*
  179. Function LinuxToWinAttr (FN : Pchar; Const Info : Stat) : Longint;
  180. begin
  181. Result:=faArchive;
  182. If (Info.Mode and STAT_IFDIR)=STAT_IFDIR then
  183. Result:=Result or faDirectory;
  184. If (FN[0]='.') and (not (FN[1] in [#0,'.'])) then
  185. Result:=Result or faHidden;
  186. If (Info.Mode and STAT_IWUSR)=0 Then
  187. Result:=Result or faReadOnly;
  188. If (Info.Mode and
  189. (STAT_IFSOCK or STAT_IFBLK or STAT_IFCHR or STAT_IFIFO))<>0 then
  190. Result:=Result or faSysFile;
  191. end;
  192. {
  193. GlobToSearch takes a glob entry, stats the file.
  194. The glob entry is removed.
  195. If FileAttributes match, the entry is reused
  196. }
  197. Type
  198. TGlobSearchRec = Record
  199. Path : String;
  200. GlobHandle : PGlob;
  201. end;
  202. PGlobSearchRec = ^TGlobSearchRec;
  203. Function GlobToTSearchRec (Var Info : TSearchRec) : Boolean;
  204. Var SInfo : Stat;
  205. p : Pglob;
  206. GlobSearchRec : PGlobSearchrec;
  207. begin
  208. GlobSearchRec:=PGlobSearchrec(Info.FindHandle);
  209. P:=GlobSearchRec^.GlobHandle;
  210. Result:=P<>Nil;
  211. If Result then
  212. begin
  213. GlobSearchRec^.GlobHandle:=P^.Next;
  214. Result:=Fstat(GlobSearchRec^.Path+StrPas(p^.name),SInfo);
  215. If Result then
  216. begin
  217. Info.Attr:=LinuxToWinAttr(p^.name,SInfo);
  218. Result:=(Info.ExcludeAttr and Info.Attr)=0;
  219. If Result Then
  220. With Info do
  221. begin
  222. Attr:=Info.Attr;
  223. If P^.Name<>Nil then
  224. Name:=strpas(p^.name);
  225. Time:=Sinfo.mtime;
  226. Size:=Sinfo.Size;
  227. end;
  228. end;
  229. P^.Next:=Nil;
  230. GlobFree(P);
  231. end;
  232. end;
  233. *)
  234. procedure DoFind (var F: TSearchRec; var retname: RawByteString; firstTime: Boolean);
  235. var
  236. err: OSErr;
  237. s: Str255;
  238. begin
  239. (* TODO fix
  240. with Rslt, findData, paramBlock do
  241. begin
  242. ioVRefNum := searchFSSpec.vRefNum;
  243. if firstTime then
  244. ioFDirIndex := 0;
  245. while true do
  246. begin
  247. s := '';
  248. ioDirID := searchFSSpec.parID;
  249. ioFDirIndex := ioFDirIndex + 1;
  250. ioNamePtr := @s;
  251. err := PBGetCatInfoSync(@paramBlock);
  252. if err <> noErr then
  253. begin
  254. if err = fnfErr then
  255. DosError := 18
  256. else
  257. DosError := MacOSErr2RTEerr(err);
  258. break;
  259. end;
  260. attr := GetFileAttrFromPB(Rslt.paramBlock);
  261. if ((Attr and not(searchAttr)) = 0) then
  262. begin
  263. retname := s;
  264. SetCodePage(retname, DefaultFileSystemCodePage, false);
  265. UpperString(s, true);
  266. if FNMatch(Rslt.searchFSSpec.name, s) then
  267. begin
  268. size := GetFileSizeFromPB(paramBlock);
  269. time := MacTimeToDosPackedTime(ioFlMdDat);
  270. Result := 0;
  271. break;
  272. end;
  273. end;
  274. end;
  275. end;
  276. *)
  277. end;
  278. Function InternalFindFirst (Const Path : RawByteString; Attr : Longint; out Rslt : TAbstractSearchRec; var Name: RawByteString) : Longint;
  279. var
  280. s: Str255;
  281. begin
  282. (* TODO fix
  283. if path = '' then
  284. begin
  285. Result := 3;
  286. Exit;
  287. end;
  288. {We always also search for readonly and archive, regardless of Attr.}
  289. Rslt.searchAttr := (Attr or (archive or readonly));
  290. { TODO: convert PathArgToFSSpec (and the routines it calls) to rawbytestring }
  291. Result := PathArgToFSSpec(path, Rslt.searchFSSpec);
  292. with Rslt do
  293. if (Result = 0) or (Result = 2) then
  294. begin
  295. { FIXME: SearchSpec is a shortstring -> ignores encoding }
  296. SearchSpec := path;
  297. NamePos := Length(path) - Length(searchFSSpec.name);
  298. if (Pos('?', searchFSSpec.name) = 0) and (Pos('*', searchFSSpec.name) = 0) then {No wildcards}
  299. begin {If exact match, we don't have to scan the directory}
  300. exactMatch := true;
  301. Result := DoFindOne(searchFSSpec, paramBlock);
  302. if Result = 0 then
  303. begin
  304. Attr := GetFileAttrFromPB(paramBlock);
  305. if ((Attr and not(searchAttr)) = 0) then
  306. begin
  307. name := searchFSSpec.name;
  308. SetCodePage(name, DefaultFileSystemCodePage, false);
  309. size := GetFileSizeFromPB(paramBlock);
  310. time := MacTimeToDosPackedTime(paramBlock.ioFlMdDat);
  311. end
  312. else
  313. Result := 18;
  314. end
  315. else if Result = 2 then
  316. Result := 18;
  317. end
  318. else
  319. begin
  320. exactMatch := false;
  321. s := searchFSSpec.name;
  322. UpperString(s, true);
  323. Rslt.searchFSSpec.name := s;
  324. DoFind(Rslt, name, true);
  325. end;
  326. end;
  327. *)
  328. end;
  329. Function InternalFindNext (var Rslt : TAbstractSearchRec; var Name : RawByteString) : Longint;
  330. begin
  331. (* TODO fix
  332. if F.exactMatch then
  333. Result := 18
  334. else
  335. Result:=DoFind (Rslt, Name, false);
  336. *)
  337. end;
  338. Procedure InternalFindClose (var Handle: THandle; var FindData: TFindData);
  339. (*
  340. Var
  341. GlobSearchRec : PGlobSearchRec;
  342. *)
  343. begin
  344. (* TODO fix
  345. GlobSearchRec:=PGlobSearchRec(Handle);
  346. GlobFree (GlobSearchRec^.GlobHandle);
  347. Dispose(GlobSearchRec);
  348. *)
  349. end;
  350. Function FileGetDate (Handle : Longint) : Longint;
  351. (*
  352. Var Info : Stat;
  353. *)
  354. begin
  355. (* TODO fix
  356. If Not(FStat(Handle,Info)) then
  357. Result:=-1
  358. else
  359. Result:=Info.Mtime;
  360. *)
  361. end;
  362. Function FileSetDate (Handle,Age : Longint) : Longint;
  363. begin
  364. // TODO fix
  365. // Impossible under Linux from FileHandle !!
  366. FileSetDate:=-1;
  367. end;
  368. Function FileGetAttr (Const FileName : RawByteString) : Longint;
  369. (*
  370. Var Info : Stat;
  371. *)
  372. begin
  373. (* TODO fix
  374. If Not FStat (FileName,Info) then
  375. Result:=-1
  376. Else
  377. Result:=LinuxToWinAttr(Pchar(FileName),Info);
  378. *)
  379. end;
  380. Function FileSetAttr (Const Filename : RawByteString; Attr: longint) : Longint;
  381. begin
  382. Result:=-1;
  383. end;
  384. Function DeleteFile (Const FileName : RawByteString) : Boolean;
  385. begin
  386. (* TODO fix
  387. Result:=UnLink (FileName);
  388. *)
  389. end;
  390. Function RenameFile (Const OldName, NewName : RawByteString) : Boolean;
  391. begin
  392. (* TODO fix
  393. RenameFile:=Unix.FRename(OldNAme,NewName);
  394. *)
  395. end;
  396. {****************************************************************************
  397. Disk Functions
  398. ****************************************************************************}
  399. {
  400. The Diskfree and Disksize functions need a file on the specified drive, since this
  401. is required for the statfs system call.
  402. These filenames are set in drivestr[0..26], and have been preset to :
  403. 0 - '.' (default drive - hence current dir is ok.)
  404. 1 - '/fd0/.' (floppy drive 1 - should be adapted to local system )
  405. 2 - '/fd1/.' (floppy drive 2 - should be adapted to local system )
  406. 3 - '/' (C: equivalent of dos is the root partition)
  407. 4..26 (can be set by you're own applications)
  408. ! Use AddDisk() to Add new drives !
  409. They both return -1 when a failure occurs.
  410. }
  411. Const
  412. FixDriveStr : array[0..3] of pchar=(
  413. '.',
  414. '/fd0/.',
  415. '/fd1/.',
  416. '/.'
  417. );
  418. var
  419. Drives : byte;
  420. DriveStr : array[4..26] of pchar;
  421. Procedure AddDisk(const path:string);
  422. begin
  423. if not (DriveStr[Drives]=nil) then
  424. FreeMem(DriveStr[Drives],StrLen(DriveStr[Drives])+1);
  425. GetMem(DriveStr[Drives],length(Path)+1);
  426. StrPCopy(DriveStr[Drives],path);
  427. inc(Drives);
  428. if Drives>26 then
  429. Drives:=4;
  430. end;
  431. Function DiskFree(Drive: Byte): int64;
  432. (*
  433. var
  434. fs : tstatfs;
  435. *)
  436. Begin
  437. (* TODO fix
  438. if ((Drive<4) and (not (fixdrivestr[Drive]=nil)) and statfs(StrPas(fixdrivestr[drive]),fs)) or
  439. ((not (drivestr[Drive]=nil)) and statfs(StrPas(drivestr[drive]),fs)) then
  440. Diskfree:=int64(fs.bavail)*int64(fs.bsize)
  441. else
  442. Diskfree:=-1;
  443. *)
  444. End;
  445. Function DiskSize(Drive: Byte): int64;
  446. (*
  447. var
  448. fs : tstatfs;
  449. *)
  450. Begin
  451. (* TODO fix
  452. if ((Drive<4) and (not (fixdrivestr[Drive]=nil)) and statfs(StrPas(fixdrivestr[drive]),fs)) or
  453. ((not (drivestr[Drive]=nil)) and statfs(StrPas(drivestr[drive]),fs)) then
  454. DiskSize:=int64(fs.blocks)*int64(fs.bsize)
  455. else
  456. DiskSize:=-1;
  457. *)
  458. End;
  459. {****************************************************************************
  460. Locale Functions
  461. ****************************************************************************}
  462. Procedure GetLocalTime(var SystemTime: TSystemTime);
  463. begin
  464. (* TODO fix
  465. Unix.GetTime(SystemTime.Hour, SystemTime.Minute, SystemTime.Second);
  466. Unix.GetDate(SystemTime.Year, SystemTime.Month, SystemTime.Day);
  467. SystemTime.MilliSecond := 0;
  468. *)
  469. end ;
  470. Procedure InitAnsi;
  471. Var
  472. i : longint;
  473. begin
  474. { Fill table entries 0 to 127 }
  475. for i := 0 to 96 do
  476. UpperCaseTable[i] := chr(i);
  477. for i := 97 to 122 do
  478. UpperCaseTable[i] := chr(i - 32);
  479. for i := 123 to 191 do
  480. UpperCaseTable[i] := chr(i);
  481. Move (CPISO88591UCT,UpperCaseTable[192],SizeOf(CPISO88591UCT));
  482. for i := 0 to 64 do
  483. LowerCaseTable[i] := chr(i);
  484. for i := 65 to 90 do
  485. LowerCaseTable[i] := chr(i + 32);
  486. for i := 91 to 191 do
  487. LowerCaseTable[i] := chr(i);
  488. Move (CPISO88591LCT,UpperCaseTable[192],SizeOf(CPISO88591UCT));
  489. end;
  490. Procedure InitInternational;
  491. begin
  492. InitInternationalGeneric;
  493. InitAnsi;
  494. end;
  495. function SysErrorMessage(ErrorCode: Integer): String;
  496. begin
  497. (* TODO fix
  498. Result:=StrError(ErrorCode);
  499. *)
  500. end;
  501. {****************************************************************************
  502. OS utility functions
  503. ****************************************************************************}
  504. Function GetEnvironmentVariable(Const EnvVar : String) : String;
  505. begin
  506. (* TODO fix
  507. Result:=Unix.Getenv(PChar(EnvVar));
  508. *)
  509. end;
  510. Function GetEnvironmentVariableCount : Integer;
  511. begin
  512. // Result:=FPCCountEnvVar(EnvP);
  513. Result:=0;
  514. end;
  515. Function GetEnvironmentString(Index : Integer) : {$ifdef FPC_RTL_UNICODE}UnicodeString{$else}AnsiString{$endif};
  516. begin
  517. // Result:=FPCGetEnvStrFromP(Envp,Index);
  518. Result:='';
  519. end;
  520. { Create a DoScript AppleEvent that targets the given application with text as the direct object. }
  521. function CreateDoScriptEvent (applCreator: OSType; scriptText: PChar; var theEvent: AppleEvent): OSErr;
  522. var
  523. err: OSErr;
  524. targetAddress: AEDesc;
  525. s: signedByte;
  526. begin
  527. err := AECreateDesc(FourCharCodeToLongword(typeApplSignature), @applCreator, sizeof(applCreator), targetAddress);
  528. if err = noErr then
  529. begin
  530. err := AECreateAppleEvent(FourCharCodeToLongword('misc'), FourCharCodeToLongword('dosc'),
  531. targetAddress, kAutoGenerateReturnID, kAnyTransactionID, theEvent);
  532. if err = noErr then
  533. { Add script text as the direct object parameter. }
  534. err := AEPutParamPtr(theEvent, FourCharCodeToLongword('----'),
  535. FourCharCodeToLongword('TEXT'), scriptText, Length(scriptText));
  536. if err <> noErr then
  537. AEDisposeDesc(theEvent);
  538. AEDisposeDesc(targetAddress);
  539. end;
  540. CreateDoScriptEvent := err;
  541. end;
  542. Procedure Fpc_WriteBuffer(var f:Text;const b;len:longint);[external name 'FPC_WRITEBUFFER'];
  543. {declared in text.inc}
  544. procedure WriteAEDescTypeCharToFile(desc: AEDesc; var f: Text);
  545. begin
  546. if desc.descriptorType = FourCharCodeToLongword(typeChar) then
  547. begin
  548. HLock(desc.dataHandle);
  549. Fpc_WriteBuffer(f, PChar(desc.dataHandle^)^, GetHandleSize(desc.dataHandle));
  550. Flush(f);
  551. HUnLock(desc.dataHandle);
  552. end;
  553. end;
  554. function ExecuteToolserverScript(scriptText: PChar; var statusCode: Longint): OSErr;
  555. var
  556. err: OSErr;
  557. err2: OSErr; {Non serious error}
  558. theEvent: AppleEvent;
  559. reply: AppleEvent;
  560. aresult: AEDesc;
  561. applFileSpec: FSSpec;
  562. p: SignedByte;
  563. const
  564. applCreator = 'MPSX'; {Toolserver}
  565. begin
  566. statusCode:= 3; //3 according to MPW.
  567. err:= CreateDoScriptEvent (FourCharCodeToLongword(applCreator), scriptText, theEvent);
  568. if err = noErr then
  569. begin
  570. err := AESend(theEvent, reply, kAEWaitReply, kAENormalPriority, kAEDefaultTimeOut, nil, nil);
  571. if err = connectionInvalid then { Toolserver not available }
  572. begin
  573. err := FindApplication(FourCharCodeToLongword(applCreator), applFileSpec);
  574. if err = noErr then
  575. err := LaunchFSSpec(false, applFileSpec);
  576. if err = noErr then
  577. err := AESend(theEvent, reply, kAEWaitReply, kAENormalPriority, kAEDefaultTimeOut, nil, nil);
  578. end;
  579. if err = noErr then
  580. begin
  581. err:= AEGetParamDesc(reply, FourCharCodeToLongword('stat'),
  582. FourCharCodeToLongword(typeLongInteger), aresult);
  583. if err = noErr then
  584. if aresult.descriptorType = FourCharCodeToLongword(typeLongInteger) then
  585. statusCode:= LongintPtr(aresult.dataHandle^)^;
  586. {If there is no output below, we get a non zero error code}
  587. err2:= AEGetParamDesc(reply, FourCharCodeToLongword('----'),
  588. FourCharCodeToLongword(typeChar), aresult);
  589. if err2 = noErr then
  590. WriteAEDescTypeCharToFile(aresult, stdout);
  591. err2:= AEGetParamDesc(reply, FourCharCodeToLongword('diag'),
  592. FourCharCodeToLongword(typeChar), aresult);
  593. if err2 = noErr then
  594. WriteAEDescTypeCharToFile(aresult, stderr);
  595. AEDisposeDesc(reply);
  596. {$IFDEF TARGET_API_MAC_CARBON }
  597. {$ERROR FIXME AEDesc data is not allowed to be directly accessed}
  598. {$ENDIF}
  599. end;
  600. AEDisposeDesc(theEvent);
  601. end;
  602. ExecuteToolserverScript:= err;
  603. end;
  604. function ExecuteProcess (const Path: RawByteString; const ComLine: RawByteString;Flags:TExecuteFlags=[]):
  605. integer;
  606. var
  607. s: AnsiString;
  608. wdpath: RawByteString;
  609. laststatuscode : longint;
  610. E: EOSError;
  611. Begin
  612. {Make ToolServers working directory in sync with our working directory}
  613. PathArgToFullPath(':', wdpath);
  614. wdpath:= 'Directory ' + wdpath;
  615. Result := ExecuteToolserverScript(PChar(wdpath), laststatuscode);
  616. {TODO Only change path when actually needed. But this requires some
  617. change counter to be incremented each time wd is changed. }
  618. s:= path + ' ' + comline;
  619. Result := ExecuteToolserverScript(PChar(s), laststatuscode);
  620. if Result = afpItemNotFound then
  621. Result := 900
  622. else
  623. Result := MacOSErr2RTEerr(Result);
  624. if Result <> 0 then
  625. begin
  626. E := EOSError.CreateFmt (SExecuteProcessFailed, [Comline, DosError]);
  627. E.ErrorCode := DosError;
  628. raise E;
  629. end;
  630. //TODO Better dos error codes
  631. if laststatuscode <> 0 then
  632. begin
  633. {MPW status might be 24 bits}
  634. Result := laststatuscode and $ffff;
  635. if Result = 0 then
  636. Result := 1;
  637. end
  638. else
  639. Result := 0;
  640. End;
  641. function ExecuteProcess (const Path: RawByteString;
  642. const ComLine: array of RawByteString;Flags:TExecuteFlags=[]): integer;
  643. var
  644. CommandLine: RawByteString;
  645. I: integer;
  646. begin
  647. Commandline := '';
  648. for I := 0 to High (ComLine) do
  649. if Pos (' ', ComLine [I]) <> 0 then
  650. CommandLine := CommandLine + ' ' + '"' + ToSingleByteFileSystemEncodedFileName(ComLine [I]) + '"'
  651. else
  652. CommandLine := CommandLine + ' ' + ToSingleByteFileSystemEncodedFileName(Comline [I]);
  653. ExecuteProcess := ExecuteProcess (Path, CommandLine);
  654. end;
  655. procedure Sleep(milliseconds: Cardinal);
  656. begin
  657. end;
  658. (*
  659. Function GetLastOSError : Integer;
  660. begin
  661. end;
  662. *)
  663. {****************************************************************************
  664. Initialization code
  665. ****************************************************************************}
  666. Initialization
  667. InitExceptions; { Initialize exceptions. OS independent }
  668. InitInternational; { Initialize internationalization settings }
  669. Finalization
  670. DoneExceptions;
  671. end.