-
Notifications
You must be signed in to change notification settings - Fork 0
/
pipe.c
139 lines (110 loc) · 2.76 KB
/
pipe.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
/**
* @file
*
* Pipe implementation
*/
#include <stdbool.h>
#include <stdio.h>
#include <string.h>
#include <sys/wait.h>
#include <fcntl.h>
#include <unistd.h>
#include <limits.h>
#include "pipe.h"
#include "next_token.h"
#include "ui.h"
/**
function that creates my commands
*/
void createCmd(char **cmd, int num, struct command_line *commands)
{
int index = 0;
commands[index].tokens = &cmd[0];
commands[index].stdout_pipe = true;
commands[index].stdout_file = NULL;
index++;
for(int i =0; i< num; i++){
if(strcmp(cmd[i], "|") == 0){
cmd[i] = 0;
commands[index].tokens = &cmd[i + 1];
commands[index].stdout_pipe = true;
commands[index].stdout_file = NULL;
index++;
}
else if(strcmp(cmd[i], ">") == 0){
cmd[i] = 0;
commands[index -1].stdout_file = cmd[i + 1];
}
}
commands[index -1].stdout_pipe = false;
}
/**
function that executes my pipeline
*/
void execute_pipeline(struct command_line *cmds)
{
int open_flags = O_RDWR | O_CREAT | O_TRUNC;
if(cmds -> stdout_pipe != false){
int fildes[2] = {0};
if(pipe(fildes) == -1){
perror("pipe");
return;
}
int child = fork();
if(child == 0){
dup2(fildes[1], fileno(stdout));
close(fildes[0]);
execvp(cmds-> tokens[0], cmds-> tokens);
}else if(child == -1){
perror("child");
return;
}
else{
dup2(fildes[0], fileno(stdin));
close(fildes[1]);
execute_pipeline(++cmds);
}
}else{
if (cmds-> stdout_file != NULL) {
int open_perms = 0644;
int fd = open(cmds-> stdout_file, open_flags, open_perms);
if (fd == -1) {
perror("open");
return;
}
if (dup2(fd, fileno(stdout)) == -1) {
close(fd);
return;
}
}
execvp(cmds-> tokens[0], cmds-> tokens);
return;
}
}
/**
function that tokenize my commands
*/
void tokenize(char* command){
char *curr_tok;
char *next_tok;
int num = 0;
char *cmd[_POSIX_ARG_MAX] = {0};
next_tok = command;
while((curr_tok = next_token(&next_tok, " \t")) != NULL) {
cmd[num++] = curr_tok;
}
struct command_line cmds[_POSIX_ARG_MAX];
createCmd(cmd, num, cmds);
pid_t child = fork();
if (child == 0) {
execute_pipeline(cmds);
} else if (child == -1) {
//error handling
perror("fork");
} else {
int status;
waitpid(child, &status, 0);
set_status(status);
//status //WHNSMTH -> project
}
}