Detecting a PIPE in a program

S

Stu

I have the following code in a "C" program.

test_prog.c
main()
{
while ( fgets ( buffer, sizeof(buffer), stdin) != NULL)
{
.....
.....
}
}


I want to run the program like this:

ls | test_prog

Is there anyway I can detect in my program if I am being feed
("PIPPED") data.

If I just run my program like this:

test_prog

it sits and waits. I want to put the smarts in it to see if it is
actually getting data feed to it. If not, than I can take action.

Ant sample "C" code tidbets would be appreciated.
Thanks in advance for all that answer this post!!
 
R

Richard Tobin

Stu said:
Is there anyway I can detect in my program if I am being feed
("PIPPED") data.

I think you mean PIPED :) And probably what you really want to know
is whether the input is a terminal; a file should most likely be
treated the same way as a pipe.

Anyway, there's no way to do this in standard C. Your operating
system may provide a way to do it. For example, in unix you can
determine whether stdin is a terminal by using isatty(0).

-- Richard
 
C

CBFalconer

Stu said:
I have the following code in a "C" program.

test_prog.c
main()
{
while ( fgets ( buffer, sizeof(buffer), stdin) != NULL)
{
....
....
}
}

I want to run the program like this:

ls | test_prog

Is there anyway I can detect in my program if I am being feed
("PIPPED") data.

If I just run my program like this:

test_prog

it sits and waits. I want to put the smarts in it to see if it is
actually getting data feed to it. If not, than I can take action.

Here is a non-portable routine I use for the purpose. It gets
called with something like "if (akeyboard(stdin)) helpandquit();"
It also works with TC2.01 from the Borland museum.

/* ------------------- */

/* This is very likely to be non-portable */
/* DOES NOT check fp open for reading */
/* NULL fp is considered a keyboard here! */
static int akeyboard(FILE *fp)
{
#ifndef __TURBOC__
# ifdef __STDC__
/* This dirty operation allows gcc -ansi -pedantic */
extern int fileno(FILE *fp);
extern int isatty(int fn);
# endif
#endif
return ((fp != NULL) && isatty(fileno(fp)));
} /* akeyboard */
 
R

Richard Bos

CBFalconer said:
/* This is very likely to be non-portable */
/* DOES NOT check fp open for reading */
/* NULL fp is considered a keyboard here! */
static int akeyboard(FILE *fp)
{
#ifndef __TURBOC__
# ifdef __STDC__
/* This dirty operation allows gcc -ansi -pedantic */
extern int fileno(FILE *fp);
extern int isatty(int fn);

Only "very likely" to be non-portable?

Richard
 
K

Keith Thompson

CBFalconer said:
Here is a non-portable routine I use for the purpose. It gets
called with something like "if (akeyboard(stdin)) helpandquit();"
It also works with TC2.01 from the Borland museum.

/* ------------------- */

/* This is very likely to be non-portable */
/* DOES NOT check fp open for reading */
/* NULL fp is considered a keyboard here! */
static int akeyboard(FILE *fp)
{
#ifndef __TURBOC__
# ifdef __STDC__
/* This dirty operation allows gcc -ansi -pedantic */
extern int fileno(FILE *fp);
extern int isatty(int fn);
# endif
#endif
return ((fp != NULL) && isatty(fileno(fp)));
} /* akeyboard */

Why do you declare the fileno() and isatty() functions rather than
#include'ing whatever header declares them?
 
C

CBFalconer

Richard said:
Only "very likely" to be non-portable?

Yup, in the sense that it has a finite chance of failing on your
conforming system. Would you rather I claimed it to be portable,
or didn't even mention it?
 
C

CBFalconer

Keith said:
Why do you declare the fileno() and isatty() functions rather than
#include'ing whatever header declares them?

Because they live in headers in which they are disabled by -ansi
-pedantic. I know about this location, and I want the warnings
elsewhere in the code. I even commented that.
 
M

Mysidia

Stu said:
Is there anyway I can detect in my program if I am being feed
("PIPPED") data.

Maybe.. depending on platform. In the *nix world, you could
try something like this:

.. #include <stdio.h>
.. #include <unistd.h>
.. #include <sys/stat.h>

.. int main()
.. {
.. struct stat st;
..
.. if ( fstat(fileno(stdin),&st) < 0) { perror("fstat"); exit(0);
}
.. if (S_ISFIFO(st.st_mode)) { printf("Pipe\n"); }
.. else if (S_ISCHR(st.st_mode)) { printf("Character device\n");
}
.. else if (S_ISREG(st.st_mode)) { printf("Regular file\n"); }
..}

But usually this kind of detection is not among the best of ideas...
for determining input type rather than setting aside a command line
option or separate binary to give the user control of input method.

(You can't be too sure of the underlying input, actually... and by
making a decision based on input device.. you risk sacrificing
generality)
 
L

Lawrence Kirby

Yup, in the sense that it has a finite chance of failing on your
conforming system. Would you rather I claimed it to be portable,
or didn't even mention it?

I think Richard would rather you stated that it is non-portable without
qualification.

Lawrence
 
R

Richard Bos

CBFalconer said:
Yup, in the sense that it has a finite chance of failing on your
conforming system. Would you rather I claimed it to be portable,
or didn't even mention it?

In the context of c.l.c, it not very likely, but with certainty
non-portable. In fact, IIRC the solution you give isn't even guarantee
to work correctly under exotic circumstances (over a serial line springs
to mind), but I could be wrong; that's the danger of non-portable code
in c.l.c! (Of cource, the OP isn't likely to be in such unusual
circumstances, but still...)

Richard
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,756
Messages
2,569,540
Members
45,025
Latest member
KetoRushACVFitness

Latest Threads

Top