fpredir.pas 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384
  1. {
  2. $Id$
  3. This file is part of the Free Pascal Integrated Development Environment
  4. Copyright (c) 1998 by Berczi Gabor
  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. {$S-}
  18. {$endif}
  19. {$ifdef TP}
  20. {$define in_dos}
  21. {$endif TP}
  22. {$ifdef Go32v2}
  23. {$define in_dos}
  24. {$endif}
  25. Var
  26. IOStatus : Integer;
  27. RedirError : Integer;
  28. ExecuteResult : Word;
  29. {------------------------------------------------------------------------------}
  30. function ExecuteRedir (Const ProgName, ComLine, RedirStdOut, RedirStdErr : String) : boolean;
  31. function ChangeRedir(Const Redir : String; AppendToFile : Boolean) : Boolean;
  32. procedure RestoreRedir;
  33. function ChangeErrorRedir(Const Redir : String; AppendToFile : Boolean) : Boolean;
  34. procedure RestoreErrorRedir;
  35. Implementation
  36. Uses
  37. {$ifdef go32v2}
  38. go32,
  39. {$endif go32v2}
  40. dos;
  41. {*****************************************************************************
  42. Dos
  43. *****************************************************************************}
  44. {$ifdef in_dos}
  45. Type
  46. PtrRec = packed record
  47. Ofs, Seg : Word;
  48. end;
  49. PHandles = ^THandles;
  50. THandles = Array [Byte] of Byte;
  51. PWord = ^Word;
  52. Var
  53. PrefSeg : Word;
  54. MinBlockSize : Word;
  55. FName : PathStr;
  56. F,FE : File;
  57. MyBlockSize : Word;
  58. RedirChanged : Boolean;
  59. RedirErrorChanged : Boolean;
  60. Handles : PHandles;
  61. OldHandle,OldErrorHandle : Byte;
  62. TempH, TempErrorH : longint;
  63. {$ifdef FPC}
  64. HandlesOffset : word;
  65. {$endif FPC}
  66. function dup(fh : longint) : longint;
  67. var
  68. Regs : Registers;
  69. begin
  70. Regs.ax:=$45;
  71. Regs.bx:=fh;
  72. MsDos (Regs);
  73. If (Regs.Flags and fCarry)=0 then
  74. Dup:=Regs.Ax
  75. else
  76. Dup:=-1;
  77. end;
  78. function dup2(fh,nh : longint) : longint;
  79. var
  80. Regs : Registers;
  81. begin
  82. If fh=nh then
  83. begin
  84. dup2:=nh;
  85. exit;
  86. end;
  87. Regs.ax:=$46;
  88. Regs.bx:=fh;
  89. {$ifndef TP}
  90. Regs.cs:=nh;
  91. {$endif}
  92. MsDos (Regs);
  93. If (Regs.Flags and fCarry)=0 then
  94. Dup2:=nh
  95. else
  96. Dup2:=-1;
  97. end;
  98. {$I-}
  99. function FileExist(const FileName : PathStr) : Boolean;
  100. var
  101. f : file;
  102. Attr : word;
  103. begin
  104. Assign(f, FileName);
  105. GetFAttr(f, Attr);
  106. FileExist := DosError = 0;
  107. end;
  108. {............................................................................}
  109. function ChangeRedir(Const Redir : String; AppendToFile : Boolean) : Boolean;
  110. var temp : byte;
  111. begin
  112. ChangeRedir:=False;
  113. If Redir = '' then Exit;
  114. Assign (F, Redir);
  115. If AppendToFile and FileExist(Redir) then
  116. Begin
  117. Reset(F,1);
  118. Seek(F,FileSize(F));
  119. End else Rewrite (F);
  120. RedirError:=IOResult;
  121. IOStatus:=RedirError;
  122. If IOStatus <> 0 then Exit;
  123. {$ifndef FPC}
  124. Handles:=Ptr (prefseg, PWord (Ptr (prefseg, $34))^);
  125. OldHandle:=Handles^[1];
  126. Handles^[1]:=Handles^[FileRec (F).Handle];
  127. ChangeRedir:=True;
  128. {$else}
  129. {$ifdef UseDUP}
  130. TempH:=dup(1);
  131. if dup2(1,FileRec(F).Handle)=FileRec(F).Handle then
  132. {$else UseDUP}
  133. DosMemGet(prefseg,HandlesOffset+1,OldHandle,1);
  134. DosMemGet(prefseg,HandlesOffset+FileRec(F).handle,temp,1);
  135. dosmemput(prefseg,HandlesOffset+1,temp,1);
  136. { NO MEM use as %fs is distroyed somewhere !!
  137. OldHandle:=Mem[prefseg:HandlesOffset+1];
  138. Mem[prefseg:HandlesOffset+1]:=Mem[prefseg:HandlesOffset+FileRec(F).handle];}
  139. {$endif UseDUP}
  140. ChangeRedir:=True;
  141. {$endif}
  142. RedirChanged:=True;
  143. end;
  144. function ChangeErrorRedir(Const Redir : String; AppendToFile : Boolean) : Boolean;
  145. var temp : byte;
  146. begin
  147. ChangeErrorRedir:=False;
  148. If Redir = '' then Exit;
  149. Assign (FE, Redir);
  150. If AppendToFile and FileExist(Redir) then
  151. Begin
  152. Reset(FE,1);
  153. Seek(FE,FileSize(FE));
  154. End else Rewrite (FE);
  155. RedirError:=IOResult;
  156. IOStatus:=RedirError;
  157. If IOStatus <> 0 then Exit;
  158. {$ifndef FPC}
  159. Handles:=Ptr (prefseg, PWord (Ptr (prefseg, $34))^);
  160. OldErrorHandle:=Handles^[2];
  161. Handles^[2]:=Handles^[FileRec (FE).Handle];
  162. ChangeErrorRedir:=True;
  163. {$else}
  164. {$ifdef UseDUP}
  165. TempErrorH:=dup(2);
  166. if dup2(2,FileRec(F).Handle)=FileRec(F).Handle then
  167. {$else UseDUP}
  168. DosMemGet(prefseg,HandlesOffset+2,OldErrorHandle,1);
  169. DosMemGet(prefseg,HandlesOffset+FileRec(F).handle,temp,1);
  170. dosmemput(prefseg,HandlesOffset+1,temp,1);
  171. {OldErrorHandle:=Mem[prefseg:HandlesOffset+2];
  172. Mem[prefseg:HandlesOffset+2]:=Mem[prefseg:HandlesOffset+FileRec(FE).handle];}
  173. {$endif UseDUP}
  174. ChangeErrorRedir:=True;
  175. {$endif}
  176. RedirErrorChanged:=True;
  177. end;
  178. {............................................................................}
  179. {$IfDef MsDos}
  180. procedure CompactHeap;
  181. var
  182. Regs : Registers;
  183. begin
  184. Regs.AH:=$4A;
  185. Regs.ES:=PrefSeg;
  186. Regs.BX:=MinBlockSize + (PtrRec (HeapPtr).Seg - PtrRec (HeapOrg).Seg);
  187. MsDos (Regs);
  188. end;
  189. {............................................................................}
  190. procedure ExpandHeap;
  191. var
  192. Regs : Registers;
  193. begin
  194. Regs.AH:=$4A;
  195. Regs.ES:=PrefSeg;
  196. Regs.BX:=MyBlockSize;
  197. MsDos (Regs);
  198. end;
  199. {$EndIf MsDos}
  200. {............................................................................}
  201. procedure RestoreRedir;
  202. begin
  203. If not RedirChanged then Exit;
  204. {$ifndef FPC}
  205. Handles^[1]:=OldHandle;
  206. {$else}
  207. {$ifdef UseDUP}
  208. dup2(1,TempH);
  209. {$else UseDUP}
  210. dosmemput(prefseg,HandlesOffset+1,OldHandle,1);
  211. {Mem[prefseg:HandlesOffset+1]:=OldHandle;}
  212. {$endif UseDUP}
  213. {$endif}
  214. Close (F);
  215. RedirChanged:=false;
  216. end;
  217. {............................................................................}
  218. procedure RestoreErrorRedir;
  219. begin
  220. If not RedirErrorChanged then Exit;
  221. {$ifndef FPC}
  222. Handles^[2]:=OldErrorHandle;
  223. {$else}
  224. {$ifdef UseDUP}
  225. dup2(1,TempErrorH);
  226. {$else UseDUP}
  227. dosmemput(prefseg,HandlesOffset+2,OldErrorHandle,1);
  228. {Mem[prefseg:HandlesOffset+2]:=OldErrorHandle;}
  229. {$endif UseDUP}
  230. {$endif}
  231. Close (FE);
  232. RedirErrorChanged:=false;
  233. end;
  234. {............................................................................}
  235. procedure DosExecute(ProgName, ComLine : String);
  236. Begin
  237. {$IfDef MsDos}
  238. CompactHeap;
  239. {$EndIf MsDos}
  240. SwapVectors;
  241. Dos.Exec (ProgName, ComLine);
  242. IOStatus:=DosError;
  243. ExecuteResult:=DosExitCode;
  244. SwapVectors;
  245. {$IfDef MsDos}
  246. Expandheap;
  247. {$EndIf MsDos}
  248. End;
  249. {............................................................................}
  250. function ExecuteRedir (Const ProgName, ComLine, RedirStdOut, RedirStdErr : String) : boolean;
  251. Begin
  252. RedirError:=0;
  253. ExecuteResult:=0;
  254. IOStatus:=0;
  255. if RedirStdOut<>'' then
  256. ChangeRedir(RedirStdOut,false);
  257. if RedirStdErr<>'stderr' then
  258. RedirErrorChanged:=ChangeErrorRedir(RedirStdErr,false);
  259. DosExecute(ProgName,ComLine);
  260. RestoreRedir;
  261. RestoreErrorRedir;
  262. ExecuteRedir:=(IOStatus=0) and (RedirError=0) and (ExecuteResult=0);
  263. End;
  264. procedure InitRedir;
  265. begin
  266. {$ifndef FPC}
  267. PrefSeg:=PrefixSeg;
  268. {$else FPC}
  269. {$ifdef go32v2}
  270. PrefSeg:=go32_info_block.linear_address_of_original_psp div 16;
  271. HandlesOffset:=Memw[prefseg:$34];
  272. {$else }
  273. PrefSeg:=0;
  274. {$endif }
  275. {$endif FPC}
  276. end;
  277. {$endif indos}
  278. {*****************************************************************************
  279. Linux
  280. *****************************************************************************}
  281. {$ifdef linux}
  282. function ExecuteRedir (Const ProgName, ComLine, RedirStdOut, RedirStdErr : String) : boolean;
  283. begin
  284. ExecuteRedir:=false;
  285. end;
  286. function ChangeRedir(Const Redir : String; AppendToFile : Boolean) : Boolean;
  287. begin
  288. ChangeRedir:=false;
  289. end;
  290. procedure RestoreRedir;
  291. begin
  292. end;
  293. function ChangeErrorRedir(Const Redir : String; AppendToFile : Boolean) : Boolean;
  294. begin
  295. ChangeErrorRedir:=false;
  296. end;
  297. procedure RestoreErrorRedir;
  298. begin
  299. end;
  300. procedure InitRedir;
  301. begin
  302. end;
  303. {$endif linux}
  304. {*****************************************************************************
  305. Initialize
  306. *****************************************************************************}
  307. Begin
  308. InitRedir;
  309. End.
  310. {
  311. $Log$
  312. Revision 1.6 1999-02-05 13:51:43 peter
  313. * unit name of FPSwitches -> FPSwitch which is easier to use
  314. * some fixes for tp7 compiling
  315. }