-
-
Save mplewis/5279108 to your computer and use it in GitHub Desktop.
// This program is an example of how to run a command such as | |
// ps aux | grep root | grep sbin | |
// using C and Unix. | |
#include <stdlib.h> | |
#include <unistd.h> | |
int pid; | |
int pipe1[2]; | |
int pipe2[2]; | |
void main() { | |
// create pipe1 | |
if (pipe(pipe1) == -1) { | |
perror("bad pipe1"); | |
exit(1); | |
} | |
// fork (ps aux) | |
if ((pid = fork()) == -1) { | |
perror("bad fork1"); | |
exit(1); | |
} else if (pid == 0) { | |
// stdin --> ps --> pipe1 | |
exec1(); | |
} | |
// parent | |
// create pipe2 | |
if (pipe(pipe2) == -1) { | |
perror("bad pipe2"); | |
exit(1); | |
} | |
// fork (grep root) | |
if ((pid = fork()) == -1) { | |
perror("bad fork2"); | |
exit(1); | |
} else if (pid == 0) { | |
// pipe1 --> grep --> pipe2 | |
exec2(); | |
} | |
// parent | |
// close unused fds | |
close(pipe1[0]); | |
close(pipe1[1]); | |
// fork (grep sbin) | |
if ((pid = fork()) == -1) { | |
perror("bad fork3"); | |
exit(1); | |
} else if (pid == 0) { | |
// pipe2 --> grep --> stdout | |
exec3(); | |
} | |
// parent | |
} | |
void exec1() { | |
// input from stdin (already done) | |
// output to pipe1 | |
dup2(pipe1[1], 1); | |
// close fds | |
close(pipe1[0]); | |
close(pipe1[1]); | |
// exec | |
execlp("ps", "ps", "aux", NULL); | |
// exec didn't work, exit | |
perror("bad exec ps"); | |
_exit(1); | |
} | |
void exec2() { | |
// input from pipe1 | |
dup2(pipe1[0], 0); | |
// output to pipe2 | |
dup2(pipe2[1], 1); | |
// close fds | |
close(pipe1[0]); | |
close(pipe1[1]); | |
close(pipe2[0]); | |
close(pipe2[1]); | |
// exec | |
execlp("grep", "grep", "root", NULL); | |
// exec didn't work, exit | |
perror("bad exec grep root"); | |
_exit(1); | |
} | |
void exec3() { | |
// input from pipe2 | |
dup2(pipe2[0], 0); | |
// output to stdout (already done) | |
// close fds | |
close(pipe2[0]); | |
close(pipe2[1]); | |
// exec | |
execlp("grep", "grep", "sbin", NULL); | |
// exec didn't work, exit | |
perror("bad exec grep sbin"); | |
_exit(1); | |
} |
Appreciate the help, but not sure why you would post something that doesn't compile.
Thank you, this helped a lot :)
Thank you for this, it really makes the concept simple and understandable
For additional help, an excellent example of pipes in C in Linux is here under the "EXAMPLES" section: https://man7.org/linux/man-pages/man2/pipe.2.html
Also, I can confirm that threePipeDemo.c does compile, contrary to what @nskoro says. Just make sure you do NOT use -Werror
in your compile command, as there are a variety of warnings.
Here is my compile command. I tested this on Linux Ubuntu 18.04.
# compile
mkdir -p bin && gcc -Wall -Wextra -O3 -std=c17 threePipeDemo.c -o bin/a
# then run the program with:
bin/a
Here's my compile command and the output with a bunch of warnings:
eRCaGuy_hello_world/c/todo$ mkdir -p bin && gcc -Wall -Wextra -O3 -std=c17 threePipeDemo.c -o bin/a
threePipeDemo.c:52:6: warning: return type of ‘main’ is not ‘int’ [-Wmain]
void main() {
^~~~
threePipeDemo.c: In function ‘main’:
threePipeDemo.c:56:5: warning: implicit declaration of function ‘perror’ [-Wimplicit-function-declaration]
perror("bad pipe1");
^~~~~~
threePipeDemo.c:66:5: warning: implicit declaration of function ‘exec1’; did you mean ‘execl’? [-Wimplicit-function-declaration]
exec1();
^~~~~
execl
threePipeDemo.c:82:5: warning: implicit declaration of function ‘exec2’; did you mean ‘execl’? [-Wimplicit-function-declaration]
exec2();
^~~~~
execl
threePipeDemo.c:96:5: warning: implicit declaration of function ‘exec3’; did you mean ‘execl’? [-Wimplicit-function-declaration]
exec3();
^~~~~
execl
threePipeDemo.c: At top level:
threePipeDemo.c:104:6: warning: conflicting types for ‘exec1’
void exec1() {
^~~~~
threePipeDemo.c:66:5: note: previous implicit declaration of ‘exec1’ was here
exec1();
^~~~~
threePipeDemo.c:118:6: warning: conflicting types for ‘exec2’
void exec2() {
^~~~~
threePipeDemo.c:82:5: note: previous implicit declaration of ‘exec2’ was here
exec2();
^~~~~
threePipeDemo.c:135:6: warning: conflicting types for ‘exec3’
void exec3() {
^~~~~
threePipeDemo.c:96:5: note: previous implicit declaration of ‘exec3’ was here
exec3();
^~~~~
This is incredibly helpful for anyone trying to understand the super confusing execlp()
cmd: I do not understand how execlp() works in Linux
thz...