Skip to content

Commit 28c5dfe

Browse files
author
Anton Yarkov
committed
Named and nonamed pipes examples.
1 parent ddce52c commit 28c5dfe

File tree

4 files changed

+286
-0
lines changed

4 files changed

+286
-0
lines changed

multithreading/03 - Nonamed_pipes.cpp

Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,132 @@
1+
#include <iostream>
2+
#include <stdio.h>
3+
#include <stdlib.h>
4+
#include <unistd.h>
5+
#include <sys/types.h>
6+
#include <sys/wait.h>
7+
8+
using namespace std;
9+
10+
struct CmdLine
11+
{
12+
char* value;
13+
char* arguments;
14+
CmdLine* next;
15+
};
16+
17+
// Compilation:
18+
// g++ "03 - Nonamed_pipes.cpp" -o nonamedpipes
19+
20+
// Task:
21+
// Create a program which works just like the command below:
22+
// $> who | sort | uniq -c | sort -nk1
23+
24+
void run(CmdLine* command)
25+
{
26+
const int numPipes = 3;
27+
int i = 0;
28+
pid_t pid;
29+
30+
// Create all pipes.
31+
int pipefds[2*numPipes];
32+
for(i = 0; i < (numPipes); i++)
33+
{
34+
if(pipe(pipefds + i*2) < 0)
35+
{
36+
printf("Couldn't create pipe %d\n", i + 1);
37+
exit(EXIT_FAILURE);
38+
}
39+
}
40+
41+
int j = 0;
42+
while(command)
43+
{
44+
pid = fork();
45+
if(pid == 0)
46+
{
47+
//if not last command
48+
if(command->next)
49+
{
50+
if(dup2(pipefds[j + 1], STDOUT_FILENO) < 0)
51+
{
52+
perror("dup2");
53+
exit(EXIT_FAILURE);
54+
}
55+
}
56+
57+
//if not first command && j != 2*numPipes
58+
if(j != 0 )
59+
{
60+
if(dup2(pipefds[j-2], STDIN_FILENO) < 0)
61+
{
62+
perror(" dup2");///j-2 0 j+1 1
63+
exit(EXIT_FAILURE);
64+
}
65+
}
66+
67+
68+
for(i = 0; i < 2*numPipes; i++)
69+
{
70+
close(pipefds[i]);
71+
}
72+
73+
// Command with or without arguments.
74+
if (command->arguments == NULL)
75+
{
76+
if( execlp(command->value, command->value, NULL) < 0 )
77+
{
78+
perror(command->value);
79+
exit(EXIT_FAILURE);
80+
}
81+
}
82+
else
83+
{
84+
if( execlp(command->value, command->value, command->arguments, NULL) < 0 )
85+
{
86+
perror(command->value);
87+
exit(EXIT_FAILURE);
88+
}
89+
}
90+
}
91+
else if(pid < 0)
92+
{
93+
perror("error");
94+
exit(EXIT_FAILURE);
95+
}
96+
97+
command = command->next;
98+
j+=2;
99+
}
100+
101+
/* Parent closes the pipes and wait for children */
102+
for(i = 0; i < 2 * numPipes; i++)
103+
{
104+
close(pipefds[i]);
105+
}
106+
107+
int status;
108+
for(i = 0; i < numPipes + 1; i++)
109+
{
110+
wait(&status);
111+
}
112+
}
113+
114+
int main(int argc, char** argv)
115+
{
116+
printf("Result of operation is the same like if you type\n$>who | sort | uniq -c | sort -nk1\n");
117+
118+
char sort[] = "sort";
119+
char sortArg[] = "-nk1";
120+
char uniq[] = "uniq";
121+
char uniqArg[] = "-c";
122+
char who[] = "who";
123+
124+
CmdLine command4 = { sort, sortArg, NULL };
125+
CmdLine command3 = { uniq, uniqArg, &command4 };
126+
CmdLine command2 = { sort, NULL, &command3 };
127+
CmdLine command1 = { who, NULL, &command2 };
128+
129+
run(&command1);
130+
131+
return 0;
132+
}
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
#include <stdio.h>
2+
#include <stdlib.h>
3+
#include <string.h>
4+
#include <unistd.h>
5+
#include <sys/types.h>
6+
7+
#define EXIT_FAILURE 1
8+
9+
// Compilation:
10+
// gcc "03 - Nonamed_pipes_read_write.c" -o nonamedpipesrw
11+
12+
// Task:
13+
// Do write on one end and read on another end.
14+
15+
void main()
16+
{
17+
int fd[2], nbytes;
18+
pid_t childpid;
19+
char string[] = "Hello, world!\n";
20+
char readbuffer[80];
21+
22+
pipe(fd);
23+
24+
printf("Process %d creates child\n", getpid());
25+
26+
if((childpid = fork()) == -1)
27+
{
28+
perror("fork");
29+
exit(EXIT_FAILURE);
30+
}
31+
32+
if(childpid == 0)
33+
{
34+
/* Child process closes up input side of pipe */
35+
close(fd[0]);
36+
37+
/* Send "string" through the output side of pipe */
38+
write(fd[1], string, (strlen(string)+1));
39+
printf("Done write in process %d\n", getpid());
40+
exit(0);
41+
}
42+
else
43+
{
44+
/* Parent process closes up output side of pipe */
45+
close(fd[1]);
46+
47+
/* Read in a string from the pipe */
48+
nbytes = read(fd[0], readbuffer, sizeof(readbuffer));
49+
printf("Received string: %s in process %d\n", readbuffer, getpid());
50+
}
51+
52+
exit(0);
53+
}
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
#include <stdio.h>
2+
#include <unistd.h>
3+
4+
// Compilation:
5+
// gcc "03 - Nonamed_pipes_wc_logins.c" -o nonamedpipeslogins
6+
7+
// Task:
8+
// Create a program which works just like the command
9+
// $> who | wc -l
10+
11+
// Help:
12+
// Create pipe: who -> stdout -> [pfd[1] -> pfd[0]] -> stdin -> wc -l
13+
void main()
14+
{
15+
printf("Result of operation is the same like if you type\n$>who | wc -l\n");
16+
17+
int pfd[2];
18+
19+
pipe(pfd);
20+
21+
if (!fork())
22+
{
23+
// Since descriptors are shared between the parent and child,
24+
// we should always be sure to close the end of pipe we aren't concerned with.
25+
// On a technical note, the EOF will never be returned
26+
// if the unnecessary ends of the pipe are not explicitly closed.
27+
close(STDOUT_FILENO);
28+
dup2(pfd[1], STDOUT_FILENO);
29+
close(pfd[1]);
30+
close(pfd[0]);
31+
execlp("who", "who", NULL);
32+
}
33+
else
34+
{
35+
close(STDIN_FILENO);
36+
dup2(pfd[0], STDIN_FILENO);
37+
close(pfd[1]);
38+
close(pfd[0]);
39+
execlp("wc", "wc", "-l", NULL);
40+
}
41+
exit(0);
42+
}

multithreading/04 - Named_pipes.c

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
#include <fcntl.h>
2+
#include <stdio.h>
3+
#include <stdlib.h>
4+
#include <string.h>
5+
#include <unistd.h>
6+
#include <sys/types.h>
7+
#include <sys/stat.h>
8+
9+
#define EXIT_FAILURE 1
10+
11+
// Compilation:
12+
// gcc "04 - Named_pipes.c" -o namedpipes
13+
14+
// Task:
15+
// Create Named Pipe aka FIFO to do write on one end and read on another end.
16+
17+
void main()
18+
{
19+
char * myfifo = "/tmp/myfifo";
20+
mkfifo(myfifo, 0666);
21+
22+
23+
pid_t childpid;
24+
if((childpid = fork()) == -1)
25+
{
26+
perror("fork");
27+
exit(EXIT_FAILURE);
28+
}
29+
30+
if(childpid == 0)
31+
{
32+
char string[] = "Hello, world!";
33+
int fd;
34+
if (fd = open(myfifo, O_WRONLY))
35+
{
36+
write(fd, string, (strlen(string)+1));
37+
close(fd);
38+
}
39+
40+
printf("Process %d done write and unlink fifo.\n", getpid());
41+
unlink(myfifo);
42+
}
43+
else
44+
{
45+
printf("Process %d creates child %d\n", getpid(), childpid);
46+
47+
char readbuffer[80];
48+
int fd;
49+
if (fd = open(myfifo, O_RDONLY))
50+
{
51+
read(fd, readbuffer, 80);
52+
printf("Process %d received string: %s\n", getpid(), readbuffer);
53+
close(fd);
54+
}
55+
unlink(myfifo);
56+
}
57+
58+
exit(0);
59+
}

0 commit comments

Comments
 (0)