[comp.os.msdos.programmer] How to detect redirection?

stever@Octopus.COM (Steve Resnick ) (08/08/90)

In article <1426@wet.UUCP> naga@wet.UUCP (Peter Davidson) writes:
>Let's say X.EXE is a program written in (Microsoft) C which
>calls printf() to output to the monitor.  Invoking X using
>X > PRN (or some file) redirects output to the printer (or file).
>Suppose that X does something (such as writing directly to video RAM)
>which it would not like to do if output has been redirected as above?
>How can it tell?  One solution is: Use printf() to output a charactr
>and then peek in the video RAM to see if the character went there
>(if so, no redirection).  The disadvantage is that, if redirection
>is in effect, a character (perhaps only a space) is sent to the
>printer (or file).  Is there a more elegant way to tell whether
>output has been redirected? 

That's not too elegant a solution: there is no guarantee that printf will
put the character in a specific memory location, and if I/O is redirected,
that character may already be on the screen. In C the easiest way to determine
if I/O has been redirected is to call isatty(fileno(stdout)) this returns
non-zero if the file descriptor associated with stdout is a character device.
The problem with this is the redirection may be associated with another
character device (AUX, PRN, etc). Is there an easy way to do THIS?

Cheers! 
Steve

-- 
----------------------------------------------------------------------------
steve.resnick@f105.n143.z1@FIDONET.ORG #include<std_disclaimer.h>
Flames, grammar errors, spelling errrors >/dev/nul
----------------------------------------------------------------------------

lai@math.sdsu.edu (Henry Lai ) (08/08/90)

In article <1426@wet.UUCP> naga@wet.UUCP (Peter Davidson) writes:
> Let's say X.EXE is a program written in (Microsoft) C which
> calls printf() to output to the monitor.  Invoking X using
> X > PRN (or some file) redirects output to the printer (or file).
> Suppose that X does something (such as writing directly to video RAM)
> which it would not like to do if output has been redirected as above?
> How can it tell?  One solution is: Use printf() to output a charactr
> and then peek in the video RAM to see if the character went there
> (if so, no redirection).  The disadvantage is that, if redirection
> is in effect, a character (perhaps only a space) is sent to the
> printer (or file).  Is there a more elegant way to tell whether
> output has been redirected? 

	isatty (fileno (stdout))
will return zero if stdout has been redirected to a file. See the
reference to isatty in your run-time library reference.
--
Henry Lai
Internet: lai@math.sdsu.edu
    UUCP: {mcgill-vision,sobeco,uunet}!batcave!lai

jstone@world.std.com (Jeffrey R Stone) (08/08/90)

lai@math.sdsu.edu (Henry Lai ) writes:

>In article <1426@wet.UUCP> naga@wet.UUCP (Peter Davidson) writes:
    [ question about how to detect that stdout has been redirected ]

>	isatty (fileno (stdout))
>will return zero if stdout has been redirected to a file. See the
>reference to isatty in your run-time library reference.

According to Turbo C's library reference, isatty() returns TRUE if 
it argument file pointer is a character devuce - A tty - not necessarily
THE tty.

-jeff-

dmurdoch@watstat.uwaterloo.ca (Duncan Murdoch) (08/08/90)

In article <1990Aug8.004304.26989@Octopus.COM> stever@octopus.UUCP (Steve Resnick ) writes:
>that character may already be on the screen. In C the easiest way to determine
>if I/O has been redirected is to call isatty(fileno(stdout)) this returns
>non-zero if the file descriptor associated with stdout is a character device.
>The problem with this is the redirection may be associated with another
>character device (AUX, PRN, etc). Is there an easy way to do THIS?

Use the IOCTL service from DOS.  To quote Ralf Brown's interrupt list:

INT 21 - DOS 2+ - IOCTL - GET DEVICE INFORMATION
        AX = 4400h
        BX = file or device handle
Return: CF set on error
           AX = error code (see AH=59h)
        CF clear if successful
           DX = device info
           If bit 7 set: (character device)
                   1: console output device
                   2: NUL device
                   3: CLOCK$ device
                   4: device is special (uses INT 29)
                   5: binary (raw) mode
                   6: Not EOF
                  12: network device (DOS 3+)
                  14: can process IOCTL control strings (see AL = 02h-05h)
           If bit 7 clear: (file)
               bits 0-5 are block device number
                   6: file has not been written
                  12: network device (DOS 3+)
                  14: can process IOCTL control strings (DOS 3+)
                  15: file is remote (DOS 3+)
SeeAlso: AX=4401h, INT 2F/AX=122Bh


Duncan Murdoch

shurr@cbnews.att.com (Larry A. Shurr) (08/09/90)

In article <1990Aug8.030621.24021@world.std.com> jstone@world.std.com (Jeffrey R Stone) writes:
}lai@math.sdsu.edu (Henry Lai ) writes:
}
}}In article <1426@wet.UUCP> naga@wet.UUCP (Peter Davidson) writes:
}    [ question about how to detect that stdout has been redirected ]

}}	isatty (fileno (stdout))
}}will return zero if stdout has been redirected to a file. See the
}}reference to isatty in your run-time library reference.

}According to Turbo C's library reference, isatty() returns TRUE if 
}it argument file pointer is a character devuce - A tty - not necessarily
}THE tty.

As does Turbo C++.  I don't have the canonical list of interrupts or any
other suitable reference in front of me, but if memory serves, you can
do an ioctl on fileno(stdout) to get device information which includes a
bit which identifies whether or not the device is the console.  Presum-
ably, you can assume that if fileno(stdout) is a file or is a character
device other than the console, then stdout is redirected.  Borland
provides an ioctl() function you can use for this.

I think that the original question referred to MicroSoft C, but its
isatty() may have the same characteristic as Borland's.

regards, Larry
-- 
Larry A. Shurr (cbnmva!las@att.ATT.COM or att!cbnmva!las)
The end of the world has been delayed due to a shortage of trumpet players.
(The above reflects my opinions, not those of AGS or AT&T, but you knew that.)