fpredir.pas 23 KB

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