manikawnth
manikawnth

Reputation: 3229

Shell command execution via forked process by passing variables through pipes

This is a nothing-to-achieve-special kind of scenario. I want to understand what mistake I"m doing.

Scenario:
1. Fork a child process 2. The child process shall execute a shell command (e.g. cat sort a file) 3. The arguments of the shell command are passed from parent process through pipe (e.g. file inputs for the g. cat sort)

I've written the below program but it is displaying the filename instead of printing out the file content. but it is hanging without giving any output on to the screen

#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/wait.h>

int main(){

  int pipefd[2];
  pipe(pipefd);

  //create a pipe before you fork a child process
  pid_t cpid = fork();
  if(cpid < 0){
    perror("Fork");
  }
  else if(cpid == 0){
    printf("This is child process\n");

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

    dup2(pipefd[0],0);

    execlp("sort", "sort", NULL);

    exit(0);

  }
  else{
    printf("This is parent process\n");
    close(pipefd[0]);

    char *sort_array[] = {"hello", "amigos", "gracias", "hola"};
    for (int i=0; i<4; i++){
      write(pipefd[1],sort_array[i],strlen(sort_array[i]));
      write(pipefd[1], "\n",1);
    }


    int cstatus;
    wait(&cstatus);

  }


}

Update:
Original example is not valid. I've updated to sort command.
I'm trying to sort the contents. But the screen is hanging without any output

Upvotes: 0

Views: 136

Answers (2)

FKEinternet
FKEinternet

Reputation: 1060

pipe(pipefd);  // N.B. failed to check the return value, potential error

//create a pipe before you fork a child process
pid_t cpid = fork();
if (cpid < 0)  // `if` is a language keyword, not a function, space after
{              // opening brace on next line makes reading code easier
    perror("Fork");
}
else if (cpid == 0)
{
    printf("This is child process\n");

    close(pipefd[1]);  // closing "write" end of pipe in child
    close(0);          // closing stdin in child

    dup2(pipefd[0],0); // returned handle is not stored, see https://linux.die.net/man/3/dup2

    execlp("cat", "cat", NULL);  // function prototype is int execlp(const char *file, const char *arg, ...);
                                 // what are you trying to accomplish?

    exit(0);
}
else
{
    printf("This is parent process\n");
    close(pipefd[0]);  // close "read" end of pipe in parent process

    write(pipefd[1], "s.txt", 5);  // write text into pipe

    int cstatus;
    wait(&cstatus);    // wait for ??? something
}

Where did you expect the file whose name is passed into the pipe to be opened and written to an output?

Upvotes: 0

Parham Alvani
Parham Alvani

Reputation: 2440

when you use dup you simulate child process stdin with input of pipe so when you execute sort without any argument it's read from stdin and it read until it see EOF so you must write to pipe then close it.

#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/wait.h>

int main(){

   int pipefd[2];
   //create a pipe before you fork a child process
   pipe(pipefd);

   pid_t cpid = fork();
   if(cpid < 0){
       perror("Fork");
   } else if(cpid == 0) {
       printf("This is child process\n");

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

       dup2(pipefd[0],0);

       execlp("sort", "sort", NULL);

       exit(0);

  } else {
      printf("This is parent process\n");
      close(pipefd[0]);

      char *sort_array[] = {"hello", "amigos", "gracias", "hola"};
      for (int i=0; i<4; i++){
          write(pipefd[1],sort_array[i],strlen(sort_array[i]));
          write(pipefd[1], "\n",1);
      }
      close(pipefd[1]);


      int cstatus;
      wait(&cstatus);

    }
}

Upvotes: 1

Related Questions