Does the child process redirect standard output to the parent process?

I am studying OS exam on Tuesday. To prepare, I'm trying to simulate a command line pipe using a C program.

The program is pretty simple. I make a pipe and then deploy a child process.

The child process redirects standard output to the end of the record, closes the file descriptors for the pipe, and then executes the command ( ls

, in this case).

The parent process waits for the child process to exit, redirects standard input to the end of the output on the pipe, closes the file descriptors for the pipe, and then executes the command ( grep 'school'

in this case).

When I execute a command via the command line with using ls | grep 'school'

, a line appears that says "school" is being printed to standard output, which makes sense given that there is a directory in the directory where I run the program in the name of that.

When I run the program I created, I don't get any error messages, but it doesn't output any results.

The only thing I can think of as interfering with work is that redirecting standard output to the child process somehow affects the parent's command output, but I'm pretty sure it shouldn't be.

Here is the code:

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

int main() {
    int fds[2];
    int pipe_val, close_val, write_val, dup_val, status;
    pid_t pid;
    char *error;

    pipe_val = pipe(fds);
    if (pipe_val) {
        fprintf(stderr, "Failed to prepare pipe.\n");
        return -1;
    }
    pid = fork();
    if (pid == -1) {
        fprintf(stderr, "Failed to fork a child process.\n");
        return -1;
    } else if (pid == 0) {
        dup_val = dup2(fds[1], STDOUT_FILENO);
        if (dup_val) {
            error = strerror(errno);
            fprintf(stderr, "Failed to redirect standard output in child process because %s\n", error);
            exit(1);
        }
        close_val = close(fds[0]);
        if (close_val) {
            fprintf(stderr, "Failed to close read-end of pipe in child process.\n");
            exit(1);
        }
        close_val = close(fds[1]);
        if (close_val) {
            fprintf(stderr, "Failed to close write-end of pipe in child process.\n");
            exit(1);
        }
        execl("/bin/ls", "ls", NULL);
        fprintf(stderr, "Failed to execute command in child process.\n");
        exit(1);
    } else {
        wait(&status);
        dup_val = dup2(fds[0], STDIN_FILENO);
        if (dup_val) {
           error = strerror(errno);
           fprintf(stderr, "Failed to redirect standard input in parent process because %s.\n", error);
            return -1;
        }
        close_val = close(fds[0]);
        if (close_val) {
            fprintf(stderr, "Failed to close read-end of the pipe in the parent process.\n");
            return -1;
        }
        close_val = close(fds[1]);
        if (close_val) {
            fprintf(stderr, "Failed to close write-end of the pipe in the parent process.\n");
            return -1;
        }
        execl("/bin/grep", "grep", "school", NULL);
        fprintf(stderr, "Failed to execute the command in the parent process.\n");
        return -1;
    }
}

      

+3


source to share


1 answer


Your first problem is that you haven't included all the required headers for the functions you are using. strerror

demands <string.h>

and wait

demands <sys/wait.h>

.

If you are compiling gcc, always use gcc -Wall

and read warnings. In this case, he would have complained about the implicit declaration strerror

.



Since strerror

it was not declared, the compiler assumes that it returns int

, which is incorrect. If you run the program on 64-bit Linux x86 int

does not match the pointer returned strerror

. This becomes a fatal problem when you pass the result strerror

in fprintf

with a format %s

, because the pointer was misinterpreted as an int and then converted back to a pointer, eventually with a dummy value. fprintf

segfaults and you will never see an error message.

Include the correct headers and you will see an error message that will lead you to the next problem you should fix.

+3


source







All Articles