Skip to content

Instantly share code, notes, and snippets.

@a-cordier
Created November 24, 2015 19:41
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save a-cordier/33211eda92b8084a9e7e to your computer and use it in GitHub Desktop.
Save a-cordier/33211eda92b8084a9e7e to your computer and use it in GitHub Desktop.
using pipe() dup() and execlp to mock the | shell operator
#include <sys/wait.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
/**
Using pipe() and dup() plus execlp() to
reproduce the | shell operator behavior
**/
int main(int argc, char *argv[])
{
int pfd[2];
pid_t cpid;
char buf;
if(argc != 2)
{
fprintf(stderr, "Missing parameter\n");
exit(-1);
}
if(pipe(pfd) == -1)
{
fprintf(stderr, "Pipe error\n");
exit(-1);
}
cpid = fork();
if(cpid == -1)
{
fprintf(stderr, "Fork error\n");
exit(-1);
}
if( cpid == 0 )
{
/* child will not write into pipe */
close(pfd[1]);
/* closing the standard input file descriptor*/
close(STDIN_FILENO);
/* dup returns the lower number available for a file descriptor
As we just closed the STDIN file desc (0) we know that what we
get here is 0 */
int new_stdin = dup(pfd[0]);
/* what folows from there is that
any command reading from stdin will
now read its input from the pipe input file desc */
execlp("wc","wc", "-l", 0);
close(pfd[0]);
close(new_stdin);
exit(0);
}
else
{
/* Father */
close(pfd[0]);
close(STDOUT_FILENO);
/* dup returns the lower number available for a file descriptor
As we just closed the STDOUT file desc (1) we know that what we
get here is 1 */
int new_stdout = dup(pfd[1]);
/* what folows from there is that
any command writing to stdout will
now write its output into the pipe */
execlp("ls", "ls", (char *)NULL);
close(pfd[1]);
close(new_stdout);
/* waiting for child */
wait(NULL);
exit(EXIT_SUCCESS);
}
return(0);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment