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
+
29
+ // Create all pipes.
30
+ int pipefds[2 *numPipes];
31
+ for (i = 0 ; i < (numPipes); i++)
32
+ {
33
+ if (pipe (pipefds + i*2 ) < 0 )
34
+ {
35
+ printf (" Couldn't create pipe %d\n " , i + 1 );
36
+ exit (EXIT_FAILURE);
37
+ }
38
+ }
39
+
40
+ int j = 0 ;
41
+ pid_t pid;
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
+ }
0 commit comments