fpredir.pas 23 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022
  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. {$ifndef ver1_0}
  222. function fpdup(fh:longint):longint;
  223. begin
  224. if not dup(fh,fpdup) then
  225. fpdup:=-1;
  226. end;
  227. function fpdup2(fh,nh:longint):longint;
  228. begin
  229. if dup2(fh,nh) then
  230. fpdup2:=0
  231. else
  232. fpdup2:=-1;
  233. end;
  234. {$endif ver1_0}
  235. Function {$ifdef ver1_0}fdclose{$else}fpclose{$endif} (Handle : Longint) : boolean;
  236. var Regs: registers;
  237. begin
  238. Regs.Eax := $3e00;
  239. Regs.Ebx := Handle;
  240. MsDos(Regs);
  241. {$ifdef ver1_0}fdclose{$else}fpclose{$endif}:=(Regs.Flags and fCarry)=0;
  242. end;
  243. {$endif def go32v2}
  244. {$ifdef Windows}
  245. Function {$ifdef ver1_0}fdclose{$else}fpclose{$endif} (Handle : Longint) : boolean;
  246. begin
  247. { Do we need this ?? }
  248. {$ifdef ver1_0}fdclose{$else}fpclose{$endif}:=true;
  249. end;
  250. {$endif}
  251. {$ifdef os2}
  252. Function {$ifdef ver1_0}fdclose{$else}fpclose{$endif} (Handle : Longint) : boolean;
  253. begin
  254. { Do we need this ?? }
  255. {$ifdef ver1_0}fdclose{$else}fpclose{$endif}:=true;
  256. end;
  257. {$endif}
  258. {$ifdef TP}
  259. Function {$ifdef ver1_0}fdclose{$else}fpclose{$endif} (Handle : Longint) : boolean;
  260. begin
  261. { if executed as under GO32 this hangs the DOS-prompt }
  262. {$ifdef ver1_0}fdclose{$else}fpclose{$endif}:=true;
  263. end;
  264. {$endif}
  265. {$I-}
  266. function FileExist(const FileName : PathStr) : Boolean;
  267. var
  268. f : file;
  269. Attr : word;
  270. begin
  271. Assign(f, FileName);
  272. GetFAttr(f, Attr);
  273. FileExist := DosError = 0;
  274. end;
  275. function CompleteDir(const Path: string): string;
  276. begin
  277. { keep c: untouched PM }
  278. if (Path<>'') and (Path[Length(Path)]<>DirSep) and
  279. (Path[Length(Path)]<>':') then
  280. CompleteDir:=Path+DirSep
  281. else
  282. CompleteDir:=Path;
  283. end;
  284. function LocateExeFile(var FileName:string): boolean;
  285. var
  286. dir,s,d,n,e : string;
  287. i : longint;
  288. begin
  289. LocateExeFile:=False;
  290. if FileExist(FileName) then
  291. begin
  292. LocateExeFile:=true;
  293. Exit;
  294. end;
  295. Fsplit(Filename,d,n,e);
  296. if (e='') and FileExist(FileName+exeext) then
  297. begin
  298. FileName:=FileName+exeext;
  299. LocateExeFile:=true;
  300. Exit;
  301. end;
  302. S:=GetEnv('PATH');
  303. While Length(S)>0 do
  304. begin
  305. i:=1;
  306. While (i<=Length(S)) and not (S[i] in ListSep) do
  307. Inc(i);
  308. Dir:=CompleteDir(Copy(S,1,i-1));
  309. if i<Length(S) then
  310. Delete(S,1,i)
  311. else
  312. S:='';
  313. if FileExist(Dir+FileName) then
  314. Begin
  315. FileName:=Dir+FileName;
  316. LocateExeFile:=true;
  317. Exit;
  318. End;
  319. end;
  320. end;
  321. {............................................................................}
  322. function ChangeRedirOut(Const Redir : String; AppendToFile : Boolean) : Boolean;
  323. begin
  324. ChangeRedirOut:=False;
  325. If Redir = '' then Exit;
  326. Assign (FOUT^, Redir);
  327. If AppendToFile and FileExist(Redir) then
  328. Begin
  329. Reset(FOUT^,1);
  330. Seek(FOUT^,FileSize(FOUT^));
  331. End else Rewrite (FOUT^);
  332. RedirErrorOut:=IOResult;
  333. IOStatus:=RedirErrorOut;
  334. If IOStatus <> 0 then Exit;
  335. {$ifndef FPC}
  336. Handles:=Ptr (prefseg, PWord (Ptr (prefseg, $34))^);
  337. OldHandleOut:=Handles^[StdOutputHandle];
  338. Handles^[StdOutputHandle]:=Handles^[FileRec (FOUT^).Handle];
  339. ChangeRedirOut:=True;
  340. OutRedirDisabled:=False;
  341. {$else}
  342. {$ifdef Windows}
  343. if SetStdHandle(Std_Output_Handle,FileRec(FOUT^).Handle) then
  344. {$else not Windows}
  345. {$ifdef ver1_0}
  346. dup(StdOutputHandle,TempHOut);
  347. dup2(FileRec(FOUT^).Handle,StdOutputHandle);
  348. {$else}
  349. TempHOut:=fpdup(StdOutputHandle);
  350. fpdup2(FileRec(FOUT^).Handle,StdOutputHandle);
  351. {$endif}
  352. if (TempHOut<>UnusedHandle) and
  353. (StdOutputHandle<>UnusedHandle) then
  354. {$endif not Windows}
  355. begin
  356. ChangeRedirOut:=True;
  357. OutRedirDisabled:=False;
  358. end;
  359. {$endif def FPC}
  360. RedirChangedOut:=True;
  361. end;
  362. function ChangeRedirIn(Const Redir : String) : Boolean;
  363. begin
  364. ChangeRedirIn:=False;
  365. If Redir = '' then Exit;
  366. Assign (FIN^, Redir);
  367. Reset(FIN^,1);
  368. RedirErrorIn:=IOResult;
  369. IOStatus:=RedirErrorIn;
  370. If IOStatus <> 0 then Exit;
  371. {$ifndef FPC}
  372. Handles:=Ptr (prefseg, PWord (Ptr (prefseg, $34))^);
  373. OldHandleIn:=Handles^[StdInputHandle];
  374. Handles^[StdInputHandle]:=Handles^[FileRec (FIN^).Handle];
  375. ChangeRedirIn:=True;
  376. InRedirDisabled:=False;
  377. {$else}
  378. {$ifdef Windows}
  379. if SetStdHandle(Std_Input_Handle,FileRec(FIN^).Handle) then
  380. {$else not Windows}
  381. {$ifdef ver1_0}
  382. dup(StdInputHandle,TempHIn);
  383. dup2(FileRec(FIn^).Handle,StdInputHandle);
  384. {$else}
  385. TempHIn:=fpdup(StdInputHandle);
  386. fpdup2(FileRec(FIn^).Handle,StdInputHandle);
  387. {$endif}
  388. if (TempHIn<>UnusedHandle) and
  389. (StdInputHandle<>UnusedHandle) then
  390. {$endif not Windows}
  391. begin
  392. ChangeRedirIn:=True;
  393. InRedirDisabled:=False;
  394. end;
  395. {$endif def FPC}
  396. RedirChangedIn:=True;
  397. end;
  398. function ChangeRedirError(Const Redir : String; AppendToFile : Boolean) : Boolean;
  399. begin
  400. ChangeRedirError:=False;
  401. If Redir = '' then Exit;
  402. Assign (FERR^, Redir);
  403. If AppendToFile and FileExist(Redir) then
  404. Begin
  405. Reset(FERR^,1);
  406. Seek(FERR^,FileSize(FERR^));
  407. End else Rewrite (FERR^);
  408. RedirErrorError:=IOResult;
  409. IOStatus:=RedirErrorError;
  410. If IOStatus <> 0 then Exit;
  411. {$ifndef FPC}
  412. Handles:=Ptr (prefseg, PWord (Ptr (prefseg, $34))^);
  413. OldHandleError:=Handles^[StdErrorHandle];
  414. Handles^[StdErrorHandle]:=Handles^[FileRec (FERR^).Handle];
  415. ChangeRedirError:=True;
  416. ErrorRedirDisabled:=False;
  417. {$else}
  418. {$ifdef Windows}
  419. if SetStdHandle(Std_Error_Handle,FileRec(FERR^).Handle) then
  420. {$else not Windows}
  421. {$ifdef ver1_0}
  422. dup(StdErrorHandle,TempHError);
  423. dup2(FileRec(FERR^).Handle,StdErrorHandle);
  424. {$else}
  425. TempHError:=fpdup(StdErrorHandle);
  426. fpdup2(FileRec(FERR^).Handle,StdErrorHandle);
  427. {$endif}
  428. if (TempHError<>UnusedHandle) and
  429. (StdErrorHandle<>UnusedHandle) then
  430. {$endif not Windows}
  431. begin
  432. ChangeRedirError:=True;
  433. ErrorRedirDisabled:=False;
  434. end;
  435. {$endif}
  436. RedirChangedError:=True;
  437. end;
  438. {$IfDef MsDos}
  439. {Set HeapEnd Pointer to Current Used Heapsize}
  440. Procedure SmallHeap;assembler;
  441. asm
  442. mov bx,word ptr HeapPtr
  443. shr bx,4
  444. inc bx
  445. add bx,word ptr HeapPtr+2
  446. mov ax,PrefixSeg
  447. sub bx,ax
  448. mov es,ax
  449. mov ah,4ah
  450. int 21h
  451. end;
  452. {Set HeapEnd Pointer to Full Heapsize}
  453. Procedure FullHeap;assembler;
  454. asm
  455. mov bx,word ptr HeapEnd
  456. shr bx,4
  457. inc bx
  458. add bx,word ptr HeapEnd+2
  459. mov ax,PrefixSeg
  460. sub bx,ax
  461. mov es,ax
  462. mov ah,4ah
  463. int 21h
  464. end;
  465. {$EndIf MsDos}
  466. procedure RestoreRedirOut;
  467. begin
  468. If not RedirChangedOut then Exit;
  469. {$ifndef FPC}
  470. Handles^[StdOutputHandle]:=OldHandleOut;
  471. OldHandleOut:=StdOutputHandle;
  472. {$else}
  473. {$ifdef Windows}
  474. SetStdHandle(Std_Output_Handle,StdOutputHandle);
  475. {$else not Windows}
  476. {$ifdef ver1_0}dup2{$else}fpdup2{$endif}(TempHOut,StdOutputHandle);
  477. {$endif not Windows}
  478. {$endif FPC}
  479. Close (FOUT^);
  480. {$ifdef ver1_0}fdclose{$else}fpclose{$endif}(TempHOut);
  481. RedirChangedOut:=false;
  482. end;
  483. {............................................................................}
  484. procedure RestoreRedirIn;
  485. begin
  486. If not RedirChangedIn then Exit;
  487. {$ifndef FPC}
  488. Handles^[StdInputHandle]:=OldHandleIn;
  489. OldHandleIn:=StdInputHandle;
  490. {$else}
  491. {$ifdef Windows}
  492. SetStdHandle(Std_Input_Handle,StdInputHandle);
  493. {$else not Windows}
  494. {$ifdef ver1_0}dup2{$else}fpdup2{$endif}(TempHIn,StdInputHandle);
  495. {$endif not Windows}
  496. {$endif}
  497. Close (FIn^);
  498. {$ifdef ver1_0}fdclose{$else}fpclose{$endif}(TempHIn);
  499. RedirChangedIn:=false;
  500. end;
  501. {............................................................................}
  502. procedure DisableRedirIn;
  503. begin
  504. If not RedirChangedIn then Exit;
  505. If InRedirDisabled then Exit;
  506. {$ifndef FPC}
  507. Handles^[StdInputHandle]:=OldHandleIn;
  508. {$else}
  509. {$ifdef Windows}
  510. SetStdHandle(Std_Input_Handle,StdInputHandle);
  511. {$else not Windows}
  512. {$ifdef ver1_0}dup2{$else}fpdup2{$endif}(TempHIn,StdInputHandle);
  513. {$endif not Windows}
  514. {$endif}
  515. InRedirDisabled:=True;
  516. end;
  517. {............................................................................}
  518. procedure EnableRedirIn;
  519. begin
  520. If not RedirChangedIn then Exit;
  521. If not InRedirDisabled then Exit;
  522. {$ifndef FPC}
  523. Handles:=Ptr (prefseg, PWord (Ptr (prefseg, $34))^);
  524. Handles^[StdInputHandle]:=Handles^[FileRec (FIn^).Handle];
  525. {$else}
  526. {$ifdef Windows}
  527. SetStdHandle(Std_Input_Handle,FileRec(FIn^).Handle);
  528. {$else not Windows}
  529. {$ifdef ver1_0}dup2{$else}fpdup2{$endif}(FileRec(FIn^).Handle,StdInputHandle);
  530. {$endif not Windows}
  531. {$endif}
  532. InRedirDisabled:=False;
  533. end;
  534. {............................................................................}
  535. procedure DisableRedirOut;
  536. begin
  537. If not RedirChangedOut then Exit;
  538. If OutRedirDisabled then Exit;
  539. {$ifndef FPC}
  540. Handles^[StdOutputHandle]:=OldHandleOut;
  541. {$else}
  542. {$ifdef Windows}
  543. SetStdHandle(Std_Output_Handle,StdOutputHandle);
  544. {$else not Windows}
  545. {$ifdef ver1_0}dup2{$else}fpdup2{$endif}(TempHOut,StdOutputHandle);
  546. {$endif not Windows}
  547. {$endif}
  548. OutRedirDisabled:=True;
  549. end;
  550. {............................................................................}
  551. procedure EnableRedirOut;
  552. begin
  553. If not RedirChangedOut then Exit;
  554. If not OutRedirDisabled then Exit;
  555. {$ifndef FPC}
  556. Handles:=Ptr (prefseg, PWord (Ptr (prefseg, $34))^);
  557. Handles^[StdOutputHandle]:=Handles^[FileRec (FOut^).Handle];
  558. {$else}
  559. {$ifdef Windows}
  560. SetStdHandle(Std_Output_Handle,FileRec(FOut^).Handle);
  561. {$else not Windows}
  562. {$ifdef ver1_0}dup2{$else}fpdup2{$endif}(FileRec(FOut^).Handle,StdOutputHandle);
  563. {$endif not Windows}
  564. {$endif}
  565. OutRedirDisabled:=False;
  566. end;
  567. {............................................................................}
  568. procedure RestoreRedirError;
  569. begin
  570. If not RedirChangedError then Exit;
  571. {$ifndef FPC}
  572. Handles^[StdErrorHandle]:=OldHandleError;
  573. OldHandleError:=StdErrorHandle;
  574. {$else}
  575. {$ifdef Windows}
  576. SetStdHandle(Std_Error_Handle,StdErrorHandle);
  577. {$else not Windows}
  578. {$ifdef ver1_0}dup2{$else}fpdup2{$endif}(TempHError,StdErrorHandle);
  579. {$endif not Windows}
  580. {$endif}
  581. Close (FERR^);
  582. {$ifdef ver1_0}fdclose{$else}fpclose{$endif}(TempHError);
  583. RedirChangedError:=false;
  584. end;
  585. {............................................................................}
  586. procedure DisableRedirError;
  587. begin
  588. If not RedirChangedError then Exit;
  589. If ErrorRedirDisabled then Exit;
  590. {$ifndef FPC}
  591. Handles^[StdErrorHandle]:=OldHandleError;
  592. {$else}
  593. {$ifdef Windows}
  594. SetStdHandle(Std_Error_Handle,StdErrorHandle);
  595. {$else not Windows}
  596. {$ifdef ver1_0}dup2{$else}fpdup2{$endif}(TempHError,StdErrorHandle);
  597. {$endif not Windows}
  598. {$endif}
  599. ErrorRedirDisabled:=True;
  600. end;
  601. {............................................................................}
  602. procedure EnableRedirError;
  603. begin
  604. If not RedirChangedError then Exit;
  605. If not ErrorRedirDisabled then Exit;
  606. {$ifndef FPC}
  607. Handles:=Ptr (prefseg, PWord (Ptr (prefseg, $34))^);
  608. Handles^[StdErrorHandle]:=Handles^[FileRec (FErr^).Handle];
  609. {$else}
  610. {$ifdef Windows}
  611. SetStdHandle(Std_Error_Handle,FileRec(FErr^).Handle);
  612. {$else not Windows}
  613. {$ifdef ver1_0}dup2{$else}fpdup2{$endif}(FileRec(FERR^).Handle,StdErrorHandle);
  614. {$endif not Windows}
  615. {$endif}
  616. ErrorRedirDisabled:=False;
  617. end;
  618. {............................................................................}
  619. function ExecuteRedir (Const ProgName, ComLine, RedirStdIn, RedirStdOut, RedirStdErr : String) : boolean;
  620. {$ifdef Windows}
  621. var
  622. mode : word;
  623. {$endif Windows}
  624. Begin
  625. RedirErrorOut:=0; RedirErrorIn:=0; RedirErrorError:=0;
  626. ExecuteResult:=0;
  627. IOStatus:=0;
  628. if RedirStdIn<>'' then
  629. ChangeRedirIn(RedirStdIn);
  630. if RedirStdOut<>'' then
  631. ChangeRedirOut(RedirStdOut,false);
  632. if RedirStdErr<>'stderr' then
  633. ChangeRedirError(RedirStdErr,false);
  634. DosExecute(ProgName,ComLine);
  635. RestoreRedirOut;
  636. RestoreRedirIn;
  637. RestoreRedirError;
  638. ExecuteRedir:=(IOStatus=0) and (RedirErrorOut=0) and
  639. (RedirErrorIn=0) and (RedirErrorError=0) and
  640. (ExecuteResult=0);
  641. {$ifdef Windows}
  642. // reenable mouse events
  643. GetConsoleMode(GetStdHandle(cardinal(Std_Input_Handle)), @mode);
  644. mode:=mode or ENABLE_MOUSE_INPUT;
  645. SetConsoleMode(GetStdHandle(cardinal(Std_Input_Handle)), mode);
  646. {$endif Windows}
  647. End;
  648. {............................................................................}
  649. procedure RedirDisableAll;
  650. begin
  651. If RedirChangedIn and not InRedirDisabled then
  652. DisableRedirIn;
  653. If RedirChangedOut and not OutRedirDisabled then
  654. DisableRedirOut;
  655. If RedirChangedError and not ErrorRedirDisabled then
  656. DisableRedirError;
  657. end;
  658. {............................................................................}
  659. procedure RedirEnableAll;
  660. begin
  661. If RedirChangedIn and InRedirDisabled then
  662. EnableRedirIn;
  663. If RedirChangedOut and OutRedirDisabled then
  664. EnableRedirOut;
  665. If RedirChangedError and ErrorRedirDisabled then
  666. EnableRedirError;
  667. end;
  668. procedure InitRedir;
  669. begin
  670. {$ifndef FPC}
  671. PrefSeg:=PrefixSeg;
  672. {$endif FPC}
  673. end;
  674. {$else not implemented}
  675. {*****************************************************************************
  676. Fake
  677. *****************************************************************************}
  678. {$IFDEF SHELL_IMPLEMENTED}
  679. {$I-}
  680. function FileExist(const FileName : PathStr) : Boolean;
  681. var
  682. f : file;
  683. Attr : word;
  684. begin
  685. Assign(f, FileName);
  686. GetFAttr(f, Attr);
  687. FileExist := DosError = 0;
  688. end;
  689. function CompleteDir(const Path: string): string;
  690. begin
  691. { keep c: untouched PM }
  692. if (Path<>'') and (Path[Length(Path)]<>DirSep) and
  693. (Path[Length(Path)]<>':') then
  694. CompleteDir:=Path+DirSep
  695. else
  696. CompleteDir:=Path;
  697. end;
  698. function LocateExeFile(var FileName:string): boolean;
  699. var
  700. dir,s,d,n,e : string;
  701. i : longint;
  702. begin
  703. LocateExeFile:=False;
  704. if FileExist(FileName) then
  705. begin
  706. LocateExeFile:=true;
  707. Exit;
  708. end;
  709. Fsplit(Filename,d,n,e);
  710. if (e='') and FileExist(FileName+exeext) then
  711. begin
  712. FileName:=FileName+exeext;
  713. LocateExeFile:=true;
  714. Exit;
  715. end;
  716. S:=GetEnv('PATH');
  717. While Length(S)>0 do
  718. begin
  719. i:=1;
  720. While (i<=Length(S)) and not (S[i] in ListSep) do
  721. Inc(i);
  722. Dir:=CompleteDir(Copy(S,1,i-1));
  723. if i<Length(S) then
  724. Delete(S,1,i)
  725. else
  726. S:='';
  727. if FileExist(Dir+FileName) then
  728. Begin
  729. FileName:=Dir+FileName;
  730. LocateExeFile:=true;
  731. Exit;
  732. End;
  733. end;
  734. end;
  735. function ExecuteRedir (Const ProgName, ComLine, RedirStdIn, RedirStdOut, RedirStdErr: String): boolean;
  736. var
  737. CmdLine2: string;
  738. begin
  739. CmdLine2 := ComLine;
  740. if RedirStdIn <> '' then CmdLine2 := CmdLine2 + ' < ' + RedirStdIn;
  741. if RedirStdOut <> '' then CmdLine2 := CmdLine2 + ' > ' + RedirStdOut;
  742. if RedirStdErr <> '' then
  743. begin
  744. if RedirStdErr = RedirStdOut
  745. then CmdLine2 := CmdLine2 + ' 2>&1'
  746. else CmdLine2 := CmdLine2 + ' 2> ' + RedirStdErr;
  747. end;
  748. DosExecute (ProgName, CmdLine2);
  749. ExecuteRedir := true;
  750. end;
  751. {$ELSE SHELL_IMPLEMENTED}
  752. function ExecuteRedir (Const ProgName, ComLine, RedirStdIn, RedirStdOut, RedirStdErr : String) : boolean;
  753. begin
  754. ExecuteRedir:=false;
  755. end;
  756. {$ENDIF SHELL_IMPLEMENTED}
  757. function ChangeRedirOut(Const Redir : String; AppendToFile : Boolean) : Boolean;
  758. begin
  759. ChangeRedirOut:=false;
  760. end;
  761. procedure RestoreRedirOut;
  762. begin
  763. end;
  764. procedure DisableRedirOut;
  765. begin
  766. end;
  767. procedure EnableRedirOut;
  768. begin
  769. end;
  770. function ChangeRedirIn(Const Redir : String) : Boolean;
  771. begin
  772. ChangeRedirIn:=false;
  773. end;
  774. procedure RestoreRedirIn;
  775. begin
  776. end;
  777. procedure DisableRedirIn;
  778. begin
  779. end;
  780. procedure EnableRedirIn;
  781. begin
  782. end;
  783. function ChangeRedirError(Const Redir : String; AppendToFile : Boolean) : Boolean;
  784. begin
  785. ChangeRedirError:=false;
  786. end;
  787. procedure RestoreRedirError;
  788. begin
  789. end;
  790. procedure DisableRedirError;
  791. begin
  792. end;
  793. procedure EnableRedirError;
  794. begin
  795. end;
  796. procedure RedirDisableAll;
  797. begin
  798. end;
  799. procedure RedirEnableAll;
  800. begin
  801. end;
  802. procedure InitRedir;
  803. begin
  804. end;
  805. {$endif not implemented}
  806. {............................................................................}
  807. procedure DosExecute(ProgName, ComLine : String);
  808. {$ifdef Windows}
  809. var
  810. StoreInherit : BOOL;
  811. {$endif Windows}
  812. Begin
  813. {$IfDef MsDos}
  814. SmallHeap;
  815. {$EndIf MsDos}
  816. SwapVectors;
  817. { Must use shell() for linux for the wildcard expansion (PFV) }
  818. {$ifdef UNIX}
  819. IOStatus:=0;
  820. ExecuteResult:=Shell(MaybeQuoted(FixPath(Progname))+' '+Comline);
  821. {$ifdef ver1_0}
  822. { Signal that causes the stop of the shell }
  823. IOStatus:=ExecuteResult and $7F;
  824. { Exit Code seems to be in the second byte,
  825. is this also true for BSD ??
  826. $80 bit is a CoreFlag apparently }
  827. ExecuteResult:=(ExecuteResult and $ff00) shr 8;
  828. {$else}
  829. if ExecuteResult<0 then
  830. begin
  831. IOStatus:=(-ExecuteResult) and $7f;
  832. ExecuteResult:=((-ExecuteResult) and $ff00) shr 8;
  833. end;
  834. {$endif}
  835. {$else}
  836. {$ifdef Windows}
  837. StoreInherit:=ExecInheritsHandles;
  838. ExecInheritsHandles:=true;
  839. {$endif Windows}
  840. DosError:=0;
  841. If UseComSpec then
  842. Dos.Exec (Getenv('COMSPEC'),'/C '+MaybeQuoted(FixPath(progname))+' '+Comline)
  843. else
  844. begin
  845. if LocateExeFile(progname) then
  846. Dos.Exec(ProgName,Comline)
  847. else
  848. DosError:=2;
  849. end;
  850. {$ifdef Windows}
  851. ExecInheritsHandles:=StoreInherit;
  852. {$endif Windows}
  853. IOStatus:=DosError;
  854. ExecuteResult:=DosExitCode;
  855. {$endif}
  856. SwapVectors;
  857. {$ifdef CPU86}
  858. { reset the FPU }
  859. {$asmmode att}
  860. asm
  861. fninit
  862. end;
  863. {$endif CPU86}
  864. {$IfDef MsDos}
  865. Fullheap;
  866. {$EndIf MsDos}
  867. End;
  868. {*****************************************************************************
  869. Initialize
  870. *****************************************************************************}
  871. initialization
  872. New(FIn); New(FOut); New(FErr);
  873. finalization
  874. Dispose(FIn); Dispose(FOut); Dispose(FErr);
  875. End.