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
|
#include "exec.h"
#include "parser.h"
#include "builtin.h"
#include "variable.h"
#include "../lib/sys/fork.h"
#include "../lib/sys/wait4.h"
#include "../lib/sys/pipe.h"
#include "../lib/sys/dup2.h"
#include "../lib/sys/close.h"
#include "../lib/sys/exit.h"
#include "../lib/cstr/cstr.h"
#include "../lib/io/io.h"
#include "../lib/env/env.h"
#include "../lib/malloc/malloc.h"
#include "../lib/list/list.h"
#include "../lib/exec/exec.h"
void print_call(char **argv)
{
while (*argv) {
write(STDOUT_FD, *argv, cstr_length(*argv));
write(STDOUT_FD, "\n", 1);
++argv;
}
}
void execute_line(char *line)
{
expression_list_t *exps = new_expression_from_line(line);
expression_list_t *exp = exps;
list_t *pids = new_list();
int pid;
int pipefd[2][2];
pipefd[0][PIPE_IN] = STDOUT_FD;
pipefd[0][PIPE_OUT] = STDIN_FD;
while (exp) {
char **argv = new_argv(exp->call);
pipe(pipefd[1]);
if (has_builtin_with_name(argv[0])) {
run_builtin(argv[0], (const char**)argv);
break;
}
pid = fork();
if (pid == 0) {
if (pipefd[0][PIPE_OUT] != STDIN_FD) {
dup2(pipefd[0][PIPE_OUT], STDIN_FD);
close(pipefd[0][PIPE_OUT]);
close(pipefd[0][PIPE_IN]);
}
if (exp->next)
dup2(pipefd[1][PIPE_IN], STDOUT_FD);
else if (get_end_fd() != STDOUT_FD)
dup2(get_end_fd(), STDOUT_FD);
close(pipefd[1][PIPE_OUT]);
close(pipefd[1][PIPE_IN]);
exec((const char **)argv);
wff(STDERR_FD, "command not found: %s\n", argv[0]);
exit(-1);
}
if (pipefd[0][PIPE_OUT] != STDIN_FD) {
close(pipefd[0][PIPE_IN]);
close(pipefd[0][PIPE_OUT]);
}
pipefd[0][0] = pipefd[1][0];
pipefd[0][1] = pipefd[1][1];
free_argv(argv);
list_append(pids, pid);
exp = exp->next;
}
list_node_t *node = pids->first;
for (; node; node = node->next) {
wait4((int)node->value, 0, 0);
}
free_expression(exps);
}
#ifdef EXEC_UNIT_TEST
int main() {
char *argv[] = { "ls" };
__execenv(argv);
}
#endif
|