GCC Code Coverage Report


Directory: ./
File: src/separators/pipes.c
Date: 2024-05-07 14:54:03
Exec Total Coverage
Lines: 78 84 92.9%
Functions: 6 6 100.0%
Branches: 42 46 91.3%

Line Branch Exec Source
1 /*
2 ** EPITECH PROJECT, 2024
3 ** 42sh
4 ** File description:
5 ** The file containing the pipes functions
6 */
7 /**
8 * @file pipes.c
9 * @brief The file containing the pipes functions
10 */
11
12 #include "../../include/myshell.h"
13 #include <sys/mman.h>
14
15 /**
16 * @brief Check if the command contains an ambiguous command
17 * @param mysh The shell structure
18 * @return <b>int</b> <u>1</u> if an error occurred, <u>0</u> otherwise
19 */
20 98 static int check_ambiguous_command(mysh_t *mysh)
21 {
22
2/2
✓ Branch 0 taken 212 times.
✓ Branch 1 taken 95 times.
307 for (int index = 0; mysh->input_list[index] != NULL; index++) {
23
4/4
✓ Branch 0 taken 114 times.
✓ Branch 1 taken 98 times.
✓ Branch 2 taken 2 times.
✓ Branch 3 taken 112 times.
212 if (index != 0 && mysh->input_list[index]->left_type != 0) {
24 2 mysh->exit_status = 1;
25 2 my_putstr_error("Ambiguous input redirect.\n");
26 2 free_input_list(mysh);
27 2 FREE_WORD_ARRAY(mysh->pipe_cmds);
28 2 return 1;
29 }
30
2/2
✓ Branch 0 taken 115 times.
✓ Branch 1 taken 95 times.
210 if (mysh->pipe_cmds[index + 1] != NULL &&
31
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 114 times.
115 mysh->input_list[index]->right_type != 0) {
32 1 mysh->exit_status = 1;
33 1 my_putstr_error("Ambiguous output redirect.\n");
34 1 free_input_list(mysh);
35 1 FREE_WORD_ARRAY(mysh->pipe_cmds);
36 1 return 1;
37 }
38 }
39 95 return 0;
40 }
41
42 /**
43 * @brief Check if the command is a null command
44 * @param mysh The shell structure
45 * @param line The command line
46 * @return <b>int</b> <u>1</u> if the command is a null command,
47 * <u>0</u> otherwise
48 */
49 1147 static int check_null_command(mysh_t *mysh, char *line)
50 {
51
2/2
✓ Branch 0 taken 41380 times.
✓ Branch 1 taken 1048 times.
42428 for (int index = 0; line[index] != '\0' &&
52
2/2
✓ Branch 0 taken 41281 times.
✓ Branch 1 taken 99 times.
82661 mysh->pipe_cmds[1] == NULL; index++) {
53
4/4
✓ Branch 0 taken 49 times.
✓ Branch 1 taken 41232 times.
✓ Branch 3 taken 37 times.
✓ Branch 4 taken 12 times.
41281 if (line[index] == '|' && char_is_inhibited(line, index) == 0
54
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 37 times.
37 && char_is_paranthesed(line, index) == 0) {
55 mysh->exit_status = 1;
56 my_putstr_error("Invalid null command.\n");
57 free_input_list(mysh);
58 FREE_WORD_ARRAY(mysh->pipe_cmds);
59 return 1;
60 }
61 }
62 1147 return 0;
63 }
64
65 /**
66 * @brief Check if the command contains a pipe or not
67 * @param mysh The shell structure
68 * @param line The command line
69 * @return <b>int</b> <u>1</u> if the command doesn't contain a pipe
70 * or only pipes, <u>0</u> if the command contains a pipe
71 */
72 1147 static int check_pipe(mysh_t *mysh, char *line)
73 {
74
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 1147 times.
1147 if (check_null_command(mysh, line))
75 return 1;
76
2/2
✓ Branch 0 taken 1048 times.
✓ Branch 1 taken 99 times.
1147 if (mysh->pipe_cmds[1] == NULL) {
77 1048 select_redirections(mysh, mysh->input_list[0]);
78 692 free_input_list(mysh);
79 692 FREE_WORD_ARRAY(mysh->pipe_cmds);
80 692 return 1;
81 }
82
2/2
✓ Branch 0 taken 214 times.
✓ Branch 1 taken 98 times.
312 for (int index = 0; mysh->pipe_cmds[index] != NULL; index++) {
83
3/4
✓ Branch 1 taken 213 times.
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 213 times.
214 if (my_str_is(mysh->pipe_cmds[index], " \t\n") || line[0] == '|') {
84 1 mysh->exit_status = 1;
85 1 my_putstr_error("Invalid null command.\n");
86 1 free_input_list(mysh);
87 1 FREE_WORD_ARRAY(mysh->pipe_cmds);
88 1 return 1;
89 }
90 }
91 98 return check_ambiguous_command(mysh);
92 }
93
94 /**
95 * @brief Set the pipe list (input_list and pipe_cmds)
96 * @param mysh The shell structure
97 * @param line The command line
98 * @return <b>void</b>
99 */
100 1168 int set_pipe_list(mysh_t *mysh, char *line)
101 {
102 1168 int index = 0;
103
104
3/4
✓ Branch 0 taken 1168 times.
✗ Branch 1 not taken.
✓ Branch 3 taken 4 times.
✓ Branch 4 taken 1164 times.
1168 if (line == NULL || my_strcmp(line, "") == 0)
105 4 return 1;
106 1164 mysh->pipe_cmds = array_separators(line, "|");
107 1164 mysh->input_list = malloc(sizeof(input_command_t *) *
108 1164 (my_array_len((void **) mysh->pipe_cmds) + 1));
109
2/2
✓ Branch 0 taken 1280 times.
✓ Branch 1 taken 1147 times.
2427 for (; mysh->pipe_cmds[index] != NULL; index++) {
110 1280 mysh->input_list[index] = get_input_command(mysh->pipe_cmds[index]);
111
2/2
✓ Branch 0 taken 17 times.
✓ Branch 1 taken 1263 times.
1280 if (mysh->input_list[index] == NULL) {
112 17 mysh->exit_status = 1;
113 17 free_input_list(mysh);
114 17 FREE_WORD_ARRAY(mysh->pipe_cmds);
115 17 return 1;
116 }
117 }
118 1147 mysh->input_list[index] = NULL;
119 1147 return 0;
120 }
121
122 /**
123 * @brief Execute the pipe
124 * @param mysh The shell structure
125 * @param line The command line
126 * @param index The index of the command
127 * @return <b>void</b>
128 */
129 112 static void execute_pipe(mysh_t *mysh, char *line, int index)
130 {
131 int fd[2];
132 112 pid_t pid = 0;
133
134 112 pipe(fd);
135 112 pid = fork();
136
2/2
✓ Branch 0 taken 120 times.
✓ Branch 1 taken 112 times.
232 if (pid == 0) {
137 120 close(fd[0]);
138 120 dup2(fd[1], 1);
139 120 select_redirections(mysh, mysh->input_list[index]);
140 119 my_exit(mysh, mysh->exit_status, NULL);
141 } else {
142 112 close(fd[1]);
143 112 dup2(fd[0], 0);
144 }
145 112 }
146
147 /**
148 * @brief Analyse and execute the pipes
149 * @param mysh The shell structure
150 * @param line The command line
151 * @return <b>void</b>
152 */
153 1168 void analyse_pipes(mysh_t *mysh, char *line)
154 {
155
4/4
✓ Branch 1 taken 1147 times.
✓ Branch 2 taken 21 times.
✓ Branch 4 taken 696 times.
✓ Branch 5 taken 95 times.
1168 if (set_pipe_list(mysh, line) || check_pipe(mysh, line))
156 717 return;
157 95 mysh->saved_stdin = dup(0);
158 95 mysh->saved_stdout = dup(1);
159
2/2
✓ Branch 0 taken 112 times.
✓ Branch 1 taken 95 times.
207 for (int index = 0; mysh->pipe_cmds[index + 1] != NULL; index++)
160 112 execute_pipe(mysh, line, index);
161 190 select_redirections(mysh, mysh->input_list
162 95 [my_array_len((void **)mysh->pipe_cmds) - 1]);
163 95 dup2(mysh->saved_stdin, 0);
164 95 dup2(mysh->saved_stdout, 1);
165 95 free_input_list(mysh);
166 95 FREE_WORD_ARRAY(mysh->pipe_cmds);
167 }
168