52 for (
uint64_t i = 0; i < tokenAmount; i++)
67 const char** currentArgv =
malloc(
sizeof(
char*) * (tokenAmount + 1));
68 if (currentArgv ==
NULL)
75 for (
uint64_t i = 0; i < tokenAmount; i++)
77 if (
strcmp(tokens[i],
"|") == 0)
81 printf(
"error: empty command in pipeline\n");
87 goto token_parse_error;
90 currentArgv[currentArg] =
NULL;
93 cmd->
argv = currentArgv;
94 cmd->
argc = currentArg;
97 if (
open2(
"/dev/pipe/new", pipe) ==
ERR)
100 goto token_parse_error;
108 currentArgv =
malloc(
sizeof(
char*) * (tokenAmount + 1));
109 if (currentArgv ==
NULL)
111 printf(
"error: out of memory\n");
112 goto token_parse_error;
115 cmd_t* nextCmd = &pipeline->
cmds[currentCmd];
119 else if (
strcmp(tokens[i],
"<") == 0)
121 if (i + 1 >= tokenAmount)
123 printf(
"error: missing filename after <\n");
124 goto token_parse_error;
131 goto token_parse_error;
134 cmd_t* cmd = &pipeline->
cmds[currentCmd];
144 else if (
strcmp(tokens[i],
">") == 0)
146 if (i + 1 >= tokenAmount)
148 printf(
"error: missing filename after >\n");
149 goto token_parse_error;
156 goto token_parse_error;
159 cmd_t* cmd = &pipeline->
cmds[currentCmd];
169 else if (
strcmp(tokens[i],
"2>") == 0)
171 if (i + 1 >= tokenAmount)
173 printf(
"error: missing filename after 2>\n");
174 goto token_parse_error;
181 goto token_parse_error;
184 cmd_t* cmd = &pipeline->
cmds[currentCmd];
196 currentArgv[currentArg] =
strdup(tokens[i]);
197 if (currentArgv[currentArg] ==
NULL)
199 printf(
"error: out of memory\n");
200 goto token_parse_error;
208 currentArgv[currentArg] =
NULL;
209 pipeline->
cmds[currentCmd].
argv = currentArgv;
210 pipeline->
cmds[currentCmd].
argc = currentArg;
216 if (pipeline->
amount > 0 && currentCmd > 0)
218 printf(
"error: pipeline ends with empty command\n");
219 cmd_t* emptyCmd = &pipeline->
cmds[currentCmd];
225 goto token_parse_error_no_current_argv;
229 pipeline->
amount = currentCmd;
234 if (currentArgv !=
NULL)
236 for (
uint64_t k = 0; k < currentArg; k++)
238 free((
void*)currentArgv[k]);
243token_parse_error_no_current_argv:
244 for (
uint64_t j = 0; j < currentCmd; j++)
314 if (originalStdin ==
ERR)
319 if (originalStdout ==
ERR)
321 close(originalStdin);
325 if (originalStderr ==
ERR)
327 close(originalStdin);
328 close(originalStdout);
335 close(originalStdin);
336 close(originalStdout);
337 close(originalStderr);
348 close(originalStdin);
349 close(originalStdout);
350 close(originalStderr);
365 const char** argv = cmd->
argv;
378 else if (argv[0][0] ==
'.' && argv[0][1] ==
'/')
387 printf(
"error: %s not found\n", argv[0]);
393 bool isFound =
false;
407 const char* temp = argv[0];
444 if (pipeline->
amount == 0)
483 pids[fdCount - 1] = pid;
485 fds[fdCount].
fd =
openf(
"/proc/%d/wait", pid);
486 if (fds[fdCount].fd ==
ERR)
512 for (
uint64_t i = 0; i < fdCount; i++)
516 printf(
"shell: poll error on fd %d\n", fds[i].fd);
522 if (fds[0].revents &
POLLIN)
526 if (bytesRead ==
ERR)
533 for (
uint64_t i = 0; i < bytesRead; i++)
541 for (
uint64_t j = 1; j < fdCount; j++)
543 fd_t note =
openf(
"/proc/%d/note", pids[j - 1]);
564 bool allExited =
true;
565 for (
uint64_t i = 1; i < fdCount; i++)
567 if (fds[i].revents &
POLLIN)
571 if (readCount ==
ERR)
573 printf(
"shell: failed to read process %d exit status (%s)\n", pids[i - 1],
strerror(
errno));
583 memmove(&pids[i - 1], &pids[i],
sizeof(
pid_t) * (fdCount - i - 1));
599 for (
uint64_t i = 1; i < fdCount; i++)
#define MAX_PATH
Maximum length of filepaths.
uint64_t builtin_execute(uint64_t argc, const char **argv)
bool builtin_exists(const char *name)
#define errno
Error number variable.
const char ** argsplit(const char *str, uint64_t maxLen, uint64_t *count)
Standardized argument parsing function.
fd_t dup2(fd_t oldFd, fd_t newFd)
System call for duplicating file descriptors, with a destination.
uint64_t stat(const char *path, stat_t *stat)
System call for retrieving info about a file or directory.
uint64_t writef(fd_t fd, const char *_RESTRICT format,...)
Wrapper for writing a formatted string to a file.
fd_t open(const char *path)
System call for opening files.
#define PIPE_READ
Pipe read end.
uint64_t close(fd_t fd)
System call for closing files.
fd_t dup(fd_t oldFd)
System call for duplicating file descriptors.
uint64_t poll(pollfd_t *fds, uint64_t amount, clock_t timeout)
System call for polling files.
fd_t openf(const char *_RESTRICT format,...)
Wrapper for opening files with a formatted path.
#define PIPE_WRITE
Pipe write end.
uint64_t read(fd_t fd, void *buffer, uint64_t count)
System call for reading from files.
uint64_t open2(const char *path, fd_t fd[2])
System call for opening 2 file descriptors from one file.
uint64_t write(fd_t fd, const void *buffer, uint64_t count)
System call for writing to files.
@ INODE_DIR
Is a directory.
@ POLLIN
File descriptor is ready to read.
@ POLLERR
File descriptor caused an error.
pid_t spawn(const char **argv, const spawn_fd_t *fds, const char *cwd, spawn_attr_t *attr)
System call for creating child processes.
#define SPAWN_FD_END
Spawn fds termination constant.
#define NULL
Pointer error value.
#define ERR
Integer error value.
__UINT64_TYPE__ fd_t
A file descriptor.
__UINT64_TYPE__ pid_t
Process Identifier.
EFI_PHYSICAL_ADDRESS buffer
static pid_t pipeline_execute_cmd(cmd_t *cmd)
uint64_t pipeline_execute(pipeline_t *pipeline)
void pipeline_deinit(pipeline_t *pipeline)
static uint64_t pipeline_execute_builtin(cmd_t *cmd)
static const char * lookupDirs[]
uint64_t pipeline_init(pipeline_t *pipeline, const char *cmdline)
_PUBLIC int printf(const char *_RESTRICT format,...)
_PUBLIC int fprintf(FILE *_RESTRICT stream, const char *_RESTRICT format,...)
_PUBLIC int sprintf(char *_RESTRICT s, const char *_RESTRICT format,...)
_PUBLIC void * calloc(size_t nmemb, size_t size)
_PUBLIC void * malloc(size_t size)
_PUBLIC void free(void *ptr)
_PUBLIC char * strerror(int errnum)
_PUBLIC void * memmove(void *_RESTRICT s1, const void *_RESTRICT s2, size_t n)
char * strdup(const char *src)
_PUBLIC size_t strlen(const char *s)
_PUBLIC int strcmp(const char *s1, const char *s2)
Poll file descriptor structure.
poll_events_t events
The events to wait for.
fd_t fd
The file descriptor to poll.
Stucture used to duplicate fds in spawn().
fd_t child
The destination file descriptor in the child.