fpredir.pas 23 KB

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