changed buildsystem to automake
This commit is contained in:
@@ -6,20 +6,25 @@
|
||||
#include<readline/readline.h>
|
||||
#include<readline/history.h>
|
||||
#include<signal.h>
|
||||
#include<errno.h>
|
||||
#include"include/redirection.h"
|
||||
pid_t backgroundPids[64];
|
||||
pid_t backgroundPids[1024];
|
||||
int backgroundCount = 0;
|
||||
void handleSIGINT(int sig) {
|
||||
printf("\n");
|
||||
const char *msg = "\n";
|
||||
write(STDOUT_FILENO, msg, 1);
|
||||
}
|
||||
void handleSIGCHLD(int sig) {
|
||||
int pid = waitpid(-1, NULL, WNOHANG);
|
||||
for(int i = 0; i < backgroundCount; i++) {
|
||||
if(backgroundPids[i] == pid) {
|
||||
printf("\n[done] %d\n", pid);
|
||||
backgroundPids[i] = 0; // clear it
|
||||
int saved_errno = errno;
|
||||
pid_t pid;
|
||||
while ((pid = waitpid(-1, NULL, WNOHANG)) > 0) {
|
||||
for(int i = 0; i < 1024; i++) {
|
||||
if(backgroundPids[i] == pid) {
|
||||
backgroundPids[i] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
errno = saved_errno;
|
||||
}
|
||||
int detectBackground(char **args) {
|
||||
for (int i = 0; args[i] != NULL; i++) {
|
||||
@@ -30,42 +35,92 @@ int detectBackground(char **args) {
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
int seperatePipe(char **args) {
|
||||
for(int i = 0; args[i] != NULL; i++) {
|
||||
if (strcmp(args[i], "|") == 0) return i;
|
||||
void executePipeline(char **args, int background) {
|
||||
int num_cmds = 1;
|
||||
for (int i = 0; args[i] != NULL; i++) {
|
||||
if (strcmp(args[i], "|") == 0) num_cmds++;
|
||||
}
|
||||
return -1;
|
||||
|
||||
char ***cmds = malloc(num_cmds * sizeof(char **));
|
||||
int cmd_idx = 0;
|
||||
cmds[cmd_idx++] = args;
|
||||
for (int i = 0; args[i] != NULL; i++) {
|
||||
if (strcmp(args[i], "|") == 0) {
|
||||
args[i] = NULL;
|
||||
cmds[cmd_idx++] = args + i + 1;
|
||||
}
|
||||
}
|
||||
void executePipe(char **args, int pipeIndex) {
|
||||
args[pipeIndex] = NULL;
|
||||
char **cmd1 = args;
|
||||
char **cmd2 = args + pipeIndex + 1;
|
||||
int fd[2];
|
||||
pipe(fd);
|
||||
pid_t pid1 = fork();
|
||||
if (pid1 == 0) {
|
||||
dup2(fd[1], STDOUT_FILENO);
|
||||
close(fd[0]);
|
||||
close(fd[1]);
|
||||
signal(SIGINT, SIG_DFL);
|
||||
execvp(cmd1[0], cmd1);
|
||||
perror("tinysh");
|
||||
exit(1);
|
||||
|
||||
int (*pipes)[2] = malloc((num_cmds - 1) * sizeof(int[2]));
|
||||
for (int i = 0; i < num_cmds - 1; i++) {
|
||||
if (pipe(pipes[i]) < 0) {
|
||||
perror("pipe");
|
||||
free(cmds);
|
||||
free(pipes);
|
||||
return;
|
||||
}
|
||||
}
|
||||
pid_t pid2 = fork();
|
||||
if (pid2 == 0) {
|
||||
dup2(fd[0], STDIN_FILENO);
|
||||
close(fd[0]);
|
||||
close(fd[1]);
|
||||
signal(SIGINT, SIG_DFL);
|
||||
execvp(cmd2[0], cmd2);
|
||||
perror("tinysh");
|
||||
exit(1);
|
||||
|
||||
pid_t *pids = malloc(num_cmds * sizeof(pid_t));
|
||||
|
||||
for (int i = 0; i < num_cmds; i++) {
|
||||
pids[i] = fork();
|
||||
if (pids[i] == 0) {
|
||||
signal(SIGINT, SIG_DFL);
|
||||
|
||||
if (i > 0) {
|
||||
dup2(pipes[i - 1][0], STDIN_FILENO);
|
||||
}
|
||||
if (i < num_cmds - 1) {
|
||||
dup2(pipes[i][1], STDOUT_FILENO);
|
||||
}
|
||||
|
||||
for (int j = 0; j < num_cmds - 1; j++) {
|
||||
close(pipes[j][0]);
|
||||
close(pipes[j][1]);
|
||||
}
|
||||
|
||||
Redirection in, out;
|
||||
detectRedirections(cmds[i], &in, &out);
|
||||
|
||||
// Standard shell behavior: only first cmd gets <, only last gets >
|
||||
if (i != 0) in.type = REDIRECT_NONE;
|
||||
if (i != num_cmds - 1) out.type = REDIRECT_NONE;
|
||||
|
||||
if (applyRedirections(in, out) < 0) exit(1);
|
||||
|
||||
if (cmds[i][0] == NULL) exit(0);
|
||||
execvp(cmds[i][0], cmds[i]);
|
||||
perror("tinysh");
|
||||
exit(1);
|
||||
} else if (pids[i] < 0) {
|
||||
perror("fork");
|
||||
}
|
||||
}
|
||||
close(fd[0]);
|
||||
close(fd[1]);
|
||||
if (pid1 > 0) wait(NULL);
|
||||
if(pid2 > 0) wait(NULL);
|
||||
|
||||
for (int i = 0; i < num_cmds - 1; i++) {
|
||||
close(pipes[i][0]);
|
||||
close(pipes[i][1]);
|
||||
}
|
||||
|
||||
if (!background) {
|
||||
for (int i = 0; i < num_cmds; i++) {
|
||||
if (pids[i] > 0) waitpid(pids[i], NULL, 0);
|
||||
}
|
||||
} else {
|
||||
for (int i = 0; i < num_cmds; i++) {
|
||||
if (pids[i] > 0) {
|
||||
if (backgroundCount < 1024) {
|
||||
backgroundPids[backgroundCount++] = pids[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
printf("{background} pipeline started\n");
|
||||
}
|
||||
|
||||
free(cmds);
|
||||
free(pipes);
|
||||
free(pids);
|
||||
}
|
||||
int handleBuiltins(char **args) {
|
||||
if(strcmp(args[0], "cd") == 0) {
|
||||
@@ -77,10 +132,14 @@ int handleBuiltins(char **args) {
|
||||
} else { return 0;}
|
||||
}
|
||||
char **parse(char *line) {
|
||||
char **args= malloc(64 * sizeof(char *));
|
||||
char **args = malloc(256 * sizeof(char *));
|
||||
if (!args) {
|
||||
perror("malloc");
|
||||
return NULL;
|
||||
}
|
||||
int i = 0;
|
||||
char *token = strtok(line, " \t\n");
|
||||
while(token !=NULL) {
|
||||
while(token != NULL && i < 255) {
|
||||
args[i] = token;
|
||||
i++;
|
||||
token = strtok(NULL, " \t\n");
|
||||
@@ -111,35 +170,7 @@ if(strncmp(dir, home, strlen(home)) == 0) {
|
||||
if(parsed[0] == NULL) { free(parsed); free(line); continue; }
|
||||
if(handleBuiltins(parsed)) { free(line); free(parsed); continue; }
|
||||
int background = detectBackground(parsed);
|
||||
int pipeIndex = seperatePipe(parsed);
|
||||
if (pipeIndex != -1) {
|
||||
executePipe(parsed, pipeIndex);
|
||||
free(line);
|
||||
free(parsed);
|
||||
continue;
|
||||
}
|
||||
char *filename;
|
||||
int redirectionType = detectRedirect(parsed, &filename);
|
||||
if (redirectionType) {
|
||||
executeRedirect(parsed, redirectionType, filename);
|
||||
free(parsed);
|
||||
free(line);
|
||||
continue;
|
||||
}
|
||||
pid_t pid = fork();
|
||||
if(pid == 0) {
|
||||
signal(SIGINT, SIG_DFL);
|
||||
if(execvp(parsed[0], parsed) == -1 ) {
|
||||
perror("tinysh");
|
||||
exit(1);
|
||||
}
|
||||
} else if(pid > 0) {
|
||||
if(background) {
|
||||
printf("{background} %d \n", pid);
|
||||
backgroundPids[backgroundCount++] = pid;
|
||||
}
|
||||
else wait(NULL);
|
||||
}
|
||||
executePipeline(parsed, background);
|
||||
free(parsed);
|
||||
free(line);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user