Implementar próprio shell [closed]

1

Estou tentando implementar meu próprio shell. Eu tenho algumas perguntas sobre meu código e sobre tarefas a serem resolvidas. Abaixo, apresento meu código e minhas perguntas anteriores:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
#include <string.h>
#include <sys/wait.h>
#include <sys/types.h>
#include <ctype.h>
#include <errno.h>
#include <sys/stat.h>
#include <fcntl.h>

void parse(char *line, char **argv, char **argv2)
{
    while (*line != '
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
#include <string.h>
#include <sys/wait.h>
#include <sys/types.h>
#include <ctype.h>
#include <errno.h>
#include <sys/stat.h>
#include <fcntl.h>

void parse(char *line, char **argv, char **argv2)
{
    while (*line != '%pre%')
    {
        while (*line == ' ' || *line == '\t' || *line == '\n')
        {
            *line++ = '%pre%';
        }   

        if(*line == '>' && *(line+1) == '>')
        {
            while (*line != '%pre%' && *line != ' ' &&  *line != '\t' && *line != '\n')
            {
                line++;
            }           
            while (*line == ' ' || *line == '\t' || *line == '\n')
            {           
                *line++ = '%pre%';
            }
            *argv2 = line;
            break;
        }

        if(*line == '&')
        {
            break;
        }

        *argv++ = line;

        while (*line != '%pre%' && *line != ' ' &&  *line != '\t' && *line != '\n')
        {
            line++;
        }   
    }
    *argv = '%pre%';
}

void execute(char **argv, int option)
{
    pid_t pid;
    int status;

    if ((pid = fork()) < 0)
    {
        printf("*** ERROR ***\n");
        exit(1);
    }
    else if (pid == 0)
    {
        if (execvp(*argv, argv) < 0)
        {
            printf("*** ERROR ***\n");
            exit(1);
        }
    }
    else if(option == 1)
    {
        while (wait(&status) != pid);
    }
}

void execute2(char *command, char **argv, char **argv2)
{
    pid_t pid;
    int status;

    if ((pid = fork()) < 0)
    {
        printf("*** ERROR ***\n");
        exit(1);
    }
    else if (pid == 0)
    {
        //close(1);
        parse(command, argv, argv2);
        int output = open(*argv2, O_APPEND | O_WRONLY);
        dup2(output,1);
        if (strcmp(argv[0], "exit") == 0)
            exit(0);
        if (execvp(*argv, argv) < 0)
        {
            printf("*** ERROR ***\n");
            exit(1);
        }
        close(output);
    }
    else
    {
        while (wait(&status) != pid);
    }
}

int specialChar(char *argv)
{
    int i=0;
    while(argv[i]!='%pre%')
    {
        if(argv[i]=='>' && argv[i+1]=='>')
            return 1;           
        else if(argv[i]=='&')
            return 2;           
        else if(argv[i]=='|')
            return 3;           
        i++;
    }
}

void  main()
{
    char command[20];
    char *argv[64];
    char *argv2[1];
    char **history = (char**)malloc(20*sizeof(char*));
    int counterHistory1=-1;
    int counterHistory2=0;
    int i;

    for(counterHistory2 = 0; counterHistory2<20; counterHistory2++)
    {
        history[counterHistory2]=(char*)malloc(100*sizeof(char));
    }

    FILE *file;
    file=fopen("history", "w");
    if(!file)
        printf("ERROR");

    while (1)
    {
        printf("Shell -> ");
        gets(command);

        counterHistory1++;
        strcpy(history[counterHistory1],command);
        fopen("history", "w");
        if(counterHistory1<20)
            for(i=0; i<=counterHistory1; i++)
            {
                fprintf(file,"%s\n",history[i]);
            }
        else
            for(i=counterHistory1-20; i<counterHistory1; i++)
            {
                fprintf(file,"%s\n",history[i]);
            }

        fflush(file);
        printf("\n");

        switch(specialChar(command))
        {
            case 1:
                //close(1);
                execute2(command,argv,argv2);
            break;

            case 2:                                //running program in background
                parse(command, argv, argv2);
                if (strcmp(argv[0], "exit") == 0)
                    exit(0);
                execute(argv,0);
            break;

            case 3:

            break;

            default:
                parse(command, argv, argv2);
                if (strcmp(argv[0], "exit") == 0)
                    exit(0);
                execute(argv,1);
            break;
        }
        fclose(file);
        }
}
') { while (*line == ' ' || *line == '\t' || *line == '\n') { *line++ = '%pre%'; } if(*line == '>' && *(line+1) == '>') { while (*line != '%pre%' && *line != ' ' && *line != '\t' && *line != '\n') { line++; } while (*line == ' ' || *line == '\t' || *line == '\n') { *line++ = '%pre%'; } *argv2 = line; break; } if(*line == '&') { break; } *argv++ = line; while (*line != '%pre%' && *line != ' ' && *line != '\t' && *line != '\n') { line++; } } *argv = '%pre%'; } void execute(char **argv, int option) { pid_t pid; int status; if ((pid = fork()) < 0) { printf("*** ERROR ***\n"); exit(1); } else if (pid == 0) { if (execvp(*argv, argv) < 0) { printf("*** ERROR ***\n"); exit(1); } } else if(option == 1) { while (wait(&status) != pid); } } void execute2(char *command, char **argv, char **argv2) { pid_t pid; int status; if ((pid = fork()) < 0) { printf("*** ERROR ***\n"); exit(1); } else if (pid == 0) { //close(1); parse(command, argv, argv2); int output = open(*argv2, O_APPEND | O_WRONLY); dup2(output,1); if (strcmp(argv[0], "exit") == 0) exit(0); if (execvp(*argv, argv) < 0) { printf("*** ERROR ***\n"); exit(1); } close(output); } else { while (wait(&status) != pid); } } int specialChar(char *argv) { int i=0; while(argv[i]!='%pre%') { if(argv[i]=='>' && argv[i+1]=='>') return 1; else if(argv[i]=='&') return 2; else if(argv[i]=='|') return 3; i++; } } void main() { char command[20]; char *argv[64]; char *argv2[1]; char **history = (char**)malloc(20*sizeof(char*)); int counterHistory1=-1; int counterHistory2=0; int i; for(counterHistory2 = 0; counterHistory2<20; counterHistory2++) { history[counterHistory2]=(char*)malloc(100*sizeof(char)); } FILE *file; file=fopen("history", "w"); if(!file) printf("ERROR"); while (1) { printf("Shell -> "); gets(command); counterHistory1++; strcpy(history[counterHistory1],command); fopen("history", "w"); if(counterHistory1<20) for(i=0; i<=counterHistory1; i++) { fprintf(file,"%s\n",history[i]); } else for(i=counterHistory1-20; i<counterHistory1; i++) { fprintf(file,"%s\n",history[i]); } fflush(file); printf("\n"); switch(specialChar(command)) { case 1: //close(1); execute2(command,argv,argv2); break; case 2: //running program in background parse(command, argv, argv2); if (strcmp(argv[0], "exit") == 0) exit(0); execute(argv,0); break; case 3: break; default: parse(command, argv, argv2); if (strcmp(argv[0], "exit") == 0) exit(0); execute(argv,1); break; } fclose(file); } }
  1. Quando o último sinal do usuário é '&', preciso executar meu programa em segundo plano. Eu li que posso fazer isso se não ligar para esperar. Eu fiz isso bem ou eu deveria mudar alguma coisa?
  2. No meu shell eu deveria criar pipes de qualquer tamanho com o sinal | . Não tenho ideia de como resolver esse problema.
por ByQ 22.04.2017 / 13:22

0 respostas

Tags