redir.pp 23 KB

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