2016-11-13 11 views
-1

私は、子供をフォークして親と通信したいプログラムがあります。しかし、子供の書き込み終了時にエラーが出るようです。パイプ終了エラーを閉じる

プログラムは、どうやらそれは子供が書き込み終了を閉じたいときに失敗した子の内側とif (close(pfd1[1]) == -1)

に停止します。どうして?

/* Note: working under the assumption that the messages are of equal length */ 

int main(int argc, char * argv[]) 
{ 
    int pfd1[2];   
    char buf[BUF_SIZE]; 

    //checks pipefd1 
    if (pipe(pfd1) == -1) 
    { 
     printf("Error opening pipe 1!\n"); 
     exit(1); 
    } 

    printf("Pipe opened with success. Forking ...\n"); 

    // child 1 
    switch (fork()) 
    { 
     case -1: 
      printf("Error forking child 1!\n"); 
      exit(1); 

     case 0: 
      printf("\nChild 1 executing...\n"); 
      /* close writing end of first pipe */ 
      if (close(pfd1[1]) == -1) 
      { 
       printf("Error closing writing end of pipe 1.\n"); 
       _exit(1); 
      } 

      /* read from pipe 1 */ 
      if (read(pfd1[0], buf, 2000)) 
      { 
       printf("Error reading to pipe 1.\n"); 
       _exit(1); 
      } 
      /* close reading end of first pipe */ 
      if (close(pfd1[1]) == -1) 
      { 
       printf("Error closing writing end of pipe 1.\n"); 
       _exit(1); 
      } 

      printf("Message received child ONE: %s", buf); 
      printf("Exiting child 1...\n"); 
      _exit(0); 

     default: //parent breaks just out 
      break; 
    } 

    printf("inside parent\n"); 

    int child = 1; 
    char *message = "Hey child1, this is your parent speaking"; 

    if(child == 1) 
    { 
     //close read end of pipe 
     if(close(pfd1[0]) == -1) 
     { 
      printf("Error closing reading end of the pipe.\n"); 
      exit(EXIT_FAILURE); 
     } 

     printf("Parent closed read end of pipe1\n"); 

     //read end is closed, now write to child 
     if(write(pfd1[1], message, strlen(message))) 
     { 
      printf("Error writing to the pipe."); 
      _exit(EXIT_FAILURE); 
     } 

     printf("Writing to child1 succeeded\n"); 
    } 

    if (wait(NULL) == -1) 
    { 
     printf("Error waiting.\n"); 
     exit(EXIT_FAILURE); 
    } 

    if (wait(NULL) == -1) 
    { 
     printf("Error waiting.\n"); 
     exit(EXIT_FAILURE); 
    } 

    printf("Parent finishing.\n"); 
    exit(EXIT_SUCCESS); 
} 
+1

エラーは何ですか? 'perror()'などを使ってください。 – cdarke

答えて

2

まず、子供の場合、パイプの書き込み終了を2回試みます。私はclose(2)への2回目の呼び出しは、それ以上のコメントで述べたように、読取終了を閉鎖することを意図した推測:そのほかに

/* close reading end of first pipe */ 
if (close(pfd1[0]) == -1) 
{ 
    printf("Error closing writing end of pipe 1.\n"); 
    _exit(1); 
} 

read(2)write(2)の両方が実際にあったバイト数を返すことに注意してください読んだり書いたりする。エラーの場合には戻り値が-1あるので、あなたのエラーチェックの条件のようなものに、あまりにもそこに固定する必要があります。

/* read from pipe 1 */ 
if (read(pfd1[0], buf, 2000) < 0) { 
    printf("Error reading to pipe 1.\n"); 
    _exit(1); 
} 

魚への指導の原則に
//read end is closed, now write to child 
if(write(pfd1[1], message, strlen(message)) < 0) { 
    printf("Error writing to the pipe."); 
    _exit(EXIT_FAILURE); 
} 
+0

うわーありがとう! – Rodbjartson

0

、このような問題を診断する良い方法は、エラーの内容を確認し、より有益なメッセージを出力することです。ここで私は頻繁にヘッダファイルと使用に入れ技法です:

#include <errno.h> 
#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 

/* This declaration and macro would really go into a header file: */ 
void fatal_error_helper(const char* msg, const char* sourcefile, int lineno, const char* syserr); 

#define fatal_system_error(m) \ 
    fatal_error_helper((m), __FILE__, __LINE__, strerror(errno)) 

/* This function definition would really go into a .c file: */ 
void fatal_error_helper(const char* const msg, 
         const char* const sourcefile, 
         const int lineno, 
         const char * const syserr) 
{ 
    fflush(stdout); /* Don't cross the streams! */ 
    fprintf(stderr, 
      "%s at %s:%d: %s. Program terminated.\n", 
      msg, sourcefile, lineno, syserr 
     ); 
    exit(EXIT_FAILURE); 
} 

/* Test driver: */ 
FILE* fails_to_open_file(const char* filename) 
/* Returns a FILE* to an open file. If the operation fails, prints an 
* error message and terminates the program. 
*/ 
{ 
    /* Do this in general before calling the function whose error value 
    * you check. Otherwise, you might report the wrong error message 
    * from an earlier call and really confuse someone. 
    */ 
    errno = 0; 
    FILE* result = NULL; 

    result = fopen(filename, ""); /* Fails. */ 
    if (!result) 
     fatal_system_error("Failed to open file"); 
    return result; 
} 

int main(void) 
{ 
    fails_to_open_file("nonexistent.file"); 
    return EXIT_SUCCESS; 
} 

これは、次のようなエラーメッセージを表示します。Failed to open file at prog.c:26: Invalid argument. Program terminated.

関連する問題