Проблема с программированием внутренних команд в интерпретаторе оболочки (сделано мной) - PullRequest
1 голос
/ 29 марта 2019

У меня был проект операционных систем, в котором мне приходилось программировать интерпретатор команд в оболочке на C. Я сделал это большую часть, код, который я уже реализовал, позволяет выполнять простые команды, такие как ls,или команды в фоновом режиме и / или с трубами.

Но теперь мне также нужно запрограммировать команду интерна (новую).Его имя будет myTime, и оно должно позволить вам измерить время, которое требуется процессу для выполнения его функции.Например, если вы выполняете команду sleep 10 в оболочке Linux, процесс должен находиться в режиме ожидания не менее указанного времени.Цель команды интерна myTime - измерить это время.

ВАЖНО : В коде я помогал учителям, которые позволяют мне с помощью функции под названием receive_orden получить введенную команду (например: вызов argvv [i] [0]для введенной команды i), аргументы (argvv [i] [1], первый аргумент), и если он находится или нет в фоновом режиме (bg = 0/1) Кроме того, функция pid_t fork() создает новый процесс илиновый дочерний процесс и возвращает 0, если это дочерний процесс или pid, если он родительский.

У меня есть дополнительный код для компиляции и т. д., если он вам нужен или что-то не понятно, скажите мне.Спасибо!

Я искал в библиотеке sys / time.h и в функции gettimeofday.Но я не смог показать сообщение, которое мне требуется в моем проекте: «Затрачено время:% f secs. \ N» Поскольку эта команда интерна должна измерять время, необходимое для выполнения процесса, я былсказал, что я должен выполнить fork () и exec () и измерить время после того, как дочерний процесс выполнил свою функцию.
Он должен отображаться так:

msh> mytime sleep 5
Time spent: 5.001719 secs
msh>
extern int obtain_order();      /* See parser.y for description */
int main(void)
{
    char ***argvv;
    //int command_counter;
    int num_commands;
    //int args_counter; 
    char *filev[3];
    int bg;
    int ret;

    setenv("Acc","0",1);
    setbuf(stdout, NULL);           /* Unbuffered */
    setbuf(stdin, NULL);

    while (1) 
    {
        fprintf(stderr, "%s", "msh> "); /* Prompt */
        ret = obtain_order(&argvv, filev, &bg);
        if (ret == 0) break;        /* EOF */
        if (ret == -1) continue;    /* Syntax error */
        num_commands = ret - 1;     /* Line */
        if (num_commands == 0) continue;    /* Empty line */

        if(num_commands==1){
            //Implementación propia para salir del mini-shell
            if(strcmp(argvv[0][0], "exit") == 0){
              exit(0);
            }

            if(strcmp(argvv[0][0],"myTime")==0){ 

//HERE IS WHERE I HAVE TO IMPLEMENT THE INTERN COMMAND MYTIME

            }else{  //For all other commands ls, etc... (with pipes (max 3)and background)
                int pid;
                int estado;

                pid = fork();

                switch(pid) {
                    case -1: /* error */
                        fprintf(stderr, "%s","Error en el fork del mandato simple\n");
                        return (-1);

                    case 0: /* hijo */
                        if (filev[0] != NULL) {
                            close(STDIN_FILENO);
                            open(filev[0],O_RDONLY);
                        }

                        if (filev[1] != NULL) {
                            close(STDOUT_FILENO);
                            open(filev[1],O_CREAT|O_WRONLY,0666);
                        }

                        if (filev[2] != NULL) {
                            close(STDERR_FILENO);
                            open(filev[2],O_CREAT|O_WRONLY,0666);
                        }

                        execvp(argvv[0][0], argvv[0]);
                        fprintf(stderr, "%s","Error en el execvp del mandato simple\n");
                        return(-1);

                    default: /* padre */
                        if(!bg){
                            while (wait(&estado) != pid);
                        }else printf("%d\n",pid);
                } //fin switch (1 mandato)
            } //fin if (si es comando interno o no) 

        }else if(num_commands==2){
            int pid;
            int estado;
            int fd[2];

            pipe(fd);
            pid = fork();

            switch(pid) {
                case -1: /* error */
                    fprintf(stderr, "%s","Error en el fork del primer mandato\n");
                    return (-1);

                case 0: /* hijo1 */
                    close(STDOUT_FILENO);
                    dup(fd[1]);
                    close(fd[0]);
                    close(fd[1]);

                    if (filev[0] != NULL) {
                        close(STDIN_FILENO);
                        open(filev[0],O_RDONLY);
                    }

                    if (filev[2] != NULL) {
                        close(STDERR_FILENO);
                        open(filev[2],O_CREAT|O_WRONLY,0666);
                    }

                    execvp(argvv[0][0], argvv[0]);
                    fprintf(stderr, "%s","Error en el execvp del primer mandato\n");
                    return(-1);

                default: /* padre */
                    pid = fork();
                    switch(pid) {
                        case -1: /* error */
                            fprintf(stderr, "%s","Error en el fork del segundo mandato\n");
                            return (-1);

                        case 0: /* hijo 2*/
                            close(STDIN_FILENO);
                            dup(fd[0]);
                            close(fd[0]);
                            close(fd[1]);

                            if (filev[1] != NULL) {
                                close(STDOUT_FILENO);

                                open(filev[1],O_CREAT|O_WRONLY,0666);
                            }

                            if (filev[2] != NULL) {
                                close(STDERR_FILENO);
                                open(filev[2],O_CREAT|O_WRONLY,0666);
                            }

                            execvp(argvv[1][0], argvv[1]);
                            fprintf(stderr, "%s","Error en el execvp del segundo mandato\n");
                            return(-1);

                        default: /* padre */
                            close(fd[0]);
                            close(fd[1]);

                            if(!bg){
                                while (wait(&estado) != pid);
                            }else printf("%d\n",pid);
                    } //fin switch2 (2 mandatos)    
            } //fin switch1 (2 mandatso)
        }else if(num_commands==3){
            int pid;
            int estado;
            int fd[2], fd2[2];

            pipe(fd);
            pid = fork();

            switch(pid) {
                case -1: /* error */
                    fprintf(stderr, "%s","Error en el fork del primer mandato\n");
                    return (-1);

                case 0: /* hijo1 */
                    close(STDOUT_FILENO);
                    dup(fd[1]);
                    close(fd[0]);
                    close(fd[1]);

                    if (filev[0] != NULL) {
                        close(STDIN_FILENO);
                        open(filev[0],O_RDONLY);
                    }

                    if (filev[2] != NULL) {
                        close(STDERR_FILENO);
                        open(filev[2],O_CREAT|O_WRONLY,0666);
                    }

                    execvp(argvv[0][0], argvv[0]);
                    fprintf(stderr, "%s","Error en el execvp del primer mandato\n");
                    return(-1);

                default: /* padre */
                    pipe(fd2);
                    pid = fork();

                    switch(pid) {
                        case -1: /* error */
                            fprintf(stderr, "%s","Error en el fork del segundo mandato\n");
                            return (-1);

                        case 0: /* hijo 2*/
                            close(STDIN_FILENO);
                            dup(fd[0]);
                            close(STDOUT_FILENO);
                            dup(fd2[1]);
                            close(fd[0]);
                            close(fd[1]);
                            close(fd2[0]);
                            close(fd2[1]);

                            if (filev[2] != NULL) {
                                close(STDERR_FILENO);
                                open(filev[2],O_CREAT|O_WRONLY,0666);
                            }

                            execvp(argvv[1][0], argvv[1]);
                            fprintf(stderr, "%s","Error en el execvp del segundo mandato\n");
                            return(-1);

                        default: /* padre */
                            close(fd[0]);
                            close(fd[1]);
                            pid = fork();

                            switch(pid) {
                                case -1: /* error */
                                    fprintf(stderr, "%s","Error en el fork del tercer mandato\n");
                                    return (-1);

                                case 0: /* hijo 3*/
                                    close(STDIN_FILENO);
                                    dup(fd2[0]);
                                    close(fd2[0]);
                                    close(fd2[1]);

                                    if (filev[1] != NULL) {
                                    close(STDOUT_FILENO);

                            open(filev[1],O_CREAT|O_WRONLY,0666);
                                    } 

                                    if (filev[2] != NULL) {
                                        close(STDERR_FILENO);
                                        open(filev[2],O_CREAT|O_WRONLY,0666);
                                    }

                                    execvp(argvv[2][0], argvv[2]);
                                    fprintf(stderr, "%s","Error en el execvp del tercer mandato\n");
                                    return(-1);

                                default: /* padre */
                                    close(fd2[0]);
                                    close(fd2[1]);

                                    if(!bg){
                                        while (wait(&estado) != pid);
                                    }else printf("%d\n",pid);
                            } //fin switch 3 (3 mandatos)

                    } //fin switch2 (3 mandatos)

            } //fin switch1 (tres mandatos)
        } //fin if (número de mandatos)

    } //fin while 

    return 0;

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