fpredir.pas 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999
  1. {
  2. This file is part of the Free Pascal Test Suite
  3. Copyright (c) 1999-2000 by Pierre Muller
  4. Unit to redirect output and error to files
  5. Adapted from code donated to public domain by Schwartz Gabriel 20/03/1993
  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 FpRedir;
  13. Interface
  14. {$R-}
  15. {$ifndef Linux}
  16. {$ifndef Unix}
  17. {$S-}
  18. {$endif}
  19. {$endif}
  20. {$ifdef TP}
  21. {$define implemented}
  22. {$endif TP}
  23. {$ifdef Go32v2}
  24. {$define implemented}
  25. {$endif}
  26. {$ifdef OS2}
  27. {$define shell_implemented}
  28. {$endif}
  29. {$ifdef Windows}
  30. {$define implemented}
  31. {$endif}
  32. {$ifdef linux}
  33. {$define implemented}
  34. {$endif}
  35. {$ifdef BSD}
  36. {$define implemented}
  37. {$endif}
  38. {$ifdef netwlibc}
  39. {$define implemented}
  40. {$endif}
  41. {$ifdef netware_clib}
  42. {$define implemented}
  43. {$endif}
  44. { be sure msdos is not set for FPC compiler }
  45. {$ifdef FPC}
  46. {$UnDef MsDos}
  47. {$endif FPC}
  48. Var
  49. IOStatus : Integer;
  50. RedirErrorOut,RedirErrorIn,
  51. RedirErrorError : Integer;
  52. ExecuteResult : Word;
  53. {------------------------------------------------------------------------------}
  54. procedure InitRedir;
  55. function ExecuteRedir (Const ProgName, ComLine, RedirStdIn, RedirStdOut, RedirStdErr : String) : boolean;
  56. procedure DosExecute(ProgName, ComLine : String);
  57. function ChangeRedirOut(Const Redir : String; AppendToFile : Boolean) : Boolean;
  58. procedure RestoreRedirOut;
  59. procedure DisableRedirOut;
  60. procedure EnableRedirOut;
  61. function ChangeRedirIn(Const Redir : String) : Boolean;
  62. procedure RestoreRedirIn;
  63. procedure DisableRedirIn;
  64. procedure EnableRedirIn;
  65. function ChangeRedirError(Const Redir : String; AppendToFile : Boolean) : Boolean;
  66. procedure RestoreRedirError;
  67. procedure DisableRedirError;
  68. procedure EnableRedirError;
  69. procedure RedirDisableAll;
  70. procedure RedirEnableAll;
  71. { unused in UNIX }
  72. const
  73. UseComSpec : boolean = true;
  74. Implementation
  75. Uses
  76. {$ifdef go32v2}
  77. go32,
  78. {$endif go32v2}
  79. {$ifdef netwlibc}
  80. Libc,
  81. {$endif netwlibc}
  82. {$ifdef netware_clib}
  83. nwserv,
  84. {$endif netware_clib}
  85. {$ifdef Windows}
  86. windows,
  87. {$endif Windows}
  88. {$ifdef unix}
  89. {$ifdef ver1_0}
  90. linux,
  91. {$else}
  92. baseunix,
  93. unix,
  94. {$endif}
  95. {$endif unix}
  96. dos;
  97. Const
  98. {$ifdef UNIX}
  99. DirSep='/';
  100. listsep = [';',':'];
  101. exeext = '';
  102. {$else UNIX}
  103. DirSep='\';
  104. listsep = [';'];
  105. exeext = '.exe';
  106. {$endif UNIX}
  107. var
  108. FIN,FOUT,FERR : ^File;
  109. RedirChangedOut,
  110. RedirChangedIn : Boolean;
  111. RedirChangedError : Boolean;
  112. InRedirDisabled,OutRedirDisabled,ErrorRedirDisabled : Boolean;
  113. {*****************************************************************************
  114. Helpers
  115. *****************************************************************************}
  116. function FixPath(const s:string):string;
  117. var
  118. i : longint;
  119. begin
  120. { Fix separator }
  121. for i:=1 to length(s) do
  122. if s[i] in ['/','\'] then
  123. fixpath[i]:=DirSep
  124. else
  125. fixpath[i]:=s[i];
  126. fixpath[0]:=s[0];
  127. end;
  128. function maybequoted(const s:string):string;
  129. var
  130. s1 : string;
  131. i : integer;
  132. quoted : boolean;
  133. begin
  134. quoted:=false;
  135. s1:='"';
  136. for i:=1 to length(s) do
  137. begin
  138. case s[i] of
  139. '"' :
  140. begin
  141. quoted:=true;
  142. s1:=s1+'\"';
  143. end;
  144. ' ',
  145. #128..#255 :
  146. begin
  147. quoted:=true;
  148. s1:=s1+s[i];
  149. end;
  150. else
  151. s1:=s1+s[i];
  152. end;
  153. end;
  154. if quoted then
  155. maybequoted:=s1+'"'
  156. else
  157. maybequoted:=s;
  158. end;
  159. {*****************************************************************************
  160. Dos
  161. *****************************************************************************}
  162. {$ifdef implemented}
  163. {$ifdef TP}
  164. {$ifndef Windows}
  165. const
  166. UnusedHandle = -1;
  167. StdInputHandle = 0;
  168. StdOutputHandle = 1;
  169. StdErrorHandle = 2;
  170. {$endif Windows}
  171. Type
  172. PtrRec = packed record
  173. Ofs, Seg : Word;
  174. end;
  175. PHandles = ^THandles;
  176. THandles = Array [Byte] of Byte;
  177. PWord = ^Word;
  178. Var
  179. MinBlockSize : Word;
  180. MyBlockSize : Word;
  181. Handles : PHandles;
  182. PrefSeg : Word;
  183. OldHandleOut,OldHandleIn,OldHandleError : Byte;
  184. {$endif TP}
  185. var
  186. TempHOut, TempHIn,TempHError : longint;
  187. {
  188. For linux the following functions exist
  189. Function fpdup(oldfile:longint;var newfile:longint):Boolean;
  190. Function fpdup2(oldfile,newfile:longint):Boolean;
  191. Function fpClose(fd:longint):boolean;
  192. }
  193. {$ifdef go32v2}
  194. function dup(fh : longint;var nh : longint) : boolean;
  195. var
  196. Regs : Registers;
  197. begin
  198. Regs.ah:=$45;
  199. Regs.bx:=fh;
  200. MsDos (Regs);
  201. dup:=true;
  202. If (Regs.Flags and fCarry)=0 then
  203. nh:=Regs.Ax
  204. else
  205. dup:=false;
  206. end;
  207. function dup2(fh,nh : longint) : boolean;
  208. var
  209. Regs : Registers;
  210. begin
  211. dup2:=true;
  212. If fh=nh then
  213. exit;
  214. Regs.ah:=$46;
  215. Regs.bx:=fh;
  216. Regs.cx:=nh;
  217. MsDos (Regs);
  218. If (Regs.Flags and fCarry)<>0 then
  219. dup2:=false;
  220. end;
  221. function fpdup(fh:longint):longint;
  222. begin
  223. if not dup(fh,fpdup) then
  224. fpdup:=-1;
  225. end;
  226. function fpdup2(fh,nh:longint):longint;
  227. begin
  228. if dup2(fh,nh) then
  229. fpdup2:=0
  230. else
  231. fpdup2:=-1;
  232. end;
  233. function fpclose(Handle : Longint) : boolean;
  234. var Regs: registers;
  235. begin
  236. Regs.Eax := $3e00;
  237. Regs.Ebx := Handle;
  238. MsDos(Regs);
  239. fpclose:=(Regs.Flags and fCarry)=0;
  240. end;
  241. {$endif def go32v2}
  242. {$ifdef Windows}
  243. Function fpclose(Handle : Longint) : boolean;
  244. begin
  245. { Do we need this ?? }
  246. fpclose:=true;
  247. end;
  248. {$endif}
  249. {$ifdef os2}
  250. Function fpclose (Handle : Longint) : boolean;
  251. begin
  252. { Do we need this ?? }
  253. fpclose:=true;
  254. end;
  255. {$endif}
  256. {$ifdef TP}
  257. Function {$ifdef ver1_0}fdclose{$else}fpclose{$endif} (Handle : Longint) : boolean;
  258. begin
  259. { if executed as under GO32 this hangs the DOS-prompt }
  260. fpclose:=true;
  261. end;
  262. {$endif}
  263. {$I-}
  264. function FileExist(const FileName : PathStr) : Boolean;
  265. var
  266. f : file;
  267. Attr : word;
  268. begin
  269. Assign(f, FileName);
  270. GetFAttr(f, Attr);
  271. FileExist := DosError = 0;
  272. end;
  273. function CompleteDir(const Path: string): string;
  274. begin
  275. { keep c: untouched PM }
  276. if (Path<>'') and (Path[Length(Path)]<>DirSep) and
  277. (Path[Length(Path)]<>':') then
  278. CompleteDir:=Path+DirSep
  279. else
  280. CompleteDir:=Path;
  281. end;
  282. function LocateExeFile(var FileName:string): boolean;
  283. var
  284. dir,s,d,n,e : string;
  285. i : longint;
  286. begin
  287. LocateExeFile:=False;
  288. if FileExist(FileName) then
  289. begin
  290. LocateExeFile:=true;
  291. Exit;
  292. end;
  293. Fsplit(Filename,d,n,e);
  294. if (e='') and FileExist(FileName+exeext) then
  295. begin
  296. FileName:=FileName+exeext;
  297. LocateExeFile:=true;
  298. Exit;
  299. end;
  300. S:=GetEnv('PATH');
  301. While Length(S)>0 do
  302. begin
  303. i:=1;
  304. While (i<=Length(S)) and not (S[i] in ListSep) do
  305. Inc(i);
  306. Dir:=CompleteDir(Copy(S,1,i-1));
  307. if i<Length(S) then
  308. Delete(S,1,i)
  309. else
  310. S:='';
  311. if FileExist(Dir+FileName) then
  312. Begin
  313. FileName:=Dir+FileName;
  314. LocateExeFile:=true;
  315. Exit;
  316. End;
  317. end;
  318. end;
  319. {............................................................................}
  320. function ChangeRedirOut(Const Redir : String; AppendToFile : Boolean) : Boolean;
  321. begin
  322. ChangeRedirOut:=False;
  323. If Redir = '' then Exit;
  324. Assign (FOUT^, Redir);
  325. If AppendToFile and FileExist(Redir) then
  326. Begin
  327. Reset(FOUT^,1);
  328. Seek(FOUT^,FileSize(FOUT^));
  329. End else Rewrite (FOUT^);
  330. RedirErrorOut:=IOResult;
  331. IOStatus:=RedirErrorOut;
  332. If IOStatus <> 0 then Exit;
  333. {$ifndef FPC}
  334. Handles:=Ptr (prefseg, PWord (Ptr (prefseg, $34))^);
  335. OldHandleOut:=Handles^[StdOutputHandle];
  336. Handles^[StdOutputHandle]:=Handles^[FileRec (FOUT^).Handle];
  337. ChangeRedirOut:=True;
  338. OutRedirDisabled:=False;
  339. {$else}
  340. {$ifdef Windows}
  341. if SetStdHandle(Std_Output_Handle,FileRec(FOUT^).Handle) then
  342. {$else not Windows}
  343. TempHOut:=fpdup(StdOutputHandle);
  344. fpdup2(FileRec(FOUT^).Handle,StdOutputHandle);
  345. if (TempHOut<>UnusedHandle) and
  346. (StdOutputHandle<>UnusedHandle) then
  347. {$endif not Windows}
  348. begin
  349. ChangeRedirOut:=True;
  350. OutRedirDisabled:=False;
  351. end;
  352. {$endif def FPC}
  353. RedirChangedOut:=True;
  354. end;
  355. function ChangeRedirIn(Const Redir : String) : Boolean;
  356. begin
  357. ChangeRedirIn:=False;
  358. If Redir = '' then Exit;
  359. Assign (FIN^, Redir);
  360. Reset(FIN^,1);
  361. RedirErrorIn:=IOResult;
  362. IOStatus:=RedirErrorIn;
  363. If IOStatus <> 0 then Exit;
  364. {$ifndef FPC}
  365. Handles:=Ptr (prefseg, PWord (Ptr (prefseg, $34))^);
  366. OldHandleIn:=Handles^[StdInputHandle];
  367. Handles^[StdInputHandle]:=Handles^[FileRec (FIN^).Handle];
  368. ChangeRedirIn:=True;
  369. InRedirDisabled:=False;
  370. {$else}
  371. {$ifdef Windows}
  372. if SetStdHandle(Std_Input_Handle,FileRec(FIN^).Handle) then
  373. {$else not Windows}
  374. TempHIn:=fpdup(StdInputHandle);
  375. fpdup2(FileRec(FIn^).Handle,StdInputHandle);
  376. if (TempHIn<>UnusedHandle) and
  377. (StdInputHandle<>UnusedHandle) then
  378. {$endif not Windows}
  379. begin
  380. ChangeRedirIn:=True;
  381. InRedirDisabled:=False;
  382. end;
  383. {$endif def FPC}
  384. RedirChangedIn:=True;
  385. end;
  386. function ChangeRedirError(Const Redir : String; AppendToFile : Boolean) : Boolean;
  387. begin
  388. ChangeRedirError:=False;
  389. If Redir = '' then Exit;
  390. Assign (FERR^, Redir);
  391. If AppendToFile and FileExist(Redir) then
  392. Begin
  393. Reset(FERR^,1);
  394. Seek(FERR^,FileSize(FERR^));
  395. End else Rewrite (FERR^);
  396. RedirErrorError:=IOResult;
  397. IOStatus:=RedirErrorError;
  398. If IOStatus <> 0 then Exit;
  399. {$ifndef FPC}
  400. Handles:=Ptr (prefseg, PWord (Ptr (prefseg, $34))^);
  401. OldHandleError:=Handles^[StdErrorHandle];
  402. Handles^[StdErrorHandle]:=Handles^[FileRec (FERR^).Handle];
  403. ChangeRedirError:=True;
  404. ErrorRedirDisabled:=False;
  405. {$else}
  406. {$ifdef Windows}
  407. if SetStdHandle(Std_Error_Handle,FileRec(FERR^).Handle) then
  408. {$else not Windows}
  409. TempHError:=fpdup(StdErrorHandle);
  410. fpdup2(FileRec(FERR^).Handle,StdErrorHandle);
  411. if (TempHError<>UnusedHandle) and
  412. (StdErrorHandle<>UnusedHandle) then
  413. {$endif not Windows}
  414. begin
  415. ChangeRedirError:=True;
  416. ErrorRedirDisabled:=False;
  417. end;
  418. {$endif}
  419. RedirChangedError:=True;
  420. end;
  421. {$IfDef MsDos}
  422. {Set HeapEnd Pointer to Current Used Heapsize}
  423. Procedure SmallHeap;assembler;
  424. asm
  425. mov bx,word ptr HeapPtr
  426. shr bx,4
  427. inc bx
  428. add bx,word ptr HeapPtr+2
  429. mov ax,PrefixSeg
  430. sub bx,ax
  431. mov es,ax
  432. mov ah,4ah
  433. int 21h
  434. end;
  435. {Set HeapEnd Pointer to Full Heapsize}
  436. Procedure FullHeap;assembler;
  437. asm
  438. mov bx,word ptr HeapEnd
  439. shr bx,4
  440. inc bx
  441. add bx,word ptr HeapEnd+2
  442. mov ax,PrefixSeg
  443. sub bx,ax
  444. mov es,ax
  445. mov ah,4ah
  446. int 21h
  447. end;
  448. {$EndIf MsDos}
  449. procedure RestoreRedirOut;
  450. begin
  451. If not RedirChangedOut then Exit;
  452. {$ifndef FPC}
  453. Handles^[StdOutputHandle]:=OldHandleOut;
  454. OldHandleOut:=StdOutputHandle;
  455. {$else}
  456. {$ifdef Windows}
  457. SetStdHandle(Std_Output_Handle,StdOutputHandle);
  458. {$else not Windows}
  459. fpdup2(TempHOut,StdOutputHandle);
  460. {$endif not Windows}
  461. {$endif FPC}
  462. Close (FOUT^);
  463. fpclose(TempHOut);
  464. RedirChangedOut:=false;
  465. end;
  466. {............................................................................}
  467. procedure RestoreRedirIn;
  468. begin
  469. If not RedirChangedIn then Exit;
  470. {$ifndef FPC}
  471. Handles^[StdInputHandle]:=OldHandleIn;
  472. OldHandleIn:=StdInputHandle;
  473. {$else}
  474. {$ifdef Windows}
  475. SetStdHandle(Std_Input_Handle,StdInputHandle);
  476. {$else not Windows}
  477. fpdup2(TempHIn,StdInputHandle);
  478. {$endif not Windows}
  479. {$endif}
  480. Close (FIn^);
  481. fpclose(TempHIn);
  482. RedirChangedIn:=false;
  483. end;
  484. {............................................................................}
  485. procedure DisableRedirIn;
  486. begin
  487. If not RedirChangedIn then Exit;
  488. If InRedirDisabled then Exit;
  489. {$ifndef FPC}
  490. Handles^[StdInputHandle]:=OldHandleIn;
  491. {$else}
  492. {$ifdef Windows}
  493. SetStdHandle(Std_Input_Handle,StdInputHandle);
  494. {$else not Windows}
  495. fpdup2(TempHIn,StdInputHandle);
  496. {$endif not Windows}
  497. {$endif}
  498. InRedirDisabled:=True;
  499. end;
  500. {............................................................................}
  501. procedure EnableRedirIn;
  502. begin
  503. If not RedirChangedIn then Exit;
  504. If not InRedirDisabled then Exit;
  505. {$ifndef FPC}
  506. Handles:=Ptr (prefseg, PWord (Ptr (prefseg, $34))^);
  507. Handles^[StdInputHandle]:=Handles^[FileRec (FIn^).Handle];
  508. {$else}
  509. {$ifdef Windows}
  510. SetStdHandle(Std_Input_Handle,FileRec(FIn^).Handle);
  511. {$else not Windows}
  512. fpdup2(FileRec(FIn^).Handle,StdInputHandle);
  513. {$endif not Windows}
  514. {$endif}
  515. InRedirDisabled:=False;
  516. end;
  517. {............................................................................}
  518. procedure DisableRedirOut;
  519. begin
  520. If not RedirChangedOut then Exit;
  521. If OutRedirDisabled then Exit;
  522. {$ifndef FPC}
  523. Handles^[StdOutputHandle]:=OldHandleOut;
  524. {$else}
  525. {$ifdef Windows}
  526. SetStdHandle(Std_Output_Handle,StdOutputHandle);
  527. {$else not Windows}
  528. fpdup2(TempHOut,StdOutputHandle);
  529. {$endif not Windows}
  530. {$endif}
  531. OutRedirDisabled:=True;
  532. end;
  533. {............................................................................}
  534. procedure EnableRedirOut;
  535. begin
  536. If not RedirChangedOut then Exit;
  537. If not OutRedirDisabled then Exit;
  538. {$ifndef FPC}
  539. Handles:=Ptr (prefseg, PWord (Ptr (prefseg, $34))^);
  540. Handles^[StdOutputHandle]:=Handles^[FileRec (FOut^).Handle];
  541. {$else}
  542. {$ifdef Windows}
  543. SetStdHandle(Std_Output_Handle,FileRec(FOut^).Handle);
  544. {$else not Windows}
  545. fpdup2(FileRec(FOut^).Handle,StdOutputHandle);
  546. {$endif not Windows}
  547. {$endif}
  548. OutRedirDisabled:=False;
  549. end;
  550. {............................................................................}
  551. procedure RestoreRedirError;
  552. begin
  553. If not RedirChangedError then Exit;
  554. {$ifndef FPC}
  555. Handles^[StdErrorHandle]:=OldHandleError;
  556. OldHandleError:=StdErrorHandle;
  557. {$else}
  558. {$ifdef Windows}
  559. SetStdHandle(Std_Error_Handle,StdErrorHandle);
  560. {$else not Windows}
  561. fpdup2(TempHError,StdErrorHandle);
  562. {$endif not Windows}
  563. {$endif}
  564. Close (FERR^);
  565. fpclose(TempHError);
  566. RedirChangedError:=false;
  567. end;
  568. {............................................................................}
  569. procedure DisableRedirError;
  570. begin
  571. If not RedirChangedError then Exit;
  572. If ErrorRedirDisabled then Exit;
  573. {$ifndef FPC}
  574. Handles^[StdErrorHandle]:=OldHandleError;
  575. {$else}
  576. {$ifdef Windows}
  577. SetStdHandle(Std_Error_Handle,StdErrorHandle);
  578. {$else not Windows}
  579. {$ifdef ver1_0}dup2{$else}fpdup2{$endif}(TempHError,StdErrorHandle);
  580. {$endif not Windows}
  581. {$endif}
  582. ErrorRedirDisabled:=True;
  583. end;
  584. {............................................................................}
  585. procedure EnableRedirError;
  586. begin
  587. If not RedirChangedError then Exit;
  588. If not ErrorRedirDisabled then Exit;
  589. {$ifndef FPC}
  590. Handles:=Ptr (prefseg, PWord (Ptr (prefseg, $34))^);
  591. Handles^[StdErrorHandle]:=Handles^[FileRec (FErr^).Handle];
  592. {$else}
  593. {$ifdef Windows}
  594. SetStdHandle(Std_Error_Handle,FileRec(FErr^).Handle);
  595. {$else not Windows}
  596. {$ifdef ver1_0}dup2{$else}fpdup2{$endif}(FileRec(FERR^).Handle,StdErrorHandle);
  597. {$endif not Windows}
  598. {$endif}
  599. ErrorRedirDisabled:=False;
  600. end;
  601. {............................................................................}
  602. function ExecuteRedir (Const ProgName, ComLine, RedirStdIn, RedirStdOut, RedirStdErr : String) : boolean;
  603. {$ifdef Windows}
  604. var
  605. mode,modebefore : word;
  606. {$endif Windows}
  607. Begin
  608. {$ifdef Windows}
  609. GetConsoleMode(GetStdHandle(cardinal(Std_Input_Handle)), @modebefore);
  610. {$endif Windows}
  611. RedirErrorOut:=0; RedirErrorIn:=0; RedirErrorError:=0;
  612. ExecuteResult:=0;
  613. IOStatus:=0;
  614. if RedirStdIn<>'' then
  615. ChangeRedirIn(RedirStdIn);
  616. if RedirStdOut<>'' then
  617. ChangeRedirOut(RedirStdOut,false);
  618. if RedirStdErr<>'stderr' then
  619. ChangeRedirError(RedirStdErr,false);
  620. DosExecute(ProgName,ComLine);
  621. RestoreRedirOut;
  622. RestoreRedirIn;
  623. RestoreRedirError;
  624. ExecuteRedir:=(IOStatus=0) and (RedirErrorOut=0) and
  625. (RedirErrorIn=0) and (RedirErrorError=0) and
  626. (ExecuteResult=0);
  627. {$ifdef Windows}
  628. // restore previous mode
  629. GetConsoleMode(GetStdHandle(cardinal(Std_Input_Handle)), @mode);
  630. //mode:=mode or ENABLE_MOUSE_INPUT;
  631. SetConsoleMode(GetStdHandle(cardinal(Std_Input_Handle)), modebefore);
  632. {$endif Windows}
  633. End;
  634. {............................................................................}
  635. procedure RedirDisableAll;
  636. begin
  637. If RedirChangedIn and not InRedirDisabled then
  638. DisableRedirIn;
  639. If RedirChangedOut and not OutRedirDisabled then
  640. DisableRedirOut;
  641. If RedirChangedError and not ErrorRedirDisabled then
  642. DisableRedirError;
  643. end;
  644. {............................................................................}
  645. procedure RedirEnableAll;
  646. begin
  647. If RedirChangedIn and InRedirDisabled then
  648. EnableRedirIn;
  649. If RedirChangedOut and OutRedirDisabled then
  650. EnableRedirOut;
  651. If RedirChangedError and ErrorRedirDisabled then
  652. EnableRedirError;
  653. end;
  654. procedure InitRedir;
  655. begin
  656. {$ifndef FPC}
  657. PrefSeg:=PrefixSeg;
  658. {$endif FPC}
  659. end;
  660. {$else not implemented}
  661. {*****************************************************************************
  662. Fake
  663. *****************************************************************************}
  664. {$IFDEF SHELL_IMPLEMENTED}
  665. {$I-}
  666. function FileExist(const FileName : PathStr) : Boolean;
  667. var
  668. f : file;
  669. Attr : word;
  670. begin
  671. Assign(f, FileName);
  672. GetFAttr(f, Attr);
  673. FileExist := DosError = 0;
  674. end;
  675. function CompleteDir(const Path: string): string;
  676. begin
  677. { keep c: untouched PM }
  678. if (Path<>'') and (Path[Length(Path)]<>DirSep) and
  679. (Path[Length(Path)]<>':') then
  680. CompleteDir:=Path+DirSep
  681. else
  682. CompleteDir:=Path;
  683. end;
  684. function LocateExeFile(var FileName:string): boolean;
  685. var
  686. dir,s,d,n,e : string;
  687. i : longint;
  688. begin
  689. LocateExeFile:=False;
  690. if FileExist(FileName) then
  691. begin
  692. LocateExeFile:=true;
  693. Exit;
  694. end;
  695. Fsplit(Filename,d,n,e);
  696. if (e='') and FileExist(FileName+exeext) then
  697. begin
  698. FileName:=FileName+exeext;
  699. LocateExeFile:=true;
  700. Exit;
  701. end;
  702. S:=GetEnv('PATH');
  703. While Length(S)>0 do
  704. begin
  705. i:=1;
  706. While (i<=Length(S)) and not (S[i] in ListSep) do
  707. Inc(i);
  708. Dir:=CompleteDir(Copy(S,1,i-1));
  709. if i<Length(S) then
  710. Delete(S,1,i)
  711. else
  712. S:='';
  713. if FileExist(Dir+FileName) then
  714. Begin
  715. FileName:=Dir+FileName;
  716. LocateExeFile:=true;
  717. Exit;
  718. End;
  719. end;
  720. end;
  721. function ExecuteRedir (Const ProgName, ComLine, RedirStdIn, RedirStdOut, RedirStdErr: String): boolean;
  722. var
  723. CmdLine2: string;
  724. begin
  725. CmdLine2 := ComLine;
  726. if RedirStdIn <> '' then CmdLine2 := CmdLine2 + ' < ' + RedirStdIn;
  727. if RedirStdOut <> '' then CmdLine2 := CmdLine2 + ' > ' + RedirStdOut;
  728. if RedirStdErr <> '' then
  729. begin
  730. if RedirStdErr = RedirStdOut
  731. then CmdLine2 := CmdLine2 + ' 2>&1'
  732. else CmdLine2 := CmdLine2 + ' 2> ' + RedirStdErr;
  733. end;
  734. DosExecute (ProgName, CmdLine2);
  735. ExecuteRedir := true;
  736. end;
  737. {$ELSE SHELL_IMPLEMENTED}
  738. function ExecuteRedir (Const ProgName, ComLine, RedirStdIn, RedirStdOut, RedirStdErr : String) : boolean;
  739. begin
  740. ExecuteRedir:=false;
  741. end;
  742. {$ENDIF SHELL_IMPLEMENTED}
  743. function ChangeRedirOut(Const Redir : String; AppendToFile : Boolean) : Boolean;
  744. begin
  745. ChangeRedirOut:=false;
  746. end;
  747. procedure RestoreRedirOut;
  748. begin
  749. end;
  750. procedure DisableRedirOut;
  751. begin
  752. end;
  753. procedure EnableRedirOut;
  754. begin
  755. end;
  756. function ChangeRedirIn(Const Redir : String) : Boolean;
  757. begin
  758. ChangeRedirIn:=false;
  759. end;
  760. procedure RestoreRedirIn;
  761. begin
  762. end;
  763. procedure DisableRedirIn;
  764. begin
  765. end;
  766. procedure EnableRedirIn;
  767. begin
  768. end;
  769. function ChangeRedirError(Const Redir : String; AppendToFile : Boolean) : Boolean;
  770. begin
  771. ChangeRedirError:=false;
  772. end;
  773. procedure RestoreRedirError;
  774. begin
  775. end;
  776. procedure DisableRedirError;
  777. begin
  778. end;
  779. procedure EnableRedirError;
  780. begin
  781. end;
  782. procedure RedirDisableAll;
  783. begin
  784. end;
  785. procedure RedirEnableAll;
  786. begin
  787. end;
  788. procedure InitRedir;
  789. begin
  790. end;
  791. {$endif not implemented}
  792. {............................................................................}
  793. procedure DosExecute(ProgName, ComLine : String);
  794. {$ifdef Windows}
  795. var
  796. StoreInherit : BOOL;
  797. {$endif Windows}
  798. Begin
  799. {$IfDef MsDos}
  800. SmallHeap;
  801. {$EndIf MsDos}
  802. SwapVectors;
  803. {$ifdef UNIX}
  804. IOStatus:=0;
  805. {We need to use fpsystem to get wildcard expansion and avoid being
  806. interrupted by ctrl+c (SIGINT).};
  807. ExecuteResult:=fpsystem(MaybeQuoted(FixPath(Progname))+' '+Comline);
  808. if ExecuteResult<0 then
  809. begin
  810. IOStatus:=(-ExecuteResult) and $7f;
  811. ExecuteResult:=((-ExecuteResult) and $ff00) shr 8;
  812. end;
  813. {$else}
  814. {$ifdef Windows}
  815. StoreInherit:=ExecInheritsHandles;
  816. ExecInheritsHandles:=true;
  817. {$endif Windows}
  818. DosError:=0;
  819. If UseComSpec then
  820. Dos.Exec (Getenv('COMSPEC'),'/C '+MaybeQuoted(FixPath(progname))+' '+Comline)
  821. else
  822. begin
  823. if LocateExeFile(progname) then
  824. Dos.Exec(ProgName,Comline)
  825. else
  826. DosError:=2;
  827. end;
  828. {$ifdef Windows}
  829. ExecInheritsHandles:=StoreInherit;
  830. {$endif Windows}
  831. IOStatus:=DosError;
  832. ExecuteResult:=DosExitCode;
  833. {$endif}
  834. SwapVectors;
  835. {$ifdef CPU86}
  836. { reset the FPU }
  837. {$asmmode att}
  838. asm
  839. fninit
  840. end;
  841. {$endif CPU86}
  842. {$IfDef MsDos}
  843. Fullheap;
  844. {$EndIf MsDos}
  845. End;
  846. {*****************************************************************************
  847. Initialize
  848. *****************************************************************************}
  849. initialization
  850. New(FIn); New(FOut); New(FErr);
  851. finalization
  852. Dispose(FIn); Dispose(FOut); Dispose(FErr);
  853. End.