2016-07-04 13 views
0
Arbeits

ich den folgenden Befehl bin mit einer konstanten Leistung von einem zweistelligen Wert zu erhalten:Buffering während popen

pipe = popen("hcidump -a | egrep --line-buffered 'RSSI|bdaddr' | grep -A1 --line-buffered --no-group-separator 'bdaddr 78:A5:04:17:9F:66' | grep -Po --line-buffered 'RSSI:\\s+\\K.*'", "r"); 

Ich mag, dass puffern, so kann ich es in eine Integer-Wert-Transformation und die Arbeit mit es. aber ich bin mir nicht sicher, wie ich das erreichen soll. Solange ich Popen laufen habe geht mein C-Programm nicht weiter. Ich habe es mit strace überprüft und er wird den Wert in popen lesen und nicht terminieren.

der Rest der Code sieht wie folgt aus:

if (pipe) 
    { 
     printf("entered pipe-if"); 

     while(!feof(pipe)) 
     { 
      if(fgets(buffer, 128, pipe) != NULL){} 
     } 
     pclose(pipe); 
     printf("pclose"); 
     buffer[strlen(buffer)-1] = '\0'; 
    } 

Die Idee dahinter ist, dass ich die Daten verwenden möchten eine distnace in „Echtzeit“ zu berechnen. Eine Möglichkeit wäre, dass ich Popen sagen könnte, dass er den Prozess nach x Sekunden beenden soll, dann benutze die gepufferten Daten und starte dann den Prozess von Anfang an.

Vielen Dank für Hilfe und Beratung.

+0

Warum denkst du, dass es ein EOF geben wird? –

+0

Ich weiß, dass es kein EOF gibt, ich habe einige Dinge ausprobiert und das ist geblieben. mein Fehler, es hier zu sagen. – DaPole

Antwort

3

Nachdem Sie die Pipe mit popen geöffnet haben, sollten Sie mit dem Dateideskriptor und nicht mit dem FILE-Zeiger arbeiten. Anschließend können Sie die Datei auf nicht-blockierend drehen und die Daten verarbeiten, wie es kommt.

int fd = fileno(pipe); 
fcntl(fd, F_SETFL, O_NONBLOCK); 

Dann können Sie Daten aus dem Rohr lesen

bytes = read(fd, buf, bufsize); 

Verwendung Wenn Bytes größer als 0 ist, dann Sie müssen noch mehr Daten verarbeiten. Wenn Bytes -1 und Errno EAGAIN ist, dann ist nichts in der Pipe. Sonst bist du fertig. Du wirst mit den Daten umgehen müssen, wie auch immer es kommt (dh du bekommst keine fgets(), die Dinge netto pro Zeile machen)

+0

Aber lässt mich das nicht dasselbe Problem? wie ich Popen zum ersten Mal mit einer nie endenden Ausgabe benutze, werde ich nie zu dem Punkt von fileno kommen, fcntl und lesen? – DaPole

+0

Indem Sie den Dateideskriptor nicht blockierend machen, haben Sie die Kontrolle wieder in Ihrem Programm, selbst wenn es keine Ausgabe gibt, so dass Sie bei Bedarf ein eigenes Timeout implementieren können. Obwohl ich nicht sagen kann, dass ich den Anwendungsfall vollständig verstehe, sieht es für mich aus, als wäre es besser, wenn Sie die Pipe öffnen und Daten verarbeiten, wenn Sie neue Daten sehen (zB bei jeder Rückgabe von fgets() oder read()) Version), anstatt nachdem Sie die Pipe geschlossen haben. – mykel

+0

Anwendungsfall ist, dass ich RSSI-Werte von einem iBeacon lesen möchte, um zu wissen, ob es nah, mittel oder weit weg von meinem Gerät ist. Und abhängig vom Wert muss ich weitere Anweisungen geben. Deshalb muss ich ständig nach den Werten lesen und darauf reagieren. Es muss nicht in Echtzeit sein, aber häufig. Mittel ich kann einige Daten sammeln (wie ein oder zwei Sekunden) und dann weiter verarbeiten. Ich werde es später versuchen. – DaPole