Помогите создать простую оболочку C - PullRequest
2 голосов
/ 26 октября 2010

Я новичок в C и пытаюсь создать простую оболочку C, которая позволит пользователю выполнять различные функции, такие как chdir, cd, exit, mkdir.

Я разместил свой код ниже.Может кто-нибудь просмотреть это и увидеть, что я делаю не так?Я не уверен, правильно ли я использую fork и execcv.Спасибо!

include stdio.h
include stdlib.h
include unistd.h
include <string.h>
include sys/types.h

main() {
    //char *user;

    //if ((user = getlogin()) == NULL)
    //    perror("__getlogin1() error");
    //else printf("__getlogin1() returned %s\n", user);
    int j, status;
    int pid, c_pid;
    int i = 0;
    char *tmp, **ap;
    char instring[80]; // store one line of input
    char *argv[10]; // store parameters in the format for execv()

    promptstart:

    printf("Please enter a commcand:\n");

    // read a char at a time and put it in instring[]
    // put a '\0' at the end
    instring[i] = getc(stdin); // stdin is the keyboard
    while (instring[i] != '\n') {
        i++;
        instring[i] = getc(stdin);
    }
    instring[i] = '\0'; // replace '\n' with '\0'

    tmp = instring;
    i = 0;
    argv[i] = strsep(&tmp, " \t"); // put first word int argv[0]
    while ((i < 10) && (argv[i] != '\0')) {
        i++;
        argv[i] = strsep(&tmp, " \t");
    }

    // print out the command and options.
    i = 0;
    while (argv[i] != '\0') {
        printf("your entered: %s\n", argv[i++]);
    }

    //PLACE ERROR HERE

    if ((c_pid = fork()) == 0) {
        for (j = 0; j < 10; j++)
            printf("child (%d) prints %d\n", getpid(), j);
        exit(0);
    } else if (c_pid > 0) {
        c_pid = wait(&status);
        printf("child %d exited with status %d\n", c_pid, status);
    } else {
        execvp(argv[0], argv);

    }
    goto promptstart;
}

Ответы [ 2 ]

3 голосов
/ 26 октября 2010

По крайней мере, IMO, вы вкладываете слишком много в main.Я бы начал с чего-то вроде:

int main() { 
    char input[128];

    do { 
        fgets(stdin, input, sizeof(input));
        dispatch(input);
    } while (strcmp(input, "exit"));
    return 0;
}

Тогда dispatch будет искать внутренние команды и делать exec только когда / если ему дана команда, которую он не распознает.Чтобы было проще начать, вы можете рассмотреть возможность использования popen для выполнения внешних команд и оставить переключение на «raw» fork / exec на потом, когда ограничения popen начнут вызывать у вас проблемы.

0 голосов
/ 26 октября 2010

Для встроенных команд оболочки (man bash) вы, вероятно, не хотите выполнять fork / exec. Я бы сохранил fork / exec для запуска программ, которые находятся в вашем PATH (переменная окружения, которой должна управлять ваша оболочка). Сама оболочка должна взаимодействовать с файловой системой с помощью таких команд, как chdir (man 2 chdir).

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...