Samuel H Page
Samuel H Page

Reputation: 1

How can I redirect the output of an exec() system call from stdout to a pipe and read the result into a buffer from the parent process?

The goal is to have the cksum_child function create a child process, and execute the checksum command on the provided file. Redirecting the output to a pipe and reading the result from the pipe in the entry function get_cksum which is functioning as the parent.

`

pid_t
create_cksum_child (int *pipe, char *const filename)
{
  pid_t pid = fork();

  if (pid < 0) {
    printf("fork\n");
    return NULL;
  }

  if (pid == 0) {
    close(pipe[0]);
    dup2(pipe[1], STDOUT_FILENO);
    execlp("/usr/bin/cksum", "cksum", filename, NULL);
    printf("execlp\n");
    exit(1);
  }

  int status;
  waitpid(pid, &status, 0);

  return pid;
}

char *
get_cksum (char *const filename)
{
  char *buffer = NULL;

  int fd[2];
  if (pipe(fd) < 0) {
    printf("pipe\n");
    exit(1);
  }

  pid_t child_pid = create_cksum_child(fd, filename);

  if (child_pid == NULL) {
    return NULL;
  }

  fflush(stdout);

  ssize_t bytes_read = read (fd[0], buffer, sizeof (buffer));

  close(fd[0]);
  close(fd[1]);

  if (bytes_read < 1) {
    printf("bytes read: %ld\n", bytes_read);
    return NULL;
  }

  return buffer;
}

`

The code I have here closely follows my textbook sections on IPC models, which initially caused a timeout err. From what I've gather from similar questions on SO I needed to fflush() stdout since the output was being buffered which fixed the timeout but the returned string is incorrect. I then added print statement to see how many bytes I'm reading from the pipe and I get -1 bytes on all test files.

What mistakes did I make and what can I do to redirect the output from stdout and read it in the parent properly?

Upvotes: 0

Views: 120

Answers (1)

Alez
Alez

Reputation: 2689

The main issue is that you should merge the 2 functions together because the parent code is not only in the second function but it is splitted into both functions you wrote.

For example you should move the waiting lines

int status;
waitpid(pid, &status, 0);

on the parent side, since the parent has to wait the child and not vice versa.

After that, your code is in a good shape but probably you should refactor it after the merge of the functions.

Upvotes: 0

Related Questions