redir.pp 21 KB

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