fpredir.pas 23 KB

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