-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathshell.c
More file actions
65 lines (50 loc) · 1.45 KB
/
shell.c
File metadata and controls
65 lines (50 loc) · 1.45 KB
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
#include "parse.h"
#include "tokenize.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/wait.h>
#include <unistd.h>
size_t buffer_size = BUFFER_SIZE; // Capacity of the input string buffer
void run_command(TokenizerState *state) {
if (state->numTokens < 1) {
fprintf(stderr, "No command entered.\n");
return;
}
char *command = state->tokens[0].literal;
char *args[state->numTokens + 1];
args[state->numTokens] = NULL; // execvp expects null-terminated array
for (size_t i = 0; i < state->numTokens; i++) {
args[i] = state->tokens[i].literal;
}
pid_t pid = fork();
if (pid == 0) {
execvp(command, args);
perror("exec");
exit(EXIT_FAILURE);
} else if (pid > 0) {
wait(NULL);
} else {
perror("fork");
}
}
int main() {
TokenizerState tokenizerState = initializeTokenizerState(BUFFER_SIZE);
// If allocation failed, exit
if (tokenizerState.source == NULL) {
exit(EXIT_FAILURE);
}
// Error handling for reading from stdin
if (fgets(tokenizerState.source, buffer_size, stdin) == NULL) {
destroyTokenizerState(&tokenizerState);
exit(EXIT_FAILURE);
}
tokenizerState.source_length = strlen(tokenizerState.source);
scanner(&tokenizerState);
ParserState parserState =
initializeParserState(tokenizerState.numTokens, tokenizerState.tokens);
parse(&parserState);
run_command(&tokenizerState);
destroyTokenizerState(&tokenizerState);
exit(EXIT_SUCCESS);
}