Форк и exec несколько процессов одновременно

Я работаю над самодельной оболочкой (очень простая оболочка). Я решил пойти по пути использования execvp, поскольку мой путь не является изменяемым элементом для моей оболочки. Я сталкиваюсь с проблемой с придуманием логики о том, как разветвлять и выполнять несколько процессов одновременно.

Моя программа должна работать с командой как таковой:

ls ; echo hello ; cat shell.c

Где каждый ";" указывает на то, что мы хотели бы запустить эти процессы одновременно. Таким образом, на выходе нашего терминала мы должны получить смесь этих команд, работающих одновременно.

Чтобы уточнить, я хотел бы объяснить, как работает моя программа:

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.

Я дошел до того, что точно знаю, сколько процессов мне нужно разветвить и тому подобное, но я не могу понять, как передать все эти функции плюс их аргументы в функцию execvp одновременно. Должен ли я использовать временный массив? Я знаю, что это не должно быть таким сложным, но по какой-то причине я не могу понять это. Ниже я отправляю свою функцию запуска, которая принимает массив массивов символов и исполняется соответствующим образом на основе моей переменной "multiCommand", которая устанавливается, когда требуются несколько команд (моей функцией разделения строки)

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;
}

1 ответ

Решение

Общая идея заключается в том, чтобы иметь цикл for для разных команд и разветвлять каждую из них.

Например

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);
    }
}

Вы можете легко получить различные команды, используя strtok(),
Вот пример:

#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;
}

Выход:

abc
def
ghi

Последняя функция будет выглядеть примерно так:

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, ";");
}
Другие вопросы по тегам