2016-06-21 9 views
2

私のコードをC#からCに書き直そうとしていますが、少し問題があります。パイプを使用してプロセス間で文字列を送信する

私はtestという名前のファイルがあります。そこには1行のテキストがあります。私はその行を読んで、プロセス間でパイプを介して送信し、それを画面に表示したい。ここで

はコードです:

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

私はこのコードを実行しながら、セグメンテーションエラーになっているようだが。私が紛失しているものはありますか?

+1

どのセグメントがセグメント化エラーを起こしていますか? – Barmar

+1

'getline()'からエラーをチェックする必要があります。エラーが発生した場合、 'line'を割り当てることができないので、印刷しようとするとセグメント化エラーが発生します。 – Barmar

+0

私はプログラムを1行ずつ実行しましたが、実際にはgetl​​ineでブレークします。私はCにうまく対応していませんが、どうすればこの問題を回避できますか? – Januszoff

答えて

1

test.txtファイルを作成すると、正常に動作します。 それは少なくとも私のマシンで修正されました。

通常、プログラムを堅牢に作成するには、かなり面倒なエラーチェックが必要です。例えば、あなたのような何かを書かれている必要があります:あなたは素敵な"write: No such file or directory"メッセージを得ているかもしれません

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

:など

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

をテストファイルのためのあなたのfopen行は以下のように見えていました。

+2

'if(ferror(stream)){fclose(stream);} goto err; } '問題がある。 'fclose'が失敗し、errnoが変更されます。その場合、エラー処理で表示されるエラーメッセージは誤解を招きます。だから...さらに多くの退屈さが必要です。 –

+0

@WilliamPursellありがとう – PSkocik

0

私のマシン(Linux 3.2.0-4-amd64#1 SMP Debian 3.2.68-1 + deb7u2 x86_64 GNU/Linux)で、このコードは変更されずに正しく動作しています。 'test.txt'ファイルを削除した結果、セグメンテーション違反が発生しました。

したがって、問題は、あなたが持っている問題は、 'test.txt'ファイルが存在しないか、あなたがそのプログラムを実行しているユーザーのための読み取り権限がないことだと思います。

1

プログラムがクラッシュする可能性がいくつかありますが、プログラムの作業ディレクトリに重要なチェックがなく、「test.txt」ファイルが見つからないことが原因です。不足している

最初のチェックは、テストファイルがNULLであるかどうかです:

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

テストファイルのファイルポインタが無効なファイルポインタを渡された場合、プログラムをクラッシュすることがありますgetlineの()に未チェック渡されます。 testfileが有効であっても、getline()自体も失敗する可能性がありますが、私の現在のDebianでは、エラー状態で行ポインタに何が起こるのかについての説明がないので、戻り値< 0を使用してエラーを検出し、その場合は後でポインタを使用したり解放したりしないでください。

この種のことを学んでいる場合は、最後の発言として、gdbの使い方を学ぶ必要があります。 次のように使用してください:

$ 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 
関連する問題