4

im trying to execute md5sume command in my programm using pipe,fork and dup.i found sum code that run succesfully but i cant understand some line of code. Here is my code:

int infp, outfp;

char buf[128];

if (popen2("md5sum", &infp, &outfp) <= 0)

  {

    printf("Unable to exec sort\n");

    exit(1);

  }

write(infp, "hello\n", 2);

close(infp);

*buf = '\0';

read(outfp, buf, 128);

printf("buf = '%s'\n", buf);

return 0;

}

int p_stdin[2], p_stdout[2];

pid_t pid;

if (pipe(p_stdin) != 0 || pipe(p_stdout) != 0)

  return -1;

pid = fork();

if (pid < 0)

  return pid;

if (pid == 0)

  {

    close(p_stdin[WRITE]);

    dup2(p_stdin[READ], READ);

    close(p_stdout[READ]);

    dup2(p_stdout[WRITE], WRITE);

    execl("/bin/sh", "sh", "-c", command, NULL);

    perror("execl");

    exit(1);

  }

else 

  {

if (infp == NULL)

    close(p_stdin[WRITE]);

else

    *infp = p_stdin[WRITE];

if (outfp == NULL)

    close(p_stdout[READ]);

else

    *outfp = p_stdout[READ];
  }

return pid;

}

i dont understand the popen function. What does this line exactly do?

*infp = p_stdin[WRITE];

how can pipes comunicate with each other?

Rafael Saraiva
  • 908
  • 2
  • 11
  • 23
farzane
  • 329
  • 2
  • 13
  • 3
    Format your code! Remove unnecessary empty lines. – too honest for this site Nov 04 '15 at 11:41
  • 1
    You're talking about`popen2()` not `popen()` I guess. I also guess that the 2nd code block is the `popen2()` function. You should refer to `man 2 pipe` and read the description. A pipe is represented by 2 file descriptors, one for write and one for read. What you write in it can be read from it. After `fork()` one of the processes can write in it and the other read from it, so they communicate. – hexasoft Nov 04 '15 at 11:50
  • yah i knew this.and also i knew that it was popen2 function.but i cant understand the use of integer to implement of bidirectional pipe and it wasnt in man!! – farzane Nov 07 '15 at 06:28
  • where do READ and WRITE come from? – sktpin Oct 04 '21 at 14:02

1 Answers1

2

i dont understand the popen function.

how can pipes comunicate with each other?

pipe() : A pipe is unidirectional and a byte stream buffer in kernel. As it is of type byte stream, a writer can write in arbitrary number of bytes and reader can read out arbitrary number of bytes. However, note that sequential reads are possible , but seek (like lseek) is not possible. Since pipe is uni-directinal, the data that is written into pipe shall be buffered in kernel, until it is read from the read-end of the pipe. Also, if pipe gets full, the write blocks.

Let's consider that fd is an integer array of 2 file descriptors (int fd[2]), then the pipe(fd) system call shall create a pipe and return a pair of file descriptors such that fd[1] (stdout is 1) shall be the write-end of the pipe and the fd[0] (stdin is 0) shall be the read-end of the pipe. Unlike named pipe(like FIFO - a pipe with name in File system), the anonymous pipes can be used only between related processes like parent-child. So, fork shall be done to duplicate these 2 parent file descriptors in child, thereby parent shares the pipe with child so that the child shall write in write-end and parent shall read from read-end of pipe or Parent shall write into write-end and child shall read from read-end of pipe. Care should be taken to ensure to close the unused read(fd[0]) file descriptor / unused write(fd[1]) file descriptor by the parent or child as per the scenario.

popen() : popen enables you to invoke another program as a new process and thereby transmit data to it or receive data from it. In case of popen, note that the direction of data flow is based on the 2nd argument. We need not manually create a child process as popen automatically forks for creating a child process, starts a shell and executes the command argument passed via popen. It also establishes appropriate read or write stream between parent and child automatically based on the type argument.

Thus, popen() simplifies things, as it avoids the need to manually call/invoke pipe,fork,exec and simplifies establishment of appropriate streams between parent / child automatically as per argument type. However, the other side of popen is that, it should be noted that every invocation of the popen() shall result in creation of extra process - that is, the shell is invoked every time apart from the program that is being invoked which in-turn leads to high resource consumption.

Community
  • 1
  • 1
Karthik Balaguru
  • 7,424
  • 7
  • 48
  • 65
  • i knew this.my main problem was about bidirectional pipe.you know in popen we can just set w or r mood at the second parameter but in my program i need to use rw mood.so i need bidirectional pipe! – farzane Nov 07 '15 at 06:25
  • pipe is unidirectional. popen supports only 'r' or 'w' and it does not support other option such as 'read and write'. In case of bidirectional communication requirement using pipes, you might need to implement two pipes such that one for each direction. – Karthik Balaguru Nov 17 '15 at 20:06