[comp.os.msdos.programmer] Sensing STDOUT redirection in C

collinsa@p4.cs.man.ac.uk (Adrian Collins) (04/15/91)

I am currently writing a program for the PC using C.  I need to be able
to sense whether STDOUT has been redirected on the command line.  In the
case where the output has not been redirected the program opens a text
window and displays the info in that window, but if output redirection
was used I want the program to output to STDOUT as it should assume that
the output is to be sent to a file.

Does anybody know how to sense whether output redirection has been used
on the command line?

Adrian

---
Adrian Collins                              collinsa@uk.ac.man.cs.p4
Department of Computer Science              a.m.collins@uk.ac.mcc
University of Manchester
Manchester,                                 "Let me face the peril"
UK.                                         "No, it's too perilous!"
                                                    - The Holy Grail

valley@gsbsun.uchicago.edu (Doug Dougherty) (04/16/91)

collinsa@p4.cs.man.ac.uk (Adrian Collins) writes:

>I am currently writing a program for the PC using C.  I need to be able
>to sense whether STDOUT has been redirected on the command line.  In the
>case where the output has not been redirected the program opens a text
>window and displays the info in that window, but if output redirection
>was used I want the program to output to STDOUT as it should assume that
>the output is to be sent to a file.

>Does anybody know how to sense whether output redirection has been used
>on the command line?

isatty(1)

(Works in Turbo C)
--

	(Another fine mess brought to you by valley@gsbsun.uchicago.edu)

jja@wsl.ie (John Allen on wsl) (04/16/91)

if (isatty(1))
	{
	// has been redirected
	}
else 
	{
	// has not been redirected
	}
-- 
People that don't know want to know from the people that do know and if the 
poeple that do know don't tell the people that don't know then the people
that don't know still won't know.
				   "Don't quote me on any issue whatsoever."

jja@wsl.ie (John Allen on wsl) (04/16/91)

Sorry that last post was incorrect.

if (isatty(1))
	{
	// has not been redirected
	}
else
	{
	// has been redirected
	}

Sorry for any confusion caused.

-- 
People that don't know want to know from the people that do know and if the 
poeple that do know don't tell the people that don't know then the people
that don't know still won't know.
				   "Don't quote me on any issue whatsoever."

jwbirdsa@amc.com (James Birdsall) (04/18/91)

In article <1991Apr16.145847.20316@midway.uchicago.edu> valley@gsbsun.uchicago.edu (Doug Dougherty) writes:
>collinsa@p4.cs.man.ac.uk (Adrian Collins) writes:
>>Does anybody know how to sense whether output redirection has been used
>>on the command line?
>isatty(1)
>(Works in Turbo C)

   Well, almost. isatty() returns true if the supplied handle is the
console *or* a printer or serial port. Determining whether the handle is
actually the console or not requires an ioctl() and checking some bits.

-- 
James W. Birdsall   WORK: jwbirdsa@amc.com   {uunet,uw-coco}!amc-gw!jwbirdsa
HOME: {uunet,uw-coco}!amc-gw!picarefy!jwbirdsa OTHER: 71261.1731@compuserve.com
================== Kitten: a small homicidal muffin on legs. ==================
=========== "For it is the doom of men that they forget." -- Merlin ===========

session@seq.uncwil.edu (Zack C. Sessions) (04/19/91)

collinsa@p4.cs.man.ac.uk (Adrian Collins) writes:

>I am currently writing a program for the PC using C.  I need to be able
>to sense whether STDOUT has been redirected on the command line.  In the
>case where the output has not been redirected the program opens a text
>window and displays the info in that window, but if output redirection
>was used I want the program to output to STDOUT as it should assume that
>the output is to be sent to a file.

>Does anybody know how to sense whether output redirection has been used
>on the command line?

Even though I have the Power C for MS-DOS (you didn't mention which
one you are using) I use it very seldom. I do most of my C programming
with the Microware C Compiler for OS-9 Level 2. With it you can tell
the difference by using a system call which returns the name of the
device which a path is opened up to. There are only certain types of
devices which are window devices and disk devices. If the STDOUT
path is a window device, it has not been re-directed (normally)
and if it is a disk device it definitely has been re-direected. Some
others here may flame you (and me) for posting such information
on a discussion on "pure C" topics and to machine or OS dependent
type questions and answers.

If there is some portable valid method for doing this type of operation,
I'd certainly be interested in hearing about it.

Zack Sessions
session@seq.uncwil.edu

valley@gsbsun.uchicago.edu (Doug Dougherty) (04/19/91)

jwbirdsa@amc.com (James Birdsall) writes:

>In article <1991Apr16.145847.20316@midway.uchicago.edu> valley@gsbsun.uchicago.edu (Doug Dougherty) writes:
>>collinsa@p4.cs.man.ac.uk (Adrian Collins) writes:
>>>Does anybody know how to sense whether output redirection has been used
>>>on the command line?
>>isatty(1)
>>(Works in Turbo C)

>   Well, almost. isatty() returns true if the supplied handle is the
>console *or* a printer or serial port. Determining whether the handle is
>actually the console or not requires an ioctl() and checking some bits.

Someone else pointed this out to me in email as well.  Yes, this is only
a 90% solution.  Actually, I think, in DOS, isatty() returns true iff
the handle refers to a *character device* (my emphasis).  Which includes
of course, not only CON, COMx, PRN, but also NUL as well as any installed
character devices.

Still, I think it handles most of the occurrences, since what most users
are concerned about is redirection to a file anyway.  And the original
poster did refer to TurboC specifically, and isatty() does have the
virtue of being a regular TC built-in function.

--

	(Another fine mess brought to you by valley@gsbsun.uchicago.edu)

collinsa@p4.cs.man.ac.uk (Adrian Collins) (04/23/91)

In <1991Apr18.165820.6035@amc.com> jwbirdsa@amc.com (James Birdsall) writes:

>In article <1991Apr16.145847.20316@midway.uchicago.edu> valley@gsbsun.uchicago.edu (Doug Dougherty) writes:
>>collinsa@p4.cs.man.ac.uk (Adrian Collins) writes:
>>>Does anybody know how to sense whether output redirection has been used
>>>on the command line?
>>isatty(1)
>>(Works in Turbo C)

>   Well, almost. isatty() returns true if the supplied handle is the
>console *or* a printer or serial port. Determining whether the handle is
>actually the console or not requires an ioctl() and checking some bits.

This is what I actually wanted to do, although I didn't really make it
very clear in my original article.

As I've had quite a few requests for responses to my original query, here
is a method of working out whether STDIN and STDOUT are being redirected.
This is a slightly altered version of the code sent to me by
Nick FitzGerald. 

unsigned int get_device_data(int handle)
{
union REGS regs;

regs.h.ah = 0x44;           /*  function number  */
regs.h.al = 0;              /*  subfunction number  */
regs.x.bx = handle;         /*  file or device handle  */
int86(0x21,&regs,&regs);
return ( regs.x.dx );
}

int output_redirected()
{
return ( ( get_device_data(fileno(stdout)) & 0x82 ) != 0x82 );
}

int input_redirected()
{
return ( ( get_device_data(fileno(stdin)) & 0x81) != 0x81 );
}

The masks have been altered to 0x81 & 0x82 from 0x01 and 0x02, so that the
code correctly senses output redirected to a file.

Thanks to everybody for your help.

Cheers,
  Adrian
---
Adrian Collins                              collinsa@uk.ac.man.cs.p4
Department of Computer Science              a.m.collins@uk.ac.mcc
University of Manchester
Manchester,                                 "Let me face the peril"
UK.                                         "No, it's too perilous!"
                                                    - The Holy Grail

bright@nazgul.UUCP (Walter Bright) (04/27/91)

In article <collinsa.671721083@p4.cs.man.ac.uk> collinsa@p4.cs.man.ac.uk (Adrian Collins) writes:
/Does anybody know how to sense whether output redirection has been used
/on the command line?

	if (!isatty(fileno(stdin)))
		/* input has been redirected to a block device */

cctr132@csc.canterbury.ac.nz (Nick FitzGerald, CSC, Uni. of Canterbury, NZ) (04/29/91)

In article <collinsa.672410890@p4.cs.man.ac.uk>, collinsa@p4.cs.man.ac.uk
(Adrian Collins) writes:
>[deletions] 
> As I've had quite a few requests for responses to my original query, here
> is a method of working out whether STDIN and STDOUT are being redirected.
> This is a slightly altered version of the code sent to me by
> Nick FitzGerald. 

Adrian should have pointed out that the code I sent him was posted late
last year (to this group ?) by Peter Davidson.

If Peter's still reading along, thanks and apologies (I'm presumptuous
enough to extend apologies on Adrian's behalf as well, 8-) ).

Nick.

collinsa@p4.cs.man.ac.uk (Adrian Collins) (04/29/91)

In <1991Apr29.141357.523@csc.canterbury.ac.nz> cctr132@csc.canterbury.ac.nz (Nick FitzGerald, CSC, Uni. of Canterbury, NZ) writes:

>Adrian should have pointed out that the code I sent him was posted late
>last year (to this group ?) by Peter Davidson.

>If Peter's still reading along, thanks and apologies (I'm presumptuous
>enough to extend apologies on Adrian's behalf as well, 8-) ).

Oops.  sorry about that.  Thanks Peter Davidson, and sorry about that
Nick.

Adrian