redir.pp 23 KB

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