1#include "../include/pipeline.h"
8#define pipe(fds) _pipe(fds, 4096, _O_BINARY)
9#define close(fd) _close(fd)
10#define dup2(oldfd, newfd) _dup2(oldfd, newfd)
40 int prev_pipe_read_end = -1;
43 PROCESS_INFORMATION pi = {0};
44 HANDLE* proc_handles = NULL;
46 DWORD command_count = 0;
50 while (count_node != NULL) {
52 count_node = count_node->next;
55 proc_handles = (HANDLE*)calloc(command_count,
sizeof(HANDLE));
61 while (current != NULL) {
63 if (current->next != NULL) {
64 if (pipe(pipefd) < 0) {
71 char command[1024] =
"";
73 while (current->args[i] != NULL) {
75 if (strchr(current->args[i],
' ') != NULL) {
76 strcat(command,
"\"");
77 strcat(command, current->args[i]);
78 strcat(command,
"\" ");
80 strcat(command, current->args[i]);
87 ZeroMemory(&si,
sizeof(si));
89 si.dwFlags = STARTF_USESTDHANDLES;
92 si.hStdInput = GetStdHandle(STD_INPUT_HANDLE);
93 si.hStdOutput = GetStdHandle(STD_OUTPUT_HANDLE);
94 si.hStdError = GetStdHandle(STD_ERROR_HANDLE);
97 if (prev_pipe_read_end != -1) {
98 si.hStdInput = (HANDLE)_get_osfhandle(prev_pipe_read_end);
102 if (current->next != NULL) {
103 si.hStdOutput = (HANDLE)_get_osfhandle(pipefd[1]);
104 }
else if (output_fd != -1) {
105 si.hStdOutput = (HANDLE)_get_osfhandle(output_fd);
109 ZeroMemory(&pi,
sizeof(pi));
110 if (!CreateProcess(NULL,
121 fprintf(stderr,
"CreateProcess failed: %lu\n", GetLastError());
126 proc_handles[proc_count++] = pi.hProcess;
129 CloseHandle(pi.hThread);
132 if (current->next != NULL) {
137 if (prev_pipe_read_end != -1) {
138 close(prev_pipe_read_end);
142 prev_pipe_read_end = pipefd[0];
144 current = current->next;
148 WaitForMultipleObjects(proc_count, proc_handles, TRUE, INFINITE);
151 for (
size_t i = 0; i < proc_count; i++) {
152 CloseHandle(proc_handles[i]);
167 int prev_pipe_read_end = -1;
170 while (current != NULL) {
172 if (current->next != NULL) {
173 if (pipe(pipefd) < 0) {
188 if (prev_pipe_read_end != -1) {
189 dup2(prev_pipe_read_end, STDIN_FILENO);
190 close(prev_pipe_read_end);
194 if (current->next != NULL) {
195 dup2(pipefd[1], STDOUT_FILENO);
197 }
else if (output_fd != -1) {
199 dup2(output_fd, STDOUT_FILENO);
204 execvp(current->args[0], current->args);
209 if (current->next != NULL) {
214 if (prev_pipe_read_end != -1) {
215 close(prev_pipe_read_end);
219 prev_pipe_read_end = pipefd[0];
222 current = current->next;
226 while (wait(NULL) > 0);
237 while (current != NULL) {
251 if (!commands)
return;
254 while (commands[i]) {
255 if (commands[i + 1] != NULL) {
256 commands[i]->next = commands[i + 1];
258 commands[i]->next = NULL;
267 char* args1[] = {
"ls",
"-l", NULL};
268 char* args2[] = {
"grep",
"-E",
".c$", NULL};
269 char* args3[] = {
"wc",
"-l", NULL};
276 CommandNode* commands[] = {cmd1, cmd2, cmd3, NULL};
283 int output_fd = _open(
"output.txt", _O_WRONLY | _O_CREAT | _O_TRUNC, _S_IWRITE);
286 int output_fd = open(
"output.txt", O_WRONLY | O_CREAT | O_TRUNC, 0644);
void build_pipeline(CommandNode **commands)
Build the pipeline using a NULL-terminated array of CommandNode pointers.
void free_pipeline(CommandNode *head)
Free the linked list of commands.
CommandNode * create_command_node(char **args)
Create a new CommandNode.
void execute_pipeline(CommandNode *head, int output_fd)
Execute a pipeline of commands.
Structure representing a command in a pipeline.