Skip to content

Instantly share code, notes, and snippets.

@Hermann-SW
Last active September 5, 2021 08:47
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 Hermann-SW/d0701c1c5c3c25d0c4eb4a8f14812f9f to your computer and use it in GitHub Desktop.
Save Hermann-SW/d0701c1c5c3c25d0c4eb4a8f14812f9f to your computer and use it in GitHub Desktop.
"man pipe" example extended to N childs+pipes
/* gcc -Wall -Wextra -pedantic pipeN.c -o pipeN
*/
#include <sys/types.h>
#include <sys/wait.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <assert.h>
int main(int argc, char *argv[])
{
assert(argc >= 3 || !"Usage: ./pipeN N <string> d1 ... dN");
int N = atoi(argv[1]);
assert(argc == 3+N || !"Usage: ./pipeN N <string> d1 ... dN");
int fd[N];
pid_t pid[N];
char buff[strlen(argv[2])+2];
for(int i=0; i<N; ++i) /* setup N childs+pipes */
{
int pipefd[2];
pid_t cpid;
char buf;
assert(pipe(pipefd) != -1);
cpid = fork();
assert(cpid != -1);
if (cpid == 0) { /* Child reads from pipe */
close(pipefd[1]); /* Close unused write end */
while (read(pipefd[0], &buf, 1) > 0)
write(STDOUT_FILENO, &buf, 1);
close(pipefd[0]);
_exit(EXIT_SUCCESS);
} else { /* Parent writes to pipe */
close(pipefd[0]); /* Close unused read end */
fd[i] = pipefd[1]; /* store for ... */
pid[i] = cpid; /* ... later use */
}
}
for(int i=0; i<N; ++i) /* send stuff to requested child */
{
int c = atoi(argv[3+i]);
assert(0<=c && c<N);
strncpy(buff, argv[2]+c, strlen(argv[2])-N+1);
buff[strlen(argv[2])-N+1]='\n';
buff[strlen(argv[2])-N+2]='\0';
write(fd[c], buff, strlen(argv[2])-N+3);
close(fd[c]); /* Reader will see EOF */
usleep(10000);
}
for(int i=0; i<N; ++i) /* Wait for all childs */
{
waitpid(pid[i], NULL, 0);
}
exit(EXIT_SUCCESS);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment