Skip to content

Instantly share code, notes, and snippets.

@sasakiyudai
Last active October 24, 2023 10:11
Show Gist options
  • Save sasakiyudai/f7cb5ccc5cd85ae7f23d37748bfb1cfa to your computer and use it in GitHub Desktop.
Save sasakiyudai/f7cb5ccc5cd85ae7f23d37748bfb1cfa to your computer and use it in GitHub Desktop.
Implementation of Multiple pipes in C.
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
// just count number of commands
int count(char ***cmd) {
int i;
i = 0;
while (cmd[i]) i++;
return i;
}
void pipeline(char ***cmd) {
int i, j = 0;
pid_t pid;
int cmd_len = count(cmd);
int fd[2 * cmd_len];
// pipe(2) for cmd_len times
for (i = 0; i < cmd_len; i++) {
if (pipe(fd + i * 2) < 0) {
perror("couldn't pipe");
exit(EXIT_FAILURE);
}
}
while (*cmd != NULL) {
if ((pid = fork()) == -1) {
perror("fork");
exit(1);
} else if (pid == 0) {
// if there is next
if (*(cmd + 1) != NULL) {
if (dup2(fd[j + 1], 1) < 0) {
perror("dup2");
exit(EXIT_FAILURE);
}
}
// if there is previous
if (j != 0) {
if (dup2(fd[j - 2], 0) < 0) {
perror("dup2");
exit(EXIT_FAILURE);
}
}
for (i = 0; i < 2 * cmd_len; i++) {
close(fd[i]);
}
if (execvp((*cmd)[0], *cmd) < 0) {
perror((*cmd)[0]);
exit(EXIT_FAILURE);
}
} else if (pid < 0) {
perror("error");
exit(EXIT_FAILURE);
}
// no wait in each process,
// because I want children to exec without waiting for each other
// as bash does.
cmd++;
j += 2;
}
// close fds in parent process
for (i = 0; i < 2 * cmd_len; i++) {
close(fd[i]);
}
// wait for children
for (i = 0; i < cmd_len; i++) wait(NULL);
}
int main(int argc, char *argv[]) {
char *ls[] = {"ls", NULL};
char *rev[] = {"rev", NULL};
char *nl[] = {"nl", NULL};
char *cat[] = {"cat", NULL};
char *wc[] = {"wc", "-c", NULL};
char *head[] = {"head", "-c", "1000", NULL};
char *time[] = {"time", "-p", "sleep", "3", NULL};
char *echo[] = {"echo", "toto", NULL};
char **cmd[] = {cat, ls, cat, NULL};
pipeline(cmd);
return (0);
}
@sasakiyudai
Copy link
Author

I used https://gist.github.com/iomonad/a66f6e9cfb935dc12c0244c1e48db5c8 as reference.

As mentioned there, even though it is very useful to understand, some problem remains.
So, I tried to resolve the problem.

Thanks.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment