[comp.sys.ibm.pc] How to determine stdin/out redirection

Steve_R_Calwas@cup.portal.com (09/26/88)

One quick question:

Is there a way for an application program to determine whether or not its
standard input and/or standard output are being redirected?

Thanks.


Steve Calwas                            src@cup.portal.com
Santa Clara, CA                         ...!sun!cup.portal.com!src

Developments

creps@silver.bacs.indiana.edu (Steve Creps) (09/26/88)

In article <9465@cup.portal.com> Steve_R_Calwas@cup.portal.com writes:
>Is there a way for an application program to determine whether or not its
>standard input and/or standard output are being redirected?

   Try
	if (!isatty(fileno(stdin))) {
		/* stdin is being redirected */
	}
and similarly for stdout. That's assuming you're using C.

-	-	-	-	-	-	-	-	-	-
Steve Creps, Indiana University, Bloomington, home of the "Hoosiers"
	creps@silver.bacs.indiana.edu (192.12.206.2)
	{inuxc,rutgers,pyramid,pur-ee}!iuvax!silver!creps
	creps@iubacs.bitnet (forwarded)

tr@wind.bellcore.com (tom reingold) (09/27/88)

In article <9465@cup.portal.com> Steve_R_Calwas@cup.portal.com writes:
$ 
$ One quick question:
$ 
$ Is there a way for an application program to determine whether or not its
$ standard input and/or standard output are being redirected?

If you are using a C compiler, you can use the isatty() function
which says if something is a tty.  If not, then it's being redirected.

This is is not a read-the-f_cking-manual reminder since I suspect
you didn't know about the existance of isatty() until now.  Now
that you do, I am sure you will enjoy reading all about it.

Tom Reingold
PAPERNET:                      |INTERNET:       tr@bellcore.bellcore.com
Bell Communications Research   |UUCP-NET:       bellcore!tr
445 South St room 2L350        |SOUNDNET:       (201) 829-4622 [work],
Morristown, NJ 07960-1910      |                (201) 287-2345 [home]

toma@tekgvs.GVS.TEK.COM (Tom Almy) (09/27/88)

In article <9465@cup.portal.com> Steve_R_Calwas@cup.portal.com writes:
>Is there a way for an application program to determine whether or not its
>standard input and/or standard output are being redirected?

I saw several followups to this that answered the question for C users
(or at least C users with certain unspecified C compilers).  But there
is a way to find out this information without resorting to the magic
of C.

Set AH to 44h, AL to 0, BX to the handle number (0 for standard input,
1 for standard output, 2 for standard error, 3 for AUX (com1), or 4 for
PRN (typically LPT1).  Execute an INT 21H.  If the carry flag is set
then an error code is in AX.  The only valid error for this operation
is 6 = handle not open.  If the carry flag is clear then all goes well.

DX will have the following information:

If bit 7 is 1, then a character device (keyboard, display, serial port,
or parallel port) and:
Bit 14 -- Can process control strings (not too interesting)
Bit 6 -- End of file on input
Bit 5 -- binary/raw mode (no special control character handling)
Bit 3 -- clock device
BIt 2 -- NUL device
bit 1 -- console output device
bit 0 -- console input device

If bit 7 is 0, then it is a block device (disk) and:
bit 6 -- file has been written
bits 0-5 -- drive number, 0 = A, 1 = B, etc.



There, that's more information than just "isatty".

Tom Almy
toma@tekgvs.TEK.COM
Standard Disclaimers Apply

cramer@optilink.UUCP (Clayton Cramer) (09/27/88)

In article <9465@cup.portal.com>, Steve_R_Calwas@cup.portal.com writes:
> 
> Is there a way for an application program to determine whether or not its
> standard input and/or standard output are being redirected?
> 
> Steve Calwas                            src@cup.portal.com

It's not 100% foolproof, but use the isatty(fileno(stdin)) function
to determine if stdin is talking to a character device -- this is a
pretty trustworthy method.  If true, you are almost certainly talking
to the console, and stdin is not redirected.

-- 
Clayton E. Cramer
..!ames!pyramid!kontron!optilin!cramer

mrk@gvgspd.GVG.TEK.COM (Michael R. Kesti) (09/28/88)

In article <9465@cup.portal.com> Steve_R_Calwas@cup.portal.com writes:
>
>Is there a way for an application program to determine whether or not its
>standard input and/or standard output are being redirected?

Well, lots of people seem to know how to do this in C, but if you wanted
to do it in assembler, here's how I determined the status of stdout in a
replacement for uSoft's (brain dead) MORE command that I wrote.  The
technique is similiar for stdin.

The information is available through the IOCTL function (44H) of the DOS
function interrupt (21H).  The following code demonstrates this:

	mov	ah,44H			; I/O control function
	mov	al,0			; get device information subfunction
	mov	bx,01H			; standard output device
	int	21H			; get standard output information
	test	dx,0000000010000000B	; is standard output a file?
	jz	init_05			; yes - set flag

	jmp	init_10			; no - clear flag

init_05:
	mov	file_flag,0FFH		; indicate standard output is a file
	jmp	init_15			; continue

init_10:
	mov	file_flag,00H		; indicate standard output is a pipe

init_15:


I got this info from Norton's _Programmer's Guide to the IBM PC_.  See
chapter 17, pages 311-313.

One more note - Norton indicates this wasn't available prior to version 2.0.

-- 
============================================================================
Michael Kesti  Grass Valley Group, Inc. | "Like one and one don't make two,
    @gvgspd.GVG.TEK.COM                 |  one and one make one."
    !tektronix!gvgpsa!gvgspd!mrk        |         - The Who, Bargain

dixon@control.steinmetz (walt dixon) (09/29/88)

There have been a number of proposed solutions to determining whether StdIn
and/or StdOut have been redirected.  All these solutions rely in one way
or another on device attributes.  MS-DOS records device attributes in
a data structure called the system file table (SFT) when it opens the
file/device.  Some attributes come directly from the attributes word of
the device (IsStdIn, IsStdOut, IsCurClk, etc);  others are maintained by
DOS (eof, binary mode).  Looking at device attributes is not a fool proof
way of determining redirection.  One could redirect StdOut to a printer.

There are a couple of other data structures which help solve this problem.
Every DOS program has a Program Segment Prefix (PSP).  The PSP contains the
address of a Job File Table (JFT).  The JFT is normally contained in the PSP,
but DOS 3.3 and above allow one to move the JFT.  The JFT is an array of bytes
indexed by file handle.  Each JFT contains a one byte System File Number or
SFN or a 0xff if the handle is not used.  The SFN is in turn an index into
the System File Table.  Most C run time environments use handles for file
access.  Using an IOB or similar structure,  the C run time can translate
a file descriptor into a DOS handle.  (For files that are opened by FCB,
one of the undocumented FCB fields contains the SFN).

DOS opens the console device in the boot process.  SFN=0 corresponds to
the console device.  Command.com reopens the console device for StdIn
and StdOut.  The JFT entries corresponding to StdIn and StdOut (JFT[0]]
and JFT[1] respectively) will contain a 0 in the absence of redirection.
By looking within the SFT entry,  one can actually find the name of the
device/file.  Unfortunately,  any path name information is lost after
the file is opened.

Much of this information comes from disassebling DOS.  I've described these
data structures in Chapters 10 and 11 of "The MS-DOS Papers" (Howard Sams,
1988) and Chapter 4 of the 2nd edition of "The MS-DOS Developer's Guide
(Howard Sams, late '88?).  NB I get no royalties;  just citing a good
reference.

I hope this helps.  Standard disclaimers apply.

Walt Dixon		{ARPA:		Dixon@GE-CRD.ARPA	}
			{US Mail:	GE Corp R&D		}
			{		PO Box 8		}
			{		Schenectady, NY 12345	}
			{Phone:		518-387-5798		}

bradc@cognos.uucp (Brad Cameron) (09/30/88)

In article <9465@cup.portal.com> Steve_R_Calwas@cup.portal.com writes:
>Is there a way for an application program to determine whether or not its
>standard input and/or standard output are being redirected?
>

Microsoft C has a library function called isatty which can be used for
this purpose.  The following function will return non-zero if neither
standard input or standard output are redirected:

int  Interactive ()
{
	 return isatty ( fileno (stdin) ) && isatty ( fileno (stdout) );
}

-- 
Brad Cameron          uucp: decvax!utzoo!dciem!nrcaer!cognos!bradc
Cognos Incorporated   mail: P.O. Box 9707, 3755 Riverside Drive, 
 (613) 738-1440             Ottawa Ontario, Canada. K1G 3Z4

Ralf.Brown@B.GP.CS.CMU.EDU (09/30/88)

In article <12265@steinmetz.ge.com>, dixon@control.steinmetz (walt dixon) writes:
}DOS opens the console device in the boot process.  SFN=0 corresponds to
}the console device.  Command.com reopens the console device for StdIn
}and StdOut.  The JFT entries corresponding to StdIn and StdOut (JFT[0]]
}and JFT[1] respectively) will contain a 0 in the absence of redirection.
}By looking within the SFT entry,  one can actually find the name of the
}device/file.  Unfortunately,  any path name information is lost after
}the file is opened.

This must vary from version to version, because for DOS 3.1, SFN[0] is AUX and
SFN[1] is CON.  In the absence of redirection, the first five entries in the
JFT are 1, 1, 1, 0, and 2.
--
UUCP: {ucbvax,harvard}!cs.cmu.edu!ralf -=-=-=- Voice: (412) 268-3053 (school)
ARPA: ralf@cs.cmu.edu  BIT: ralf%cs.cmu.edu@CMUCCVMA  FIDO: Ralf Brown 1:129/31
Disclaimer? I     |Ducharm's Axiom:  If you view your problem closely enough
claimed something?|   you will recognize yourself as part of the problem.

maddoxt@novavax.UUCP (Thomas Maddox) (10/05/88)

	This talk of device drivers reminds me of a problem a gentleman
has asked about locally.  Can he remove ansi.sys from memory without
rebooting?  
	If so, can the process be described simply enough for me to
transmit the information to him?
	Thanks in advance.