tgrekov-pipex
HIVE pipex May 2024
Loading...
Searching...
No Matches
dispatcher.c
Go to the documentation of this file.
1/* ************************************************************************** */
2/* */
3/* ::: :::::::: */
4/* dispatcher.c :+: :+: :+: */
5/* +:+ +:+ +:+ */
6/* By: tgrekov <tgrekov@student.hive.fi> +#+ +:+ +#+ */
7/* +#+#+#+#+#+ +#+ */
8/* Created: 2024/04/23 08:18:15 by tgrekov #+# #+# */
9/* Updated: 2024/05/23 05:11:33 by tgrekov ### ########.fr */
10/* */
11/* ************************************************************************** */
12
20#include <stdlib.h>
21#include <unistd.h>
22#include "../../mandatory/utils/utils.h"
23
24void dispatch(char **paths, char *args, char **envp, int *in_out);
25char **args_split(char const *s);
26int wait_all(int *pids, int n, int override);
27
28static int piping(int i, int n, int *pair, int **in_out__last_out)
29{
30 if (!i)
31 *in_out__last_out[1] = in_out__last_out[0][0];
32 else
33 *in_out__last_out[1] = pair[0];
34 if (i == (n - 1))
35 pair[1] = in_out__last_out[0][1];
36 else if (pipe(pair) == -1)
37 return ((int) err("pipe()", (void *) 1));
38 return (0);
39}
40
41static int _fork(int *i_n, int **pids_pair, int last_out, char ***str_arrs)
42{
43 int pid;
44
45 pid = fork();
46 if (pid == -1)
47 return ((int) err("fork()", 0));
48 if (!pid)
49 {
50 free(pids_pair[0]);
51 if (i_n[0] != (i_n[1] - 1) && pids_pair[1][0] != -1
52 && close(pids_pair[1][0]) == -1)
53 {
54 free(str_arrs[0]);
55 exit((int) err("close()", (void *) 1));
56 }
57 dispatch(str_arrs[0], str_arrs[1][i_n[0]], str_arrs[2],
58 (int []){last_out, pids_pair[1][1]});
59 }
60 return (pid);
61}
62
63static int _wait_all(int *pids, int n, int override)
64{
65 int status;
66
67 status = wait_all(pids, n, override);
68 free(pids);
69 return (status);
70}
71
85int dispatcher(int n, char ***str_arrs, int *in_out)
86{
87 int i;
88 int pair[2];
89 int last_out;
90 int *pids;
91
92 pids = malloc(sizeof(int) * n);
93 if (!pids)
94 return ((int) err("malloc()", (void *) 1));
95 i = 0;
96 while (i < n)
97 {
98 if (piping(i, n, pair, (int *[]){in_out, &last_out}))
99 break ;
100 pids[i] = _fork((int []){i, n}, (int *[]){pids, pair},
101 last_out, str_arrs);
102 if (last_out != -1 && close(last_out) == -1)
103 return ((int) err("close()", (void *) 1));
104 if (close(pair[1]) == -1)
105 return ((int) err("close()", (void *) 1));
106 if (!pids[i])
107 break ;
108 i++;
109 }
110 return (_wait_all(pids, i, !last_out));
111}
void dispatch(char **paths, char *args, char **envp, int *in_out)
Dispatch child process with argument string args, environment envp, and stdin / stdout in_out[0] / in...
Definition dispatch.c:67
int wait_all(int *pids, int n, int override)
Wait for first n processes in pids to change state and return the last process's exit code,...
Definition wait_all.c:31
int dispatcher(int n, char ***str_arrs, int *in_out)
Dispatch n child processes with argument strings str_arrs[1][i], environment pointer str_arrs[2],...
Definition dispatcher.c:85
void * err(const char *str, void *retval)
Wrapper around perror() that always returns retval.
Definition err.c:29