2016-06-21 14 views
2

Ich versuche, meinen Code von C# zu C umzuschreiben und habe ein bisschen Ärger.Verwenden von Pipes, um Zeichenfolgen zwischen Prozessen zu senden

Also habe ich eine Datei namens test, in der es eine einzelne Textzeile gibt. Ich möchte diese Zeile lesen, sie durch die Pipe zwischen den Prozessen senden und sie auf dem Bildschirm ausdrucken.

Hier ist der Code:

#include <sys/types.h> 
#include <unistd.h> 
#include <stdio.h> 
#include <stdlib.h> 


void 
read_from_pipe (int file) 
{ 
    FILE *stream; 
    int c; 
    stream = fdopen (file, "r"); 
    while ((c = fgetc (stream)) != EOF) 
    putchar (c); 
    fclose (stream); 
} 

void 
write_to_pipe (int file) 
{ 
    FILE *stream; 
    FILE *testfile; 
    stream = fdopen (file, "w"); 
    testfile = fopen("test.txt", "r"); 
    char *line = NULL; 
    size_t len = 0; 
    //ssize_t read; 
    getline(&line, &len, testfile); 
    fprintf (stream, "%s", line); 
    free(line); 
    fclose(testfile); 
    fclose (stream); 
} 

int 
main (void) 
{ 
    pid_t pid; 
    int mypipe[2]; 


    if (pipe (mypipe)) 
    { 
     fprintf (stderr, "Pipe failed.\n"); 
     return EXIT_FAILURE; 
    } 
    pid = fork(); 
    if (pid == (pid_t) 0) 
    { 
     close (mypipe[1]); 
     read_from_pipe (mypipe[0]); 
     return EXIT_SUCCESS; 
    } 
    else if (pid < (pid_t) 0) 
    { 
     fprintf (stderr, "Fork failed.\n"); 
     return EXIT_FAILURE; 
    } 
    else 
    { 
     close (mypipe[0]); 
     write_to_pipe (mypipe[1]); 
     return EXIT_SUCCESS; 
    } 
} 

Allerdings scheine ich immer Segmentierung Fehler werden während dieser Code ausgeführt wird. Gibt es etwas, das mir fehlt?

+1

Welche Zeile erhält den Segmentierungsfehler? – Barmar

+1

Sie sollten nach einem Fehler von 'getline()' suchen. Wenn ein Fehler auftritt, kann "line" nicht zugewiesen werden, sodass beim Versuch, sie zu drucken, ein Segmentierungsfehler auftritt. – Barmar

+0

Ich lief das Programm Zeile für Zeile und in der Tat bricht es auf getline. Ich spreche C nicht fließend, wie vermeide ich das? – Januszoff

Antwort

1

Es wird wahrscheinlich gut funktionieren, sobald Sie die Datei test.txt erstellen. Das hat es zumindest auf meiner Maschine behoben.

In C müssen Sie in der Regel einige ziemlich langwierige Fehlerprüfung durchführen, um Programme robust zu schreiben. Zum Beispiel, sollten Sie geschrieben etwas wie haben:

int read_from_pipe (int file) { 
    FILE *stream; 
    int c; 
    if((stream = fdopen (file, "r"))==NULL) goto err; 

    while ((c = fgetc (stream)) != EOF){ 
    putchar (c); 
    } 
    if(ferror(stream)){ int er=errno; fclose (stream); errno=er; goto err; } 
    return 0; 
err: 
    perror("read"); return -errno; 
} 

usw.

Hatte Ihre fopen Linie für die Testdatei ausgesehen:

if(!(testfile = fopen("test.txt", "r"))) { perror("write"); return -errno; } 

Sie eine schöne bekommen "write: No such file or directory" Nachricht haben könnte.

+2

'if (ferror (stream)) {fclose (stream); gehe irre; } ist problematisch. 'fclose' kann fehlschlagen und errno ändern. In diesem Fall ist die in der Fehlerbehandlung ausgedruckte Fehlermeldung irreführend. Also ... noch mehr Langeweile ist nötig. –

+0

@WilliamPursell Danke – PSkocik

0

Dieser Code läuft einwandfrei auf meinem Rechner (Linux 3.2.0-4-amd64 # 1 SMP Debian 3.2.68-1 + deb7u2 x86_64 GNU/Linux) wie es ohne Änderungen ist. Ich habe die Datei 'test.txt' entfernt und dadurch einen Segmentierungsfehler erhalten.

Daher denke ich, das Problem, das Sie haben, ist entweder die 'test.txt' Datei existiert nicht oder Sie haben keine Leseberechtigungen für den Benutzer, unter dem Sie das Programm ausführen.

1

Es gibt mehrere Möglichkeiten, in denen Ihr Programm abstürzt, aber wahrscheinlich liegt es daran, dass Ihnen wichtige Prüfungen fehlen und die Datei "test.txt" im Arbeitsverzeichnis Ihres Programms fehlt.

Prüfen Sie zunächst, die ist fehlt, ob testdat NULL ist:

testfile = fopen("test.txt", "r"); 

Der testdat FILE-Zeiger unkontrolliert übergeben wird auf getline(), die das Programm zum Absturz bringen kann, wenn er einen ungültigen Dateizeiger übergeben wird. Wie Barmar bereits angemerkt hat, kann getline() auch fehlschlagen, obwohl testfile gültig ist, aber auf meinem aktuellen Debian gibt die Manpage nicht aus, was mit dem Zeilenzeiger auf Fehlerbedingung passiert, also würde ich einfach nach dem Rückgabewert < suchen 0, um einen Fehler zu erkennen und in diesem Fall den Zeiger nicht zu benutzen oder danach freizugeben.

Als letzte Bemerkung sollten Sie lernen, gdb zu verwenden, wenn Sie solche Sachen lernen. Verwendung wie folgt:

$ gcc -ggdb3 -o pipetest pipetest.c 
$ gdb pipetest 
GNU gdb (Debian 7.7.1+dfsg-5) 7.7.1 
[...] 
(gdb) run 
Starting program: /home/thilo/code/test/pipetest 

Program received signal SIGSEGV, Segmentation fault. 
_IO_getdelim (lineptr=0x7fffffffe068, n=0x7fffffffe060, delimiter=10, fp=0x0) at iogetdelim.c:56 
56  iogetdelim.c: No such file or directory. 
(gdb) bt 
#0 _IO_getdelim (lineptr=0x7fffffffe068, n=0x7fffffffe060, delimiter=10, fp=0x0) at iogetdelim.c:56 
#1 0x00000000004008fb in write_to_pipe (file=4) at pipetest.c:28 
#2 0x00000000004009d9 in main() at pipetest.c:62 
(gdb) frame 1 
#1 0x00000000004008fb in write_to_pipe (file=4) at pipetest.c:28 
28  getline(&line, &len, testfile); 
(gdb) print line 
$1 = 0x0 
Verwandte Themen