简体   繁体   中英

write operation on pipe is always failing

I'm a bit new to pipes and concurrency, and have been frustrated with this problem for hours. I am struggling to understand why this write operation is constantly failing on my pipe. I am trying to have the child process write data through a pipe that will be received by the parent process. My current code is this:

#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#define MAXSIZE 4096

int main() {
    pid_t status;
    int fd[2]; //The array of file descriptors

    if (pipe(fd) == -1) {
        printf("Error piping");
    }

    status = fork(); //Begin the fork process
    switch (status) {
        case -1:
            perror("Error forking");
            break;
        case 0:
            //Child process
            close(fd[0]); //Only send data
            char some_string[15] = "hi there";
            if (write(fd[1], some_string, MAXSIZE) == -1) {
                printf("Error writing to the pipe");
            }
            close(fd[1]); //Close write end
            exit(1);
        default:
            close(fd[1]); //Only receive data
            char readed[500] = "";
            while(read(fd[0], readed, MAXSIZE) != 0) {
                printf("read this %s\n", readed);
            }
            printf("Done reading");
            close(fd[0]);
            break;
    }
    return 1;
}

However, I constantly get the message "Error writing to pipe", meaning that the write operation has failed in the child process. Another interesting thing is that if I change some_string to a string literal instead, this code works fine with the exception that it never terminates and instead, the read operation in the parent process reads from STDIN ! I don't understand why this could be happening, is it possible that we have a zombie child when parent executes so the pipe is "dead"? Or perhaps that the parent process terminates and we have an orphaned child? How can I avoid this and how does this explain the weird behaviour from the string literal instead? Any insights?

You told write() to read the data from out-of-range of the array and allowed read() to write the data read to out-of-range of the array. That is very bad.

Write only valid data and limit the length to read not to cause out-of-range access.

Try this:

#include <unistd.h>
#include <sys/types.h> /* add this to use pid_t */
#include <sys/wait.h> /* add this to use wait() */
#include <stdio.h>
#include <stdlib.h>
/* remove unused MAXSIZE */

int main() {
    pid_t status;
    int fd[2]; //The array of file descriptors
    int st; /* variable for receiving the status */

    if (pipe(fd) == -1) {
        printf("Error piping");
        return 1; /* return 1 when the execution failed */
    }

    status = fork(); //Begin the fork process
    switch (status) {
        case -1:
            perror("Error forking");
            return 1; /* return 1 when the execution failed */
            break;
        case 0:
            //Child process
            close(fd[0]); //Only send data
            char some_string[15] = "hi there";
            if (write(fd[1], some_string, sizeof(some_string)) == -1) {
                printf("Error writing to the pipe");
            }
            close(fd[1]); //Close write end
            exit(0); /* return 0 if the execution finished successfully */
        default:
            close(fd[1]); //Only receive data
            char readed[500] = "";
            while(read(fd[0], readed, sizeof(readed) - 1) != 0) { /* -1 for reserving space for terminating null-character */
                printf("read this %s\n", readed);
            }
            printf("Done reading");
            close(fd[0]);
            wait(&st); /* wait for the child process to exit and release the data of the process */
            break;
    }
    return 0; /* return 0 if the execution finished successfully */
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM