home *** CD-ROM | disk | FTP | other *** search
/ POINT Software Programming / PPROG1.ISO / pascal / swag / redirect.swg / 0003_REDIRCT1.PAS.pas < prev    next >
Encoding:
Pascal/Delphi Source File  |  1993-05-28  |  5.5 KB  |  247 lines

  1. {
  2. All these solutions of using a shell to redirect output.
  3.  
  4. There are two Dos interrupts that allow Filehandles to be duplicated.
  5.  
  6. Redirec and unredirec allow easy access to dup and dup2 For standard in
  7. and out (input and output are reserved TP Words) to a Text File that you
  8. have previously opened (reset/reWrite/append as appropriate). It must be
  9. opened - this allocates a File handle (a Byte - you declare this, you'll
  10. need it later to get your output back). if you don't unredirec to the
  11. right handle you could loose all your output to the File or a black hole -
  12. be warned.
  13.  
  14. You could make similar Procedures to redirec/unredirec For redirection of
  15. other standard handles (3 is Printer (LST), 4 I think is STDERR  and 5
  16. is AUX aren't they?)
  17.  
  18. Here's the Unit:
  19. }
  20.  
  21. {$O+ $F+}
  22.  
  23. Unit ReDIRECt;
  24.  
  25. Interface
  26.  
  27. Function dup (hand : Byte; Var error : Boolean) : Byte;
  28.    { provides a new handle For an already opened device or File.
  29.      if error, then the return is the error code - 4 no handles available or
  30.      6, invalid handle.}
  31.  
  32. Procedure dup2 (source, destination : Byte;  Var err : Byte);
  33.    { Makes two File handles refer to the same opened File at the same
  34.      location. The destination is closed first.
  35.      Err returns 0 if no error or error code as For dup.
  36.      to redirect then return to normal - do as follows:
  37.      1. Use DUP to save the handle to be directed (the source).
  38.      2. Assign and reWrite/reset the destination.
  39.      3. Redirect the handle using DUP2.
  40.      4. Do the exec
  41.      5. Use dup2 again restoring the saved handle.
  42.      6. reset/reWrite the redirected items & close the destination}
  43.  
  44. Function Redirec (op : Boolean; Var f:Text; Var hand : Byte) : Boolean;
  45.   {redirects standard out to (if op True) or standard in from File fn.
  46.    returns handle in handle to be used by undirec, below, and True if
  47.    successful.}
  48.  
  49. Procedure Undirec (op : Boolean; hand : Byte);
  50.    {undoes the redirection from the previous redirec. Assumes File closed
  51.     by caller.}
  52.  
  53. Function getFilehandle(Filename : String; Var error : Boolean) : Integer;
  54.  
  55. {////////////////////////////////////////////////////////////////////////}
  56. Implementation
  57.  
  58. Uses
  59.   Dos;
  60.  
  61. Function dup (hand : Byte; Var error : Boolean) : Byte;
  62. Var
  63.   regs : Registers;
  64. begin
  65.   With regs do
  66.   begin
  67.     AH := $45;
  68.     BX := hand;
  69.  
  70.     MsDos (regs);
  71.  
  72.     error := flags and fcarry <> 0;  {error if carry set}
  73.  
  74.     dup := AX;
  75.   end;
  76. end;
  77.  
  78. Procedure dup2 (source, destination : Byte;  Var err : Byte);
  79. Var
  80.   regs : Registers;
  81. begin
  82.   With regs do
  83.   begin
  84.     AH := $46;
  85.     BX := source;
  86.     CX := destination ;
  87.  
  88.     MsDos (regs);
  89.  
  90.     if flags and fcarry <> 0 then {error if carry set}
  91.       err := AX
  92.     else
  93.       err := 0;
  94.   end;
  95. end;
  96.  
  97. Function Redirec (op : Boolean; Var f:Text; Var hand : Byte) : Boolean;
  98.   {redirects standard out to (if op True) or standard in from File fn.
  99.    returns handle in handle to be used by undirec, below, and True if
  100.    successful.}
  101. Var
  102.   err     : Byte;
  103.   error   : Boolean;
  104. begin
  105.   redirec := False;
  106.   err := 0;
  107.   if op then
  108.   begin
  109.     flush (output);
  110.     hand := dup (Textrec(output).handle, error)
  111.   end
  112.   else
  113.   begin
  114.     flush (input);
  115.     hand := dup (Textrec(input).handle, error)
  116.   end;
  117.   if error then
  118.     Exit;
  119.   {$i-}
  120.   if op then
  121.     reWrite (f)
  122.   else
  123.     reset (f);
  124.   {$i+}
  125.   if ioresult <> 0 then
  126.     Exit;
  127.   if op then
  128.     dup2 (Textrec(f).handle, Textrec(output).handle,err)
  129.   else
  130.     dup2 (Textrec(f).handle, Textrec(input).handle,err);
  131.  
  132.   redirec := (err = 0);
  133. end;
  134.  
  135. Procedure Undirec (op : Boolean; hand : Byte);
  136.    {undoes the redirection from the previous redirec. Assumes File closed
  137.     by caller.}
  138. Var
  139.   err : Byte;
  140. begin
  141.   if op then
  142.   begin
  143.     dup2 (hand, Textrec(output).handle, err);
  144.     reWrite (output)
  145.   end
  146.   else
  147.   begin
  148.     dup2 (hand, Textrec(input).handle, err);
  149.     reset (input)
  150.   end
  151. end; {undirec}
  152.  
  153.  
  154. Function getFilehandle( Filename : String; Var error : Boolean) : Integer;
  155. Var
  156.   regs : Registers;
  157.   i : Integer;
  158. begin
  159.   Filename := Filename + #0;
  160.   fillChar(regs, sizeof(regs), 0);
  161.  
  162.   With regs do
  163.   begin
  164.     ah := $3D;
  165.     AL := $00;
  166.     ds := seg(Filename);
  167.     dx := ofs(Filename) + 1;
  168.   end;
  169.  
  170.   MsDos(Regs);
  171.  
  172.   I := regs.ax;
  173.  
  174.   if (lo(regs.flags) and $01) > 0 then
  175.   begin
  176.     error := True;
  177.     getFilehandle := 0;
  178.     Exit
  179.   end;
  180.  
  181.   getFilehandle := i;
  182. end;
  183.  
  184. end.
  185.  
  186. { Here's a demo }
  187.  
  188. Program dupdemo;
  189.  
  190. {$M 2000,0,0}
  191. Uses
  192.   Direc, Dos;
  193.  
  194.  
  195. Var
  196.   arcname : String;
  197.   tempFile : Text;
  198.   op : Boolean;
  199.   handle : Byte;
  200.   Handle2 : Byte;
  201.   err : Boolean;
  202.   Error : Byte;
  203.   InFile : File;
  204.  
  205. begin
  206.   Handle := 0;
  207.  
  208.   Handle2 := Dup(Handle,Err);
  209.  
  210.   if Err then
  211.   begin
  212.      Writeln('Error getting another handle');
  213.      halt;
  214.   end;
  215.  
  216.   arcname := 'C:\qmpro\download\qmpro102.ZIP';
  217.   assign (tempFile, 'C:\qmpro\download\TEMP.FIL');
  218.   ReWrite(TempFile);
  219.  
  220.   Dup2(Handle, Handle2, Error);
  221.   if Error <> 0 then
  222.   begin
  223.      Writeln('ERRor: ',Error);
  224.      Halt;
  225.   end;
  226.  
  227.  
  228.   if redirec(op, tempFile, handle2) then
  229.   begin
  230.     SwapVectors;
  231.     Writeln('Running ZIP!');
  232.     Exec('PKUNZIP',' -V ' + ArcName);
  233.     SwapVectors;
  234.     close (tempFile);
  235.     undirec (op, handle2);
  236.   end
  237.   else
  238.     Writeln('Error!');
  239. end.
  240.  
  241. {
  242. I wrote the DUPDEMO Program, but the Unit is the brainchild of an author that I
  243. can't remember, but I use this regularly.  It will work up to TP 7.0, I've
  244. never tested it With TP 7.0 because I don't own it.
  245. }
  246.  
  247.