Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

stdout: terminal, file, or pipe?

27 views
Skip to first unread message

Ulrich Lauther

unread,
May 29, 2005, 5:30:47 PM5/29/05
to

I didn't find an answer in the unix-programming-faq:

How can I find out wether stdout goes to the terminal or was redirected to a
file or a pipe (under Unix, and, well, slightly off topic, also under Windows) ?

--
-lauther

[nosave]
----------------------------------------------------------------------------
Ulrich Lauther ph: +49 89 636 48834 fx: ... 636 42284
Siemens CT SE 6 Internet: Ulrich....@siemens.com

Jens.T...@physik.fu-berlin.de

unread,
May 29, 2005, 5:45:17 PM5/29/05
to
Ulrich Lauther <lau...@mchp.siemens.de> wrote:

> I didn't find an answer in the unix-programming-faq:

> How can I find out wether stdout goes to the terminal or was redirected to a
> file or a pipe (under Unix, and, well, slightly off topic, also under
> Windows) ?

I don't now about Windows, but under Unix there's isatty(3). Takes
the file descriptor as its single argument and returns 1 if it's
a terminal and 0 otherwise (i.e. a file, a pipe or a socket etc.).
Of course it can be "fooled" when the output does not go to a "real"
terminal but a pseudo-terminal (pty) - but that's what pseudo-termi-
nals where invented for;-) Since istty() is in a POSIX function
chances are probably rather good that it's also available under
Windows.
Regards, Jens

--
\ Jens Thoms Toerring ___ Jens.T...@physik.fu-berlin.de
\__________________________ http://www.toerring.de

Chris McDonald

unread,
May 29, 2005, 5:57:08 PM5/29/05
to
Ulrich Lauther <lau...@mchp.siemens.de> writes:


>I didn't find an answer in the unix-programming-faq:

>How can I find out wether stdout goes to the terminal or was redirected to a
>file or a pipe (under Unix, and, well, slightly off topic, also under Windows) ?

Under Unix, this once worked:

______________________________________________________________________________
Dr Chris McDonald E: ch...@csse.uwa.edu.au
Computer Science & Software Engineering W: http://www.csse.uwa.edu.au/~chris
The University of Western Australia, M002 T: +618 6488 2533
Crawley, Western Australia, 6009 F: +618 6488 1089

#include <stdio.h> /* ch...@budgie.csse.uwa.edu.au - May 1992 */
#include <errno.h>
#include <sys/file.h>

static char *desc[] = {
"invalid",
"a file",
"a pipe",
"a tty"
};

typedef enum { FD_INVALID, FD_FILE, FD_PIPE, FD_TTY } FD_TYPE;

static FD_TYPE determine(int fd)
{
if(isatty(fd))
return(FD_TTY);
if(flock(fd,LOCK_NB) != 0) {
if(errno == EBADF)
return(FD_INVALID);
if(errno == EOPNOTSUPP)
return(FD_PIPE);
}
return(FD_FILE);
}

int main(int argc, char *argv[])
{
printf("%s\n", desc[(int)determine(1)]);
return(0);
}

Vitaly Filatov

unread,
Jun 1, 2005, 4:43:23 AM6/1/05
to
Hi!

Under Solaris file locking is not convenient. Under Solaris (SVR4) you
may use:

----------------- typeof_file.c ---------------
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>

static char *desc[] = {
"invalid",
"a file",
"a pipe",
"a tty"
};

typedef enum { FD_INVALID, FD_FILE, FD_PIPE, FD_TTY } FD_TYPE;

static FD_TYPE determine(FILE *stream)
{
fpos_t pos;

if (isatty(fileno(stream)))
return (FD_TTY);

if (fgetpos(stream, &pos)) {
switch (errno) {
case ESPIPE:
return (FD_PIPE);
case EBADF:
case EOVERFLOW:
perror("");
return (FD_INVALID);
}
}

return (FD_FILE);
}

int main(int argc, char *argv[])
{

fprintf(stderr, "%s\n", desc[determine(stdout)]);
return (0);

}
----------------- typeof_file.c ---------------

$ gcc -Wall -o typeof_file typeof_file.c

$ typeof_file
a tty
$ typeof_file | cat
a pipe
$ typeof_file > a
a file
$

Vitaly Filatov
http://members.tripod.com/Vitaly_Filatov

0 new messages