Reputation: 131
I am working on a home made shell (very simple shell). I have decided to take the route of using execvp as my path is not a changeable element for my shell. I am running into an issue with coming up with the logic on how to fork and exec multiple processes at once.
My program should work with a command as such:
ls ; echo hello ; cat shell.c
Where each ";" indicates that we would like to run these processes at once simultaneously. So on our terminal output we should get a mix of these commands working at once.
To elaborate I'd like to explain how my program works:
A. Intake full command line into char array with a grab line function
B. Split the char array received from the last function by delimiters and place into an array of char arrays (pointer to pointer).
C. If one of the elements in our array of char arrays is ";" we can assume that multi commands are necessary. This is where I have trouble.
I have gotten as far as to know exactly how many processes I need to fork and such, but I cannot seem to wrap my head around how to pass all of these functions plus their arguments to the execvp function at once. Should I use a temp array? I know this shouldn't be this complicated but for some reason I cannot figure it out. I'm submitting my launch function below, which intakes an array of char arrays and executes accordingly based on my "multiCommand" variable which is set when multi commands are needed (by my split line function)
int launch(char **args){
pid_t pid;
int status;
int i = 0;
if(strcmp(args[0], "quit") == 0){
exit(EXIT_SUCCESS);
}
if(strcmp(args[0], ";") != 0){
printf("Essential Command Found : %s\n", args[0]);
numFork++;
}
if(multiCommand == 1){
//Handle Multicommands here
printf("Multi Commands Handling Here\n");
for(; i < elements - 1; i++){
if(strcmp(args[i], ";") == 0){
if((i + 1) < elements){
printf("Essential Command Found : %s\n", args[i + 1]);
numFork++;
}
}
}
//This is where I need to figure out what to do
printf("Fork: %d times\n", numFork);
}else if (multiCommand == 0){
pid = fork();
if(pid == 0){
execvp(args[0], args);
}else{
wait(&status);
}
}
multiCommand = 0;
elements = 0;
return 1;
}
Upvotes: 1
Views: 10403
Reputation: 698
The general idea would be to have a for loop over the different commands and fork each of them.
E.g.
for(int i = 0; i < commandCount; i++) {
int pid = fork();
if(pid == 0) { //this is the child (don't forget to check for errors and what-not)
execCommand(all, of, the, info, needed);
}
}
You can easily get the different commands using strtok()
.
Here's an example:
#include <string.h>
#include <stdio.h>
int main() {
char input[] = "abc;def;ghi";
char *token = strtok(input, ";");
while(token != NULL) {
printf("%s\n", token);
token = strtok(NULL, ";");
}
return 0;
}
Output:
abc
def
ghi
The final function will look something like this:
char *token = strtok(input, ";");
while(token != NULL) {
int pid = fork();
if(pid == 0) {
//token is one command
//parse the different parts here
execCommand(args, to, exec);
}
token = strtok(NULL, ";");
}
Upvotes: 6