2010-04-02 6 views
7

Ich schreibe ein Programm, das Eingabe über Stdin lesen sollte, also habe ich folgendes Konstrukt.Wie überprüfe ich, ob mein Programm Daten in es piped hat

FILE *fp=stdin; 

Aber das hängt nur, wenn der Benutzer etwas in das Programm nicht geleitet hat, wie kann ich überprüfen, ob der Benutzer tatsächlich Daten in mein Programm wie

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

dank

+0

Für die Aufzeichnung wird das Programm nicht hängen; es wartet einfach auf Eingabe. Wenn Sie ein EOF (Ctrl-D auf den meisten Plattformen) senden, wird dies so interpretiert, als wäre die Eingabe vorzeitig beendet. – greyfade

Antwort

8

Da Sie Dateizeiger verwenden, müssen Sie beide isatty() und fileno() dies tun:

#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; 
} 

Eigentlich, das ist der lange Weg. Der kurze Weg ist nicht Dateizeiger zu verwenden:

#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; 
} 

Mehrere Standard-Unix-Programme machen diese Überprüfung, ihr Verhalten zu ändern. Zum Beispiel, wenn Sie ls eingerichtet haben, um Ihnen schöne Farben zu geben, wird es die Farben ausschalten, wenn Sie seine stdout zu einem anderen Programm pipes.

3
kochend

Das Übergeben von stdin an select() oder poll() sollte Ihnen sagen, ob die Eingabe wartet. Unter vielen Betriebssystemen können Sie auch feststellen, ob es sich bei stdin um ein tty oder eine Pipe handelt.

EDIT: Ich sehe, ich werde die auch Teil des Tty-Test zu betonen haben. Ein Fifo ist kein TYT, aber es gibt möglicherweise keine Eingabe für eine unbestimmte Zeit.

+0

Ich denke, das OP wollte nur den Run-on-Command-Line-and-Wonder-Why-It- "hängt" -Fall abdecken. Wahrscheinlich versucht, einen PEBKAC-Fehler zu beheben. Dort zu sitzen und auf einen FIFO oder eine andere Pfeife zu warten wäre okay. –

3

Versuchen Sie "Man isatty", ich denke, dass diese Funktion Ihnen sagen wird, ob Sie mit dem Benutzer sprechen oder nicht.

2

Verwenden Sie isatty, um zu erkennen, dass stdin von einem Terminal statt von einer Umleitung kommt.

1

Siehe die Funktion "isatty" - wenn STDIN ein Terminal ist, können Sie das Lesen davon überspringen. Wenn es sich nicht um ein Terminal handelt, werden Daten weitergeleitet oder weitergeleitet und Sie können bis EOF lesen.