-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathprocesses.c
117 lines (107 loc) · 3.2 KB
/
processes.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
/* ************************************************************************** */
/* */
/* :::::::: */
/* processes.c :+: :+: */
/* +:+ */
/* By: jvan-hal <[email protected]> +#+ */
/* +#+ */
/* Created: 2023/03/14 13:38:41 by jvan-hal #+# #+# */
/* Updated: 2023/03/23 11:21:58 by jvan-hal ######## odam.nl */
/* */
/* ************************************************************************** */
#include<unistd.h>
#include<stdlib.h>
#include<stdio.h>
#include<sys/wait.h>
#include<errno.h>
#include"pipex.h"
static void child_process(int *tube, char **envp, int fd, t_info *state)
{
if (dup2(fd, STDIN_FILENO) == -1 || close(fd) == -1)
exit(errno);
if (dup2(tube[1], STDOUT_FILENO) == -1 || close(tube[1]) == -1
|| close(tube[0]) == -1)
exit(errno);
state->comm_argv[state->index] = split_args(state->argv[state->index
+ state->offset], ' ');
state->comm_paths[state->index] = get_path(state->paths,
state->comm_argv[state->index][0]);
execve(state->comm_paths[state->index], state->comm_argv[state->index],
envp);
exit(errno);
}
static void child_process_last(char **envp, int fd, int *tube, t_info *state)
{
int outfd;
if (close(tube[0]) == -1 || close(tube[1]) == -1)
exit(errno);
if (dup2(fd, STDIN_FILENO) == -1 || close(fd) == -1)
exit(errno);
outfd = open_outfile(state);
if (dup2(outfd, STDOUT_FILENO) == -1 || close(outfd) == -1)
exit(errno);
state->comm_argv[state->index] = split_args(state->argv[state->index
+ state->offset], ' ');
state->comm_paths[state->index] = get_path(state->paths,
state->comm_argv[state->index][0]);
execve(state->comm_paths[state->index], state->comm_argv[state->index],
envp);
exit(errno);
}
static int pipe_and_fork(t_info *state, int *tube)
{
int pid;
if (pipe(tube) == -1)
{
perror("Pipe");
free_state(state);
exit(EXIT_FAILURE);
}
pid = fork();
if (pid == -1)
{
perror("Fork");
free_state(state);
exit(EXIT_FAILURE);
}
return (pid);
}
static void parent_end(t_info *state, int child_id, int *tube)
{
int status;
if (close(tube[0]) == -1)
{
free_state(state);
exit(EXIT_FAILURE);
}
waitpid(child_id, &status, 0);
free_state(state);
if (WIFEXITED(status))
exit(WEXITSTATUS(status));
exit(EXIT_FAILURE);
}
int exec_command(char **envp, int fd, t_info *state)
{
int tube[2];
pid_t pid;
pid = pipe_and_fork(state, tube);
if (pid == 0)
{
if (state->argv[state->index + state->offset + 2])
child_process(tube, envp, fd, state);
else
child_process_last(envp, fd, tube, state);
}
else if (state->argv[state->index + state->offset + 2])
{
if (close(tube[1]) == -1)
{
free_state(state);
exit(EXIT_FAILURE);
}
++(state->index);
exec_command(envp, tube[0], state);
}
parent_end(state, pid, tube);
exit(EXIT_FAILURE);
}