fpredir.pas 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995
  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 : word;
  606. {$endif Windows}
  607. Begin
  608. RedirErrorOut:=0; RedirErrorIn:=0; RedirErrorError:=0;
  609. ExecuteResult:=0;
  610. IOStatus:=0;
  611. if RedirStdIn<>'' then
  612. ChangeRedirIn(RedirStdIn);
  613. if RedirStdOut<>'' then
  614. ChangeRedirOut(RedirStdOut,false);
  615. if RedirStdErr<>'stderr' then
  616. ChangeRedirError(RedirStdErr,false);
  617. DosExecute(ProgName,ComLine);
  618. RestoreRedirOut;
  619. RestoreRedirIn;
  620. RestoreRedirError;
  621. ExecuteRedir:=(IOStatus=0) and (RedirErrorOut=0) and
  622. (RedirErrorIn=0) and (RedirErrorError=0) and
  623. (ExecuteResult=0);
  624. {$ifdef Windows}
  625. // reenable mouse events
  626. GetConsoleMode(GetStdHandle(cardinal(Std_Input_Handle)), @mode);
  627. mode:=mode or ENABLE_MOUSE_INPUT;
  628. SetConsoleMode(GetStdHandle(cardinal(Std_Input_Handle)), mode);
  629. {$endif Windows}
  630. End;
  631. {............................................................................}
  632. procedure RedirDisableAll;
  633. begin
  634. If RedirChangedIn and not InRedirDisabled then
  635. DisableRedirIn;
  636. If RedirChangedOut and not OutRedirDisabled then
  637. DisableRedirOut;
  638. If RedirChangedError and not ErrorRedirDisabled then
  639. DisableRedirError;
  640. end;
  641. {............................................................................}
  642. procedure RedirEnableAll;
  643. begin
  644. If RedirChangedIn and InRedirDisabled then
  645. EnableRedirIn;
  646. If RedirChangedOut and OutRedirDisabled then
  647. EnableRedirOut;
  648. If RedirChangedError and ErrorRedirDisabled then
  649. EnableRedirError;
  650. end;
  651. procedure InitRedir;
  652. begin
  653. {$ifndef FPC}
  654. PrefSeg:=PrefixSeg;
  655. {$endif FPC}
  656. end;
  657. {$else not implemented}
  658. {*****************************************************************************
  659. Fake
  660. *****************************************************************************}
  661. {$IFDEF SHELL_IMPLEMENTED}
  662. {$I-}
  663. function FileExist(const FileName : PathStr) : Boolean;
  664. var
  665. f : file;
  666. Attr : word;
  667. begin
  668. Assign(f, FileName);
  669. GetFAttr(f, Attr);
  670. FileExist := DosError = 0;
  671. end;
  672. function CompleteDir(const Path: string): string;
  673. begin
  674. { keep c: untouched PM }
  675. if (Path<>'') and (Path[Length(Path)]<>DirSep) and
  676. (Path[Length(Path)]<>':') then
  677. CompleteDir:=Path+DirSep
  678. else
  679. CompleteDir:=Path;
  680. end;
  681. function LocateExeFile(var FileName:string): boolean;
  682. var
  683. dir,s,d,n,e : string;
  684. i : longint;
  685. begin
  686. LocateExeFile:=False;
  687. if FileExist(FileName) then
  688. begin
  689. LocateExeFile:=true;
  690. Exit;
  691. end;
  692. Fsplit(Filename,d,n,e);
  693. if (e='') and FileExist(FileName+exeext) then
  694. begin
  695. FileName:=FileName+exeext;
  696. LocateExeFile:=true;
  697. Exit;
  698. end;
  699. S:=GetEnv('PATH');
  700. While Length(S)>0 do
  701. begin
  702. i:=1;
  703. While (i<=Length(S)) and not (S[i] in ListSep) do
  704. Inc(i);
  705. Dir:=CompleteDir(Copy(S,1,i-1));
  706. if i<Length(S) then
  707. Delete(S,1,i)
  708. else
  709. S:='';
  710. if FileExist(Dir+FileName) then
  711. Begin
  712. FileName:=Dir+FileName;
  713. LocateExeFile:=true;
  714. Exit;
  715. End;
  716. end;
  717. end;
  718. function ExecuteRedir (Const ProgName, ComLine, RedirStdIn, RedirStdOut, RedirStdErr: String): boolean;
  719. var
  720. CmdLine2: string;
  721. begin
  722. CmdLine2 := ComLine;
  723. if RedirStdIn <> '' then CmdLine2 := CmdLine2 + ' < ' + RedirStdIn;
  724. if RedirStdOut <> '' then CmdLine2 := CmdLine2 + ' > ' + RedirStdOut;
  725. if RedirStdErr <> '' then
  726. begin
  727. if RedirStdErr = RedirStdOut
  728. then CmdLine2 := CmdLine2 + ' 2>&1'
  729. else CmdLine2 := CmdLine2 + ' 2> ' + RedirStdErr;
  730. end;
  731. DosExecute (ProgName, CmdLine2);
  732. ExecuteRedir := true;
  733. end;
  734. {$ELSE SHELL_IMPLEMENTED}
  735. function ExecuteRedir (Const ProgName, ComLine, RedirStdIn, RedirStdOut, RedirStdErr : String) : boolean;
  736. begin
  737. ExecuteRedir:=false;
  738. end;
  739. {$ENDIF SHELL_IMPLEMENTED}
  740. function ChangeRedirOut(Const Redir : String; AppendToFile : Boolean) : Boolean;
  741. begin
  742. ChangeRedirOut:=false;
  743. end;
  744. procedure RestoreRedirOut;
  745. begin
  746. end;
  747. procedure DisableRedirOut;
  748. begin
  749. end;
  750. procedure EnableRedirOut;
  751. begin
  752. end;
  753. function ChangeRedirIn(Const Redir : String) : Boolean;
  754. begin
  755. ChangeRedirIn:=false;
  756. end;
  757. procedure RestoreRedirIn;
  758. begin
  759. end;
  760. procedure DisableRedirIn;
  761. begin
  762. end;
  763. procedure EnableRedirIn;
  764. begin
  765. end;
  766. function ChangeRedirError(Const Redir : String; AppendToFile : Boolean) : Boolean;
  767. begin
  768. ChangeRedirError:=false;
  769. end;
  770. procedure RestoreRedirError;
  771. begin
  772. end;
  773. procedure DisableRedirError;
  774. begin
  775. end;
  776. procedure EnableRedirError;
  777. begin
  778. end;
  779. procedure RedirDisableAll;
  780. begin
  781. end;
  782. procedure RedirEnableAll;
  783. begin
  784. end;
  785. procedure InitRedir;
  786. begin
  787. end;
  788. {$endif not implemented}
  789. {............................................................................}
  790. procedure DosExecute(ProgName, ComLine : String);
  791. {$ifdef Windows}
  792. var
  793. StoreInherit : BOOL;
  794. {$endif Windows}
  795. Begin
  796. {$IfDef MsDos}
  797. SmallHeap;
  798. {$EndIf MsDos}
  799. SwapVectors;
  800. { Must use shell() for linux for the wildcard expansion (PFV) }
  801. {$ifdef UNIX}
  802. IOStatus:=0;
  803. ExecuteResult:=Shell(MaybeQuoted(FixPath(Progname))+' '+Comline);
  804. if ExecuteResult<0 then
  805. begin
  806. IOStatus:=(-ExecuteResult) and $7f;
  807. ExecuteResult:=((-ExecuteResult) and $ff00) shr 8;
  808. end;
  809. {$else}
  810. {$ifdef Windows}
  811. StoreInherit:=ExecInheritsHandles;
  812. ExecInheritsHandles:=true;
  813. {$endif Windows}
  814. DosError:=0;
  815. If UseComSpec then
  816. Dos.Exec (Getenv('COMSPEC'),'/C '+MaybeQuoted(FixPath(progname))+' '+Comline)
  817. else
  818. begin
  819. if LocateExeFile(progname) then
  820. Dos.Exec(ProgName,Comline)
  821. else
  822. DosError:=2;
  823. end;
  824. {$ifdef Windows}
  825. ExecInheritsHandles:=StoreInherit;
  826. {$endif Windows}
  827. IOStatus:=DosError;
  828. ExecuteResult:=DosExitCode;
  829. {$endif}
  830. SwapVectors;
  831. {$ifdef CPU86}
  832. { reset the FPU }
  833. {$asmmode att}
  834. asm
  835. fninit
  836. end;
  837. {$endif CPU86}
  838. {$IfDef MsDos}
  839. Fullheap;
  840. {$EndIf MsDos}
  841. End;
  842. {*****************************************************************************
  843. Initialize
  844. *****************************************************************************}
  845. initialization
  846. New(FIn); New(FOut); New(FErr);
  847. finalization
  848. Dispose(FIn); Dispose(FOut); Dispose(FErr);
  849. End.