[comp.unix.programmer] How to determine the destination of standard output?

ping@cubmol.bio.columbia.edu (Shiping Zhang) (02/07/91)

I'm not sure if this subject has be discussed before. I want to know
if there is a way to tell within a program where its standard output
goes. More specifically, if the output goes to the terminal screen, or
goes to a pipe, or is redirected into a disk file. Thanks for any info.

-ping

yang@nff.ncl.omron.co.jp (YANG Liqun) (02/08/91)

<ping@cubmol.bio.columbia.edu(Shiping Zhang)> writes:

>I'm not sure if this subject has be discussed before. I want to know
>if there is a way to tell within a program where its standard output
>goes. More specifically, if the output goes to the terminal screen, or
>goes to a pipe, or is redirected into a disk file. Thanks for any info.

If you want to if the standard output is terminal, use ttyname() or isatty.
Otherwise, use
     #include <sys/types.h>
     #include <sys/stat.h>

     fstat(fd, buf)
     int fd;
     struct stat *buf;

check buf->st_mode. 
--
-------------------------------------------------------------------------------
|		Yang Li-qun                                                   |
|		OE, OMRON Corporation                                         |
|		20, Igadera Shimokaiinji Nagaokakyo-City                      |
|		Kyoto 617 Japan                                               |
|		Tel: 075-951-5111  Fax: 075-956-7403                          |
|  		E-mail:yang@nff.ncl.omron.co.jp                               |
-------------------------------------------------------------------------------

darko@hpfcdc.HP.COM (David Arko) (02/08/91)

Any easy way to know if a file descriptor is going to a tty is to use
the isatty(3C) library call on it (ie. if(isatty(1)) ...)

To check if it is going to a pipe, you may have to use the
stat(2),stat(5) (or actually fstat()) system call on file descriptor 1,
and look at the st_mode field, in particular, the S_IFIFO bit field
to tell if stdout is a pipe.  The st_mode field will also tell you if
it is going to a character or block device, or if it is a regular
file... all you ever wanted to know and more..., see the man page for
more detailed

-- David (darko@hpfcrn.fc.hp.com)

bernie@metapro.DIALix.oz.au (Bernd Felsche) (02/09/91)

In <1991Feb6.204432.2850@cubmol.bio.columbia.edu> ping@cubmol.bio.columbia.edu (Shiping Zhang) writes:

>I'm not sure if this subject has be discussed before. I want to know
>if there is a way to tell within a program where its standard output
>goes. More specifically, if the output goes to the terminal screen, or
>goes to a pipe, or is redirected into a disk file. Thanks for any info.

Refer to fstat(2) for System V.

This gives you inode info for a file descriptor.

There is also isatty(3), which tells you if it is.

-- 
 _--_|\  Bernd Felsche         #include <std/disclaimer.h>
/      \ Metapro Systems, 328 Albany Highway, Victoria Park,  Western Australia
\_.--._/ Fax: +61 9 472 3337   Phone: +61 9 362 9355  TZ=WST-8
      v  E-Mail: bernie@metapro.DIALix.oz.au | bernie@DIALix.oz.au

guy@auspex.auspex.com (Guy Harris) (02/10/91)

>To check if it is going to a pipe, you may have to use the
>stat(2),stat(5) (or actually fstat()) system call on file descriptor 1,
>and look at the st_mode field, in particular, the S_IFIFO bit field
>to tell if stdout is a pipe.

Well, that works on many systems, but not all systems; a better test for
"is this a pipe" may be to do "lseek(fd, 0L, 1)" and see if it fails
setting "errno" to ESPIPE.

>The st_mode field will also tell you if it is going to a character or
>block device, or if it is a regular file...

Yup, and note that the correct way to test for a given file type is

	if ((statbuf.st_mode & S_IFMT) == <the type>)

*NOT*

	if (statbuf.st_mode & <the type>)

Most of you probably already know that, but every so often I see code
written by somebody who didn't, so....

If you have a POSIX-conforming system, you should use the "S_ISxxx"
macros to test for a given file type instead.