2016-11-13 60 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

首先,在孩子的情況下,您嘗試關閉管道的寫入結束兩次。我猜close(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.