Program that read file and send it to parent process with pipe

前端 未结 3 1324
小蘑菇
小蘑菇 2021-01-15 06:46

I need to write a program that create pipe send filename from command line to child process. In child read that file and send it back using pipe. Parent process should print

相关标签:
3条回答
  • 2021-01-15 07:14

    Your program works as intended after quite a few changes. Lets list out what all changes are required and why-

    I) Both in the child and parent, close the respective pipes as soon as you are done with them. From man page of read(3),

    If some process has the pipe open for writing and O_NONBLOCK is clear, read() shall block the calling thread until some data is written or the pipe is closed by all processes that had the pipe open for writing.

    So do something like this in your code everywhere where the job pipes is over,

      size = read(pipefd[0], buff, sizeof(buff));
      close(pipefd[0]);
    
      write(pipefd[1], buff, strlen(buff));
      close(pipefd[1]);
    
      if (write(pipefd[1], argv[1], size) != size) {
         perror("Error writing to pipe\n");
      }
      close(pipefd[1]);
    
      while ((size = read(pipefd[0], buff, sizeof(buff))) > 0) 
      {
         write(1, buff, size);
      }
      close(pipefd[0]);
    

    You hadn't closed the write end of of the pipe in the child and your parent was blocking in the read

    II) You are using something like while(fgets(...)) in a loop to read data from file. This will bomb when there are newlines in the file and fgets returns multiple times, overwriting the buffer everytime during the process

    I always use simple fgetc and feof combination to read from file. So, change your file reading mechanism to something like

    unsigned count=0;
    while (!feof(file) && count < sizeof(buff))
        buff[count++]=fgetc(file);
    if (feof(file)) 
        buff[--count]=0;
    else
        buff[sizeof(buff)-1]=0;
    

    III) While writing the file data from the child, you should use strlen(as we have already made sure buffer is null terminated, see above ) and not sizeof as the buffer may not be full at all and you will end up writing junk. So, change

      write(pipefd[1], buff, sizeof(buff));
    

    to

      write(pipefd[1], buff, strlen(buff));
    

    IV) Follow a safe exit from the child and parent after their job is done. Something like

    close(pipefd[1]);
    _exit(EXIT_SUCCESS);   // in child
    

    and

    close(pipefd[0]);
    exit(EXIT_SUCCESS); // in parent
    

    PS: I've changed the file reading logic, so your compiler error is gone now and do follow the advice given by n.m.

    0 讨论(0)
  • 2021-01-15 07:29

    You cannot write sizeof(buf) meaningful bytes if fgets returned less than that. The rest will be filled with junk.

    Moreover, mixing string-oriented fgets with binary read/write is a bad style. Use read or fread to read the file. They return number of bytes read, use this number as an argument to write.

    0 讨论(0)
  • 2021-01-15 07:39

    This code does not compile:

      while (fgets(buff, sizeof(buff), file) != NULL) {
            write(pipefd[1], "Error reading file", 18);
         } else {
            write(pipefd[1], buff, sizeof(buff));
         }
    

    You can't have an else clause there.

    0 讨论(0)
提交回复
热议问题