fpredir.pas 24 KB

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