Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I check if my program has data piped into it

Tags:

c++

c

stdin

pipe

Im writing a program that should read input via stdin, so I have the following contruct.

FILE *fp=stdin;

But this just hangs if the user hasn't piped anything into the program, how can I check if the user is actually piping data into my program like

gunzip -c file.gz |./a.out #should work
./a.out  #should exit program with nice msg.

thanks

like image 317
monkeyking Avatar asked Apr 02 '10 00:04

monkeyking


5 Answers

Since you're using file pointers, you'll need both isatty() and fileno() to do this:

#include <unistd.h>
#include <stdio.h>

int main(int argc, char* argv[])
{
    FILE* fp = stdin;

    if(isatty(fileno(fp)))
    {
        fprintf(stderr, "A nice msg.\n");
        exit(1);
    }

    /* carry on... */
    return 0;
}

Actually, that's the long way. The short way is to not use file pointers:

#include <unistd.h>

int main(int argc, char* argv[])
{
    if(isatty(STDIN_FILENO))
    {
        fprintf(stderr, "A nice msg.\n");
        exit(1);
    }

    /* carry on... */
    return 0;
}

Several standard Unix programs do this check to modify their behavior. For example, if you have ls set up to give you pretty colors, it will turn the colors off if you pipe its stdout to another program.

like image 168
Mike DeSimone Avatar answered Oct 20 '22 14:10

Mike DeSimone


Try "man isatty", I think that function will tell you if you are talking to the user or not.

like image 30
Jeremy Friesner Avatar answered Oct 20 '22 14:10

Jeremy Friesner


Passing stdin to select() or poll() should tell you if input is waiting. Under many OSes you can also tell if stdin is a tty or pipe.

EDIT: I see I'm going to have to emphasize the also part of the tty test. A fifo is not a tty, yet there might be no input ready for an indefinite amount of time.

like image 41
Ben Voigt Avatar answered Oct 20 '22 14:10

Ben Voigt


Use isatty to detect that stdin is coming from a terminal rather than a redirect.

like image 30
Marcelo Cantos Avatar answered Oct 20 '22 14:10

Marcelo Cantos


See the function "isatty" - if STDIN is a terminal, you can skip reading from it. If it's not a terminal, you're getting data piped or redirected and you can read until EOF.

like image 20
nobody Avatar answered Oct 20 '22 12:10

nobody