home *** CD-ROM | disk | FTP | other *** search
/ DP Tool Club 16 / CD_ASCQ_16_0994.iso / maj / swag / redirect.swg < prev    next >
Text File  |  1994-08-29  |  29KB  |  1 lines

  1. SWAGOLX.EXE (c) 1993 GDSOFT  ALL RIGHTS RESERVED 00008         DOS REDIRECTION ROUTINES                                          1      05-28-9313:56ALL                      SWAG SUPPORT TEAM        DOS-REDR.PAS             IMPORT              28          Unit Execute;ππInterfaceππProcedure Exec(Path,CmdLine : String);ππImplementationππUsesπ  Dos;ππFunction ExtractFileName(Var Line : String;Index : Integer) : String;ππVarπ  Temp : String;ππbeginπ  Delete(Line,Index,1);π  While (Index <= Length(Line)) and (Line[Index] = ' ')π    Do Delete(Line,Index,1);π  Temp := '';π  While (Index <= Length(Line)) and (Line[Index] <> ' ') Doπ  beginπ    Temp := Temp + Line[Index];π    Delete(Line,Index,1);π  end;π  ExtractFileName := Temp;πend;ππProcedure CloseHandle(Handle : Word);ππVarπ  Regs : Registers;ππbeginπ  With Regs Doπ  beginπ    AH := $3E;π    BX := Handle;π    MsDos(Regs);π  end;πend;ππProcedure Duplicate(SourceHandle : Word;Var TargetHandle : Word);ππVarπ  Regs : Registers;ππbeginπ  With Regs Doπ  beginπ    AH := $45;π    BX := SourceHandle;π    MsDos(Regs);π    TargetHandle := AX;π  end;πend;ππProcedure ForceDuplicate(SourceHandle : Word;Var TargetHandle : Word);ππVarπ  Regs : Registers;ππbeginπ  With Regs Doπ  beginπ    AH := $46;π    BX := SourceHandle;π    CX := TargetHandle;π    MsDos(Regs);π    TargetHandle := AX;π  end;πend;ππProcedure Exec(Path,CmdLine : String);ππVarπ  StdIn   : Word;π  Stdout  : Word;π  Index   : Integer;π  FName   : String[80];π  InFile  : Text;π  OutFile : Text;ππ  InHandle  : Word;π  OutHandle : Word;π         { ===============>>>> }   { change below For STDERR }πbeginπ  StdIn := 0;π  StdOut := 1;                    { change to 2 For StdErr       }π  Duplicate(StdIn,InHandle);      { duplicate standard input     }π  Duplicate(StdOut,OutHandle);    { duplicate standard output    }π  Index := Pos('>',CmdLine);π  If Index > 0 Then               { check For output redirection }π  beginπ    FName := ExtractFileName(CmdLine,Index);  { get output File name  }π    Assign(OutFile,FName);                    { open a Text File      }π    ReWrite(OutFile);                         { .. For output         }π    ForceDuplicate(TextRec(OutFile).Handle,StdOut);{ make output same }π  end;π  Index := Pos('<',CmdLine);π  If Index > 0 Then               { check For input redirection }π  beginπ    FName := ExtractFileName(CmdLine,Index);  { get input File name  }π    Assign(InFile,FName);                     { open a Text File     }π    Reset(InFile);                            { For input            }π    ForceDuplicate(TextRec(InFile).Handle,StdIn);  { make input same }π  end;π  Dos.Exec(Path,CmdLine);           { run EXEC }π  ForceDuplicate(InHandle,StdIn);   { put standard input back to keyboard }π  ForceDuplicate(OutHandle,StdOut); { put standard output back to screen  }π  CloseHandle(InHandle);            { Close the redirected input File     }π  CloseHandle(OutHandle);           { Close the redirected output File    }πend;ππend.ππ{===============================================================}π{πUse it exactly as you would the normal EXEC Procedure:ππ  Exec('MAsm.EXE','mystuff.Asm');ππTo activate redirection simply add the redirection symbols, etc:ππ  Exec('MAsm.EXE','mystuff.Asm >err.lst');ππOne note of caution.  This routine temporarily Uses extra handles. It'sπeither two or four more.  The Various books I have are not clear as toπwhether duplicated handles 'count' or not. My guess is yes.  If you don'tπplan on redirecting STDIN then reMove all the code For duplicating it toπcut your handle overhead in half.π}ππ                                                                                                                        2      05-28-9313:56ALL                      SWAG SUPPORT TEAM        DUALOUT.PAS              IMPORT              37          Unit dualout;ππ{ This Unit is designed to demonstrate directing all screen output to a File }π{ in addition to the normal display.  This means that any Write or Writeln   }π{ will display normally on the screen and also be Recorded in a Text File.   }π{ The File name For the output can be supplied by a command line parameter   }π{ in the Format -  dual=c:\test\output.dat or you can provide an environment }π{ Variable named dual that supplies the File name or it will default to the  }π{ current directory and output.dat.                                          }ππInterfaceππUsesπ  globals,  { contains the Function exist, which tests For the existence of  }π            { a File.  It also defines the Type str80 as String[80]          }π  Dos,π  tpString; { from TPro. Needed For StUpCase Function in Procedure initialise}ππConst π  DualOn   : Boolean = False;π  DualOK   : Boolean = False;π  fname    : str80   = 'output.dat';  { The default File name For the output }π  πTypeπ  DriverFunc = Function(Var f: TextRec): Integer;ππVarπ  OldExitProc    : Pointer;                  { For saving old Exit Procedure }π  OldInOutOutput,                            { The old output InOut Function }π  OldFlushOutput : DriverFunc;               { The old output Flush Function }π  dualf          : Text;ππProcedure  dual(status: Boolean);ππ{===========================================================================}πImplementationππVarπ  cmdline : String;π  πProcedure DualWrite(Var f: TextRec);π  { Writes the output from stdout to a File }π  Varπ    x : Word;π  beginπ    For x := 0 to pred(f.BufPos) doπ      Write(dualf, f.BufPtr^[x]);π  end;  { DualWrite }ππ{$F+}πFunction InOutOutput(Var f: TextRec): Integer;π  beginπ    DualWrite(f);                                        { Write to the File }π    InOutOutput := OldInOutOutput(f);                { Call the old Function }π  end; { InOutOutput }ππFunction FlushOutput(Var f: TextRec): Integer;π  beginπ    DualWrite(f);                                        { Write to the File }π    FlushOutput := OldFlushOutput(f);                { Call the old Function }π  end; { FlushOutput }ππProcedure DualExitProc;π  beginπ    close(dualf);π    ExitProc := OldExitProc;                { Restore the old Exit Procedure }π    With TextRec(output) do beginπ      InOutFunc := @OldInOutOutput;          { Restore the old output Record }π      FlushFunc := @OldFlushOutput;           { Restore the old flush Record }π    end; { With }π  end; { DualExitProc }ππ{$F-,I-}πProcedure dual(status: Boolean);π  Varπ    ErrorCode : Integer;π  beginπ    if status then beginπ      assign(dualf,fname);π      if Exist(fname) then { open For writing }π        append(dualf)π      else { start new File }π        reWrite(dualf);π      ErrorCode := Ioresult;   π      if ErrorCode <> 0 then π        halt(ErrorCode);π      With TextRec(output) do beginπ        { This is where the old output Functions are rerouted }π        OldInOutOutput := DriverFunc(InOutFunc);π        OldFlushOutput := DriverFunc(FlushFunc);π        InOutFunc := @InOutOutput;π        FlushFunc := @FlushOutput;π      end; { With }π      OldExitProc := ExitProc;            { Save the current Exit Procedure }π      ExitProc    := @DualExitProc;            { Install new Exit Procedure }π      DualOn      := True;π    end { if status }  π    else { switch dual output off } begin  π      if DualOn then beginπ        close(dualf);  if Ioresult = 0 then;                   { dummy call }π        ExitProc := OldExitProc;           { Restore the old Exit Procedure }π        OldExitProc := nil;π        With TextRec(output) do beginπ          InOutFunc := @OldInOutOutput;     { Restore the old output Record }π          FlushFunc := @OldFlushOutput;      { Restore the old flush Record }π        end; { With }π      end; { if DualOn }π    end; { else }π  end; { dual }π{$I+}  πππProcedure Initialise;π  { Determines if a File name For the output has been provided. }π  beginπ    if GetEnv('DUAL') <> '' thenπ      fname := GetEnv('DUAL')π    else beginπ      if ParamCount <> 0 then beginπ        cmdline := String(ptr(PrefixSeg,$80)^);π        cmdline := StUpCase(cmdline);π        if pos('DUAL=',cmdline) <> 0 then beginπ          fname := copy(cmdline,pos('DUAL=',cmdline)+5,80);π          if pos(' ',fname) <> 0 thenπ            fname := copy(fname,1,pos(' ',fname)-1);π        end; { if pos('Dual... }π      end;  { if ParamCount... }π    end; { else }π  end; { Initialise }π  πbeginπ  Initialise;πend.  ππ                                                                                           3      05-28-9313:56ALL                      SWAG SUPPORT TEAM        REDIRCT1.PAS             IMPORT              43          {πAll these solutions of using a shell to redirect output.ππThere are two Dos interrupts that allow Filehandles to be duplicated.ππRedirec and unredirec allow easy access to dup and dup2 For standard inπand out (input and output are reserved TP Words) to a Text File that youπhave previously opened (reset/reWrite/append as appropriate). It must beπopened - this allocates a File handle (a Byte - you declare this, you'llπneed it later to get your output back). if you don't unredirec to theπright handle you could loose all your output to the File or a black hole -πbe warned.ππYou could make similar Procedures to redirec/unredirec For redirection ofπother standard handles (3 is Printer (LST), 4 I think is STDERR  and 5πis AUX aren't they?)ππHere's the Unit:π}ππ{$O+ $F+}ππUnit ReDIRECt;ππInterfaceππFunction dup (hand : Byte; Var error : Boolean) : Byte;π   { provides a new handle For an already opened device or File.π     if error, then the return is the error code - 4 no handles available orπ     6, invalid handle.}ππProcedure dup2 (source, destination : Byte;  Var err : Byte);π   { Makes two File handles refer to the same opened File at the sameπ     location. The destination is closed first.π     Err returns 0 if no error or error code as For dup.π     to redirect then return to normal - do as follows:π     1. Use DUP to save the handle to be directed (the source).π     2. Assign and reWrite/reset the destination.π     3. Redirect the handle using DUP2.π     4. Do the execπ     5. Use dup2 again restoring the saved handle.π     6. reset/reWrite the redirected items & close the destination}ππFunction Redirec (op : Boolean; Var f:Text; Var hand : Byte) : Boolean;π  {redirects standard out to (if op True) or standard in from File fn.π   returns handle in handle to be used by undirec, below, and True ifπ   successful.}ππProcedure Undirec (op : Boolean; hand : Byte);π   {undoes the redirection from the previous redirec. Assumes File closedπ    by caller.}ππFunction getFilehandle(Filename : String; Var error : Boolean) : Integer;ππ{////////////////////////////////////////////////////////////////////////}πImplementationππUsesπ  Dos;ππFunction dup (hand : Byte; Var error : Boolean) : Byte;πVarπ  regs : Registers;πbeginπ  With regs doπ  beginπ    AH := $45;π    BX := hand;ππ    MsDos (regs);ππ    error := flags and fcarry <> 0;  {error if carry set}ππ    dup := AX;π  end;πend;ππProcedure dup2 (source, destination : Byte;  Var err : Byte);πVarπ  regs : Registers;πbeginπ  With regs doπ  beginπ    AH := $46;π    BX := source;π    CX := destination ;ππ    MsDos (regs);ππ    if flags and fcarry <> 0 then {error if carry set}π      err := AXπ    elseπ      err := 0;π  end;πend;ππFunction Redirec (op : Boolean; Var f:Text; Var hand : Byte) : Boolean;π  {redirects standard out to (if op True) or standard in from File fn.π   returns handle in handle to be used by undirec, below, and True ifπ   successful.}πVarπ  err     : Byte;π  error   : Boolean;πbeginπ  redirec := False;π  err := 0;π  if op thenπ  beginπ    flush (output);π    hand := dup (Textrec(output).handle, error)π  endπ  elseπ  beginπ    flush (input);π    hand := dup (Textrec(input).handle, error)π  end;π  if error thenπ    Exit;π  {$i-}π  if op thenπ    reWrite (f)π  elseπ    reset (f);π  {$i+}π  if ioresult <> 0 thenπ    Exit;π  if op thenπ    dup2 (Textrec(f).handle, Textrec(output).handle,err)π  elseπ    dup2 (Textrec(f).handle, Textrec(input).handle,err);ππ  redirec := (err = 0);πend;ππProcedure Undirec (op : Boolean; hand : Byte);π   {undoes the redirection from the previous redirec. Assumes File closedπ    by caller.}πVarπ  err : Byte;πbeginπ  if op thenπ  beginπ    dup2 (hand, Textrec(output).handle, err);π    reWrite (output)π  endπ  elseπ  beginπ    dup2 (hand, Textrec(input).handle, err);π    reset (input)π  endπend; {undirec}πππFunction getFilehandle( Filename : String; Var error : Boolean) : Integer;πVarπ  regs : Registers;π  i : Integer;πbeginπ  Filename := Filename + #0;π  fillChar(regs, sizeof(regs), 0);ππ  With regs doπ  beginπ    ah := $3D;π    AL := $00;π    ds := seg(Filename);π    dx := ofs(Filename) + 1;π  end;ππ  MsDos(Regs);ππ  I := regs.ax;ππ  if (lo(regs.flags) and $01) > 0 thenπ  beginπ    error := True;π    getFilehandle := 0;π    Exitπ  end;ππ  getFilehandle := i;πend;ππend.ππ{ Here's a demo }ππProgram dupdemo;ππ{$M 2000,0,0}πUsesπ  Direc, Dos;πππVarπ  arcname : String;π  tempFile : Text;π  op : Boolean;π  handle : Byte;π  Handle2 : Byte;π  err : Boolean;π  Error : Byte;π  InFile : File;ππbeginπ  Handle := 0;ππ  Handle2 := Dup(Handle,Err);ππ  if Err thenπ  beginπ     Writeln('Error getting another handle');π     halt;π  end;ππ  arcname := 'C:\qmpro\download\qmpro102.ZIP';π  assign (tempFile, 'C:\qmpro\download\TEMP.FIL');π  ReWrite(TempFile);ππ  Dup2(Handle, Handle2, Error);π  if Error <> 0 thenπ  beginπ     Writeln('ERRor: ',Error);π     Halt;π  end;πππ  if redirec(op, tempFile, handle2) thenπ  beginπ    SwapVectors;π    Writeln('Running ZIP!');π    Exec('PKUNZIP',' -V ' + ArcName);π    SwapVectors;π    close (tempFile);π    undirec (op, handle2);π  endπ  elseπ    Writeln('Error!');πend.ππ{πI wrote the DUPDEMO Program, but the Unit is the brainchild of an author that Iπcan't remember, but I use this regularly.  It will work up to TP 7.0, I'veπnever tested it With TP 7.0 because I don't own it.π}ππ         4      05-28-9313:56ALL                      SWAG SUPPORT TEAM        REDIRCT2.PAS             IMPORT              14          {π> When pkzip executes... it Writes to the screen and scrolls myπ> screen up. Is there a way in which I can prevent pkzip from writingπ> to the screen.ππThis thread comes up a bunch.  Here's a tried and tested solution :π}πUnit Redir;ππ{ Redirect input, output, and errors }ππInterfaceππProcedure RedirectInput (TextFile : String);πProcedure RedirectOutput (TextFile : String);πProcedure StdInput;πProcedure StdOutput;ππImplementationππUsesπ  Dos;ππConstπ    STDin  = 0;π    STdoUT = 1;π    STDERR = 2;ππProcedure Force_Dup (Existing,              { Existing handle         }π                     Second     : Word);    { Handle to place it to   }ππVarπ  R : Registers;ππbeginππ    r.AH := $46;π    r.BX := Existing;π    r.CX := Second;ππ    MSDos (R);ππ    if (r.Flags and FCarry) <> 0 thenπ        Writeln ('Error ', r.AX, ' changing handle ', Second);πend;πππProcedure RedirectInput (TextFile : String);ππVarπ    TF : Text;ππbeginπ    Assign (TF, TextFile);π    Reset (TF);π    Force_Dup (TextRec (TF).Handle, STDin);πend;ππProcedure RedirectOutput (TextFile : String);ππVarπ    TF : Text;ππbeginπ    Assign (TF, TextFile);π    ReWrite (TF);π    Force_Dup (TextRec (TF).Handle, STdoUT);π    Force_Dup (TextRec (TF).Handle, STDERR);πend;ππProcedure StdInput;ππbeginπ    Assign (Input, '');π    Reset (Input);πend;ππProcedure StdOutPut;ππbeginπ    Assign (Output, '');π    ReWrite (Output);πend;ππend.ππ{------ cut here ------}π{πIn your Program :ππUses Redir;ππbeginπ     RedirectOutput ('LOGFile.OUT');π     Exec ('PKZIP.EXE', '');π     StdOutPut;πend.π}                                                                                                          5      05-28-9313:56ALL                      SWAG SUPPORT TEAM        REDIRCT3.PAS             IMPORT              32          {πMARK LEWISππ>> Still need a bit of help here.  I can't redirect output from aπ>> Program when executing it from a Pascal Program!  Is there anyπ>> this from Pascal? Any help would be greatly appreciated.π> if I understand you, you are using the Exec Procedure to run aπ> Program.  if that is the Case you won't be ablr to redirect sinceπ> this is a Function of Dos and not the Program you exec.  You willπ> need to run the Program through a child process in order toπ> perform the redirect, something like:π> Exec(GetEnv('COMSPEC'),'/C MyProg.exe>redirect');ππone could also utilize duplicate File handles -=B-)ππ}πUnit Execute;ππInterfaceππProcedure Exec(Path, CmdLine : String);ππImplementationππUsesπ  Dos;ππFunction ExtractFileName(Var Line : String; Index : Integer) : String;πVarπ  Temp : String;πbeginπ  Delete(Line, Index, 1);π  While (Index <= Length(Line)) and (Line[Index] = ' ') Doπ    Delete(Line, Index, 1);π  Temp := '';π  While (Index <= Length(Line)) and (Line[Index] <> ' ') Doπ  beginπ    Temp := Temp + Line[Index];π    Delete(Line, Index, 1);π  end;π  ExtractFileName := Temp;πend;ππProcedure CloseHandle(Handle : Word);πVarπ  Regs : Registers;πbeginπ  With Regs Doπ  beginπ    AH := $3E;π    BX := Handle;π    MsDos(Regs);π  end;πend;ππProcedure Duplicate(SourceHandle : Word;Var TargetHandle : Word);πVarπ  Regs : Registers;πbeginπ  With Regs Doπ  beginπ    AH := $45;π    BX := SourceHandle;π    MsDos(Regs);π    TargetHandle := AX;π  end;πend;ππProcedure ForceDuplicate(SourceHandle : Word;Var TargetHandle : Word);πVarπ  Regs : Registers;πbeginπ  With Regs Doπ  beginπ    AH := $46;π    BX := SourceHandle;π    CX := TargetHandle;π    MsDos(Regs);π    TargetHandle := AX;π  end;πend;ππProcedure Exec(Path,CmdLine : String);πVarπ  StdIn,π  Stdout    : Word;π  Index     : Integer;π  FName     : String[80];π  InFile,π  OutFile   : Text;π  InHandle,π  OutHandle : Word;π         { ===============>>>> }   { change below For STDERR }πbeginπ  StdIn  := 0;π  StdOut := 1;                    { change to 2 For StdErr       }π  Duplicate(StdIn, InHandle);      { duplicate standard input     }π  Duplicate(StdOut, OutHandle);    { duplicate standard output    }π  Index := Pos('>', CmdLine);π  if Index > 0 Then               { check For output redirection }π  beginπ    FName := ExtractFileName(CmdLine, Index);  { get output File name  }π    Assign(OutFile, FName);                    { open a Text File      }π    ReWrite(OutFile);                         { .. For output         }π    ForceDuplicate(TextRec(OutFile).Handle, StdOut);{ make output same }π  end;π  Index := Pos('<', CmdLine);π  if Index > 0 Then               { check For input redirection }π  beginπ    FName := ExtractFileName(CmdLine, Index);  { get input File name  }π    Assign(InFile, FName);                     { open a Text File     }π    Reset(InFile);                            { For input            }π    ForceDuplicate(TextRec(InFile).Handle, StdIn);  { make input same }π  end;π  Dos.Exec(Path, CmdLine);           { run EXEC }π  ForceDuplicate(InHandle, StdIn);   { put standard input back to keyboard }π  ForceDuplicate(OutHandle, StdOut); { put standard output back to screen  }π  CloseHandle(InHandle);            { close the redirected input File     }π  CloseHandle(OutHandle);           { close the redirected output File    }πend;ππend.ππ{===============================================================}π{πUse it exactly as you would the normal EXEC Procedure:ππ  Exec('MAsm.EXE','mystuff.Asm');ππTo activate redirection simply add the redirection symbols, etc:ππ  Exec('MAsm.EXE','mystuff.Asm >err.lst');πππOne note of caution.  This routine temporarily Uses extra handles. It'sπeither two or four more.  The Various books I have are not clear as toπwhether duplicated handles 'count' or not. My guess is yes.  if you don'tπplan on redirecting STDIN then remove all the code For duplicating it toπcut your handle overhead in half.π}ππ                   6      01-27-9412:19ALL                      FRED JOHNSON             Redirection              IMPORT              16     åu   {πHere's a neat little ditty I converted from a C++ tip I saw in a mag a fewπyears ago.  It tests to see if its own output has been redirected andπreturns a 1 if TRUE (redirected) or a 0 if FALSE (not redirected). Thisπfunction includes a sample prog that demonstrates its use. SIDE NOTE: Iπput this function in the U_FILE.pas.tpu for use with all of my home-grownπfile related functions and procedures.ππTEST WITH: Test_Red (enter)π   [you should see a NOT REDIRECTED msg, 10 lines and a FINISHED msg.]ππTEST WITH: Test_Red > this.dat (enter)π   [you should see a REDIRECTED msg, (no lines) and a FINISHED msgπ    and the output of the lines will be in the this.dat file]π}ππprogram test_red;ππ{$A+,B-,D-,E-,F-,G-,I+,L-,N-,O-,P-,Q-,R-,S+,T-,V+,X-}π{$M 1024,0,655360}ππ{*******************************************************************!HDR**π** Function Name: fn_bRedirected()π** Description  : Determines if output has been redirected;π** Returns      : Integer to be treated as boolean;π** Calls        :π** Special considerations:π** Modification history:π** Created: 11/03/93 20:23π*********************************************************************!END}ππfunction fn_bRedirected : Integer; Assembler; {Treated as BOOLEAN}πasmπ  push  dsπ  mov   ax,      prefixsegπ  mov   ds,      axπ  xor   bx,      bxπ  les   bx,      [bx + $34]π  mov   al,      es:[bx]π  mov   ah,      es:[bx +1]π  pop   dsπ  cmp   al,      ahπ  mov   ax,      1π  jne   @_exitπ  xor   ax,      axπ @_exit:π  {mov   @Result, AX}πend;ππvarπ  Count    : Byte;π  hOutFile : text;ππbeginπ  Assign(hOutFile, 'CON');π  ReWrite(hOutFile);π  if not (boolean(fn_bRedirected)) thenπ    writeln(hOutFile, 'Not Redirected')π  elseπ    writeln(hOutFile, 'Please wait while redirection is in progress');π  for Count := 1 to 10 doπ    writeln('Line ', Count : 2);π  writeln(hOutFile, 'Finished!');πend.π                                                   7      08-25-9409:10ALL                      TODD A. JACOBS           Redirect output          SWAG9408    ªb÷    12     åu   { From: tjacobs@clark.net (Todd A. Jacobs) }πunit Redir;π πinterfaceπ πusesπ  Dos;π πfunction SetOutput(FileName: PathStr): Boolean;πprocedure CancelOutput;π πimplementationπ πconstπ  OutRedir: Boolean = False;π πfunction SetOutput(FileName: PathStr): Boolean;πbeginπ  FileName:=FileName+#0;π  SetOutput:=False;π  asmπ    push  dsπ    mov   ax, ssπ    mov   ds, axπ    lea   dx, FileName[1]π    mov   ah, 3Chπ    int   21hπ    pop   dsπ    jnc   @@1π    retπ@@1:π    push  axπ    mov   bx, axπ    mov   cx, Output.FileRec.Handleπ    mov   ah, 46hπ    int   21hπ    mov   ah, 3Ehπ    pop   bxπ    jnc   @@2π    retπ@@2:π    int   21hπ  end;π  OutRedir:=True;π  SetOutput:=True;πend;ππprocedure CancelOutput;πvarπ  FileName: String[4];πbeginπ  if not OutRedir then Exit;π  FileName:='CON'#0;π  asmπ    push  dsπ    mov   ax, ssπ    mov   ds, axπ    lea   dx, FileName[1]π    mov   ax, 3D01hπ    int   21hπ    pop   dsπ    jnc   @@1π    retπ@@1:π    push  axπ    mov   bx, axπ    mov   cx, Output.FileRec.Handleπ    mov   ah, 46hπ    int   21hπ    mov   ah, 3Ehπ    pop   bxπ    int   21hπ  end;π  OutRedir:=False;πend;ππend.π{πStandard output will be changed to FileName. The FileName can be NUL.πWhen yourπexecuted program is using int $10, all is hardly. In your main program use:ππSetOutput('NUL');πExec(....);πCancelOutput;π}ππ                                                                               8      08-25-9409:11ALL                      MATTHEW MASTRACCI        EXEC with i/o redirectionSWAG9408    ╖└*ç    41     åu   {πFrom: Matthew.Mastracci@matrix.cpubbs.cuug.ab.ca (Matthew Mastracci)ππ tf> A simple example:π tf> SwapVectors;π tf> Exec (GetEnv('comspec'), '/c dir *.* > FileName');π tf> SwapVectors;ππThis is a good way to do redirection for directory listings and the like,πbut a better way is to use this unit:  (I wrote it from an idea given to me byπsomeone else posting the same sort of this, except this one includes errorπchecking and containm much more useful procedures)  From this, you can go:ππSwapVectors;πRedirectOutput('\DIRLIST.TXT');πExec(GetEnv('COMSPEC'), '/C DIR *.*');πStdOutput;πSwapVectors;ππSame thing, but more control...ππHere's my REDIR.PAS unit:ππ  Redirection unitππ  - Original author unknown, rewritten by Matthew Mastracciπ  - Added a bit of asm, pipe support, some better file handling ability, moreπ     flexibilityπ  - If you'd like some information on this program, E-Mail me at:π     madhacker@matrix.cpubbs.cuug.ab.caπ  - Feel free to distribute this source anywhere! (Public Domain)π}ππunit Redir;ππinterfaceππ{ Redirects standard input from a textfile/device  ie: command < filename }πprocedure RedirectInput(TextFile : String);ππ{ Redirects standard output to a textfile/device  ie: command > filename }πprocedure RedirectOutput(TextFile : String);ππ{ Redirects standard error to a textfile/device }πprocedure RedirectError(TextFile : String);ππ{ Redirects standard output and error to a textfile/device }πprocedure RedirectAllOutput(TextFile : String);ππ{ Redirects all I/O from a textfile  ie: ctty device }πprocedure RedirectAll(TextFile : String);ππ{ Restores STDIN to CON }πprocedure StdInput;ππ{ Restores STDOUT to CON }πprocedure StdOutput;ππ{ Restores STDERR to CON }πprocedure StdError;ππ{ Creates a unique file and returns its name (used for piping) }πfunction UniqueFile : String;ππimplementationππuses Dos;ππvar InFile, OutFile, ErrFile : Text;ππconstπ  STDIN  = 0;       { Standard Input }π  STDOUT = 1;       { Standard Output }π  STDERR = 2;       { Standard Error }π  Redirected : array[0..2] of Boolean = (False, False, False);ππ{ Duplicates a file handle }πprocedure ForceDup (Existing, Second : Word);πvar f, Error : Word;πbeginπ  asmπ    mov ah, $46π    mov bx, Existingπ    mov cx, Secondπ    int $21π    pushfπ    pop bxπ    mov f, bxπ    mov Error, axπ  end;π  if (f and FCarry) <> 0 thenπ    Writeln ('Error ', Error, ' changing handle ', Second);πend;ππ{ Redirects standard input from a textfile/device  ie: command < filename }πprocedure RedirectInput(TextFile : String);πbeginπ  if Redirected[STDIN] then StdInput;π  Redirected[STDIN] := True;π  Assign(InFile, TextFile);π  Reset(InFile);π  ForceDup(TextRec(InFile).Handle, STDIN);πend;ππ{ Redirects standard output to a textfile/device  ie: command > filename }πprocedure RedirectOutput(TextFile : String);πbeginπ  if Redirected[STDOUT] then StdOutput;π  Redirected[STDOUT] := True;π  Assign(OutFile, TextFile);π  Rewrite(OutFile);π  ForceDup(TextRec(OutFile).Handle, STDOUT);πend;ππ{ Redirects standard error to a textfile/device }πprocedure RedirectError(TextFile : String);πbeginπ  if Redirected[STDERR] then StdError;π  Redirected[STDERR] := True;π  Assign(ErrFile, TextFile);π  Rewrite(ErrFile);π  ForceDup(TextRec(ErrFile).Handle, STDERR);πend;ππ{ Redirects standard output and error to a textfile/device }πprocedure RedirectAllOutput(TextFile : String);πbeginπ  RedirectOutput(TextFile);π  RedirectError(TextFile);πend;ππ{ Redirects all I/O from a textfile  ie: ctty device }πprocedure RedirectAll(TextFile : String);πbeginπ  RedirectInput(TextFile);π  RedirectOutput(TextFile);π  RedirectError(TextFile);πend;ππ{ Restores STDIN to CON }πprocedure StdInput;πbeginπ  if Redirected[STDIN] then beginπ    Redirected[STDIN] := False;π    RedirectInput('CON');π    Close(InFile);π  end;πend;ππ{ Restores STDOUT to CON }πprocedure StdOutput;πbeginπ  if Redirected[STDOUT] then beginπ    Redirected[STDOUT] := False;π    RedirectOutput('CON');π    Close(OutFile);π  end;πend;ππ{ Restores STDERR to CON }πprocedure StdError;πbeginπ  if Redirected[STDERR] then beginπ    Redirected[STDERR] := False;π    RedirectOutput('CON');π    Close(OutFile);π  end;πend;ππfunction UniqueFile : String;πconst FName : array[1..20] of Char = '\' + #0 + '                  ';πvar FSeg, FOfs : Word;π    FileName : String;πbeginπ  FSeg := Seg(FName);π  FOfs := Ofs(FName) + 1;π  asmπ    push dsπ    mov ax, FSegπ    mov ds, axπ    mov dx, FOfsπ    mov ah, $5aπ    mov cx, 0π    int $21π    pop dsπ  end;π  Move(FName, FileName[1], 9);π  FileName[0] := #9;π  UniqueFile := FileName;πend;ππend.ππ{ This is how you can do piping.  It is equivilent to: }π{ type \autoexec.bat | find "ECHO" | sort /R }ππ{$M $1000,0,0}πprogram PipeDemo;πuses Redir, Dos;πvar FName : String;ππbeginπ  FName := UniqueFile;π  WriteLn('Temporary file: ', FName);π  WriteLn('Output from pipe:');π  RedirectInput('\AUTOEXEC.BAT');π  RedirectOutput(FName);π  Exec('C:\DOS\FIND.EXE', '"ECHO"');π  RedirectInput(FName);π  RedirectOutput('CON');π  Exec('C:\DOS\SORT.EXE', '/R');πend.π