/minishell

The real minishell

Primary LanguageC

MiauShell 😸

Esse é o minishell feito por pessoas que amam gatos

Miau Team: Daniela | dmonteir e Luís | lamorim

Índice

  1. Entendendo projeto
  2. Algumas funções autorizadas
  3. Clone e execute o prejeto

Entendendo Projeto

No projeto minishell temos que replicar um bash com algumas funcionalidades builtins.

🐐 Bash: "é um interpretador de comandos, um entre os diversos tradutores entre o usuário e o sistema operacional conhecidos como shell. Acrônimo para "Bourne-Again SHell", o Bash é uma evolução retro-compatível muito mais interativa do Bourne Shell (sh). " Fonte: Wikipedia

🐚 Shell: "Em computação, um shell (em português, casca ou concha) é uma interface de usuário para acessar os serviços de um sistema operacional. Em geral, shells dos sistemas operacionais usam uma interface de linha de comando (CLI) ou uma interface gráfica de usuário (GUI), dependendo da função e operação particular de um computador." Fonte: Wikipedia

Funções CORE do projeto

  • readline()
  • execve()
  • fork()
  • pipe()
  • dup() e dup2()
  • signal()

Estratégias utilizadas

Nesse projeto tomamos algumas decisões de organização e métodos para o desenvolvimento do pojeto.

Utilizamos como refêrencia de organização do projeto a arquitetura pipe-and-filter

Também utilizamos o design patthern facade como inspiração para desenvolver a função core da nossa aplicação.

Além disso, utilizamos o TDD como método de desenvolvimento da parte de tokenização do nosso projeto.

Estrutura do projeto

Para organizar o fluxo de informação e as tratátivas que fizemos durante a execução do projeto exploramos mais de uma estrutura de dados e modularizamos nossa aplicação em staps muito bem definidos associados a estrutura de pastas que utilizamos.

Estruturas de dados utilizadas no projeto

As principais estrutura de dados que utilizamos foram Array, double Linked-list e Hash-table (onde utilizamos uma linked-list para lidar com os conflitos de key)

Estrutura de pastas

Nessa sessão vamos analizar a estrutúra do diretório src/

  • hash_table/: onde estão os arquivos responsáveis por implementar a hash_table;
  • builtins/: onde estão os arquivos de implementação das builtins do minishell
  • tokens/: onde estão as funções que fazem o fluxo de tratativa do input do usuário;
  • exec/: onde estão as funções de execução da pipe line.

Organizando o fluxo de informação

Estamos tratando a informação passada pelo usuário seguindo a arquiterura do pipe-and-filter, primeiro avaliamos se o input é uma string ou se é algum sinal, caso seja uma string continuamos o fluxo de informação, caso não, tratamos o sinal.

Algumas funções autorizadas

Função resumo argumentos retorno
rl_clear_history Clear the history list by deleting all of the entries void void
rl_on_new_line Tell the update function that we have moved onto a new line void int
rl_replace_line Replace the contents of rl_line_buffer with text cosnt char *text new content line. int clear_undo if clear_undo id non-zero, the undo list associated with the current line is cleared void
rl_redisplay chage what's displayed on the screen to reflect the current contents of rl_line_buffer void void
add_history add one line to history char *line line to be saved void
wait suspends execution of the calling thread until one of its children terminates int *wstatus pid_t
waitpid suspends execution of the calling thread until a child specified by pid argument has change state pid_t pid, int *wstatus, int options pid_t
wait3 is similar to waitpid, but sdditionally return resource usage information about the child int *wstatus, int options, struct rusage *rusage pid_t
wait4 is similar to waitpid, but sdditionally return resource usage information about the child pid_t pid, int *wstatus, int options, struct rusage *rusage pid_t
signal sets the disposition of the signal signum to handler int signum, sighandler_t handler returns the previus value of the signal handler of SIG_ERR on error
sigaction system call is used to change the action taken by a process on receipt of a specific signal int signum, const struct sigaction *act, struct sigaction *oldact 0 on success, -1 on error
sigemptyset allow the manipulation of POSIX signal set. Initializes the signal set given by set to empty, with all signals excluded from the set sigset_t *set 0 on success, -1 on error
sigaddset add signal signum from set sigset *set, int signum 0 on success, -1 on error
kill system call can be used to send any signal to any process group or process pid_t pid, int sig 0 on success, -1 on error and errno is set appropriately
getcwd copies an absolute pathname of te current working directory to the array pointed to by buf, which is of length size char *buf,size_t size on success return a poiter ro a string containing the pathname of the current working directory. on failure return NULL, and errno is set to indicate the error
chdir changes the current working directory of the calling process to the dir specified in path const char *path 0 on success or -1 on error and errno is set appropriately
stat return information about a file, in the buffer pointed to by statbuf. Permission is required on all of the directorries in pathname that lead to the file const char *pathname, struct stat *statbuf 0 on success or -1 on error and errno is set appropriately
lstat is identical to stat, except that if pathname is a symbolic lin, then id returns infomarion about the link itself, not the file that it refers to. const char *pathname, struct stat *statbuf 0 on success or -1 on error and errno is set appropriately
fstat is identical to stat, except that the file about which information is to be retrieved is specified by the file descriptor fd. int fd, struct stat *statbuf 0 on success or -1 on error and errno is set appropriately
unlink deletes a name from the filesystem. If that name was the last link to a file and no processes have the file open, the file is deleted and the space it was using is made available for reuse. If the name was the last link to a file but any processes still have the file open, the file will remain in existence until the last file descriptor referring to it is closed. If the name referred to a symbolic link, the link is removed. If the name referred to a socket, FIFO, or device, the name for it is removed but processes which have the object open may continue to use it. const char *pathname 0 on success or -1 on error and errno is set appropriately
dup Duplica um File Descriptor. Quando da certo retorna um fd com o: Mesmo arquivo aberto (ou pipe) do arquivo original, mesmo ponteiro de arquivo (ambos os descritores de arquivo compartilham um ponteiro de arquivo), Mesmo modo de acesso (leitura, gravação ou leitura/gravação) int dup(int fildes) Success: Retorna um int com o fd duplicado, Error: Retorna -1 e define errno para o valor retornado
dup2 Duplica um File Descriptor aberto em outro File Descriptor int dup(int fildes, int fildes2); Success: Retorna um int com o fd duplicado, Error: Retorna -1 e define errno para o valor retornado
opendir Acessa um fluxo de diretório correspondente ao diretório nomeado pelo argumento dirname . O fluxo de diretório é posicionado na primeira entrada. Se o tipo DIR for implementado usando um descritor de arquivo, os aplicativos só poderão abrir até um total de arquivos e diretórios {OPEN_MAX}. DIR *opendir(const char *dirname); Após a conclusão bem-sucedida, opendir () deve retornar um ponteiro para um objeto do tipo DIR . Caso contrário, um ponteiro nulo deve ser retornado e errno definido para indicar o erro.
readdir Lê um diretório, retorna um ponteiro para uma estrutura que representa a entrada de diretório na posição atual no fluxo de diretório especificado pelo argumento dirp e posiciona o fluxo de diretório na próxima entrada. Ele retorna um ponteiro nulo ao atingir o final do fluxo de diretório. int readdir_r(DIR *dirp, struct dirent *entry, struct dirent result); Success: readdir() retorna um ponteiro para um objeto do tipo struct dirent. Error: Quando um erro é encontrado, um ponteiro nulo é retornado e errno é definido para indicar o erro. Quando o final do diretório é encontrado, um ponteiro nulo é retornado e errno não é alterado.
strerror Retorna um ponteiro para uma string que contém uma mensagem de erro para um errnum específico. char *strerror(int errnum) Success: A string de erro é retornada com codigo 0, Error: é retornada -1 e atribuido Errno ao número
perror Imprime uma mensagem de erro descritiva para stderr. Primeiro a string str é impressa, seguida por dois pontos e depois um espaço. void perror(const char *str) (none)
isatty Testa se um File Descriptor se refere a um terminal. int isatty(int fd); Success: retorna 1 se o fd for um descritor de arquivo aberto referente a um terminal; Error: caso contrário, 0 é retornado e errno é definido para indicar o erro.
ttyname Retorna um ponteiro para uma string contendo um nome de caminho terminado em nulo do terminal associado aos fildes do descritor de arquivo. O valor de retorno pode apontar para dados estáticos cujo conteúdo é substituído por cada chamada. char *ttyname(int fildes); Success: retorna um ponteiro para um nome de caminho. Error: NULL é retornado e errno é definido como indicar o erro. Retorna 0 em sucesso e um número de erro em caso de erro.
ttyslot Encontra o slot do terminal do usuário atual em alguns Arquivo. int ttyslot(void); Success: Retornará o número do slot. Em erro (por exemplo, se nenhum dos descritores de arquivo 0, 1 ou 2 estiver associado com um terminal que ocorre nesta base de dados) ele retorna 0 em Sistemas UNIX V6 e V7 e semelhantes a BSD, mas -1 em sistemas semelhantes a System V sistemas.
ioctl Acessa arquivos especiais de sistema. int ioctl(int fd, unsigned long request, ...); Success: zero é retornado. Algumas solicitações ioctl() usam o valor de retorno como um parâmetro de saída e retornar um valor não negativo valor no sucesso. Error: -1 é retornado e errno é definido como indicar o erro.
getenv Procura a string de ambiente apontada pelo nome e retorna o valor associado à string. char *getenv(const char *name) Success: Valor da variável de ambiente que foi buscada. Error: um ponteiro nulo se essa variável de ambiente não existir.
tcsetattr Define os parâmetros associados ao terminal. int tcsetattr(int fildes, int optional_actions, const struct termios *termios_p); Success: 0 deve ser retornado. Error: -1 deve ser retornado e errno definido para indicar o erro.
tcgetattr Deve obter os parâmetros associados ao terminal referido por fildes e armazená-los na estrutura termios referenciada por termios_p . O argumento fildes é um descritor de arquivo aberto associado a um terminal. int tcgetattr(int fildes, struct termios *termios_p); Success: 0 deve ser retornado. Caso contrário. Error: -1 deve ser retornado e errno definido para indicar o erro.
tgetent Consulta a descrição do tipo de terminal em uso int tgetent (char *buffer, char *termtype); Success: as funções que retornam um número inteiro retornam OK. Error: eles retornam ERR. Funções que retornam ponteiros retornam um ponteiro nulo em caso de erro.
tgetflag interroga o programa para vários recursos do terminal. Você deve especificar o código de duas letras do recurso cujo valor você procura chamado de capacidade. É um booleano que obtem um valor int tgetflag (char *name); Success: Se o nome do recurso estiver presente na descrição do terminal, tgetflag retornará 1; Error: retorna 0.
tgetnum Obter um valor de capacidade de tipo numérico int tgetnum(char *id); Success: retornará o valor numérico (que não é negativo). Se a capacidade não for mencionada na descrição do terminal, retornará -1.
tgetstr Obter um valor de capacidade de tipo String char *tgetstr (char *name, char area); Success: Ele retorna um ponteiro para uma string que é o valor da capacidade ou um ponteiro nulo se a capacidade não estiver presente na descrição do terminal.
tgoto Trata o caso de especial de cursor char *tgoto (char *cstring, int hpos, int vpos) Success: retorna 1, 0 se não houver tal entrada e -1 se o banco de dados terminfo não puder ser encontrado.
tputs recupera recursos pelo nome termcap ou terminfo. int tputs(const char *str, int affcnt, int (*putc)(int)); Success: retorna 1, 0 se não houver tal entrada e -1 se o banco de dados terminfo não puder ser encontrado.

Clone e execute o prejeto

  1. Clone ester repositório:
git clone https://github.com/lamorim42/minishell.git miaushell
  1. Make para compilar o projeto:
make
  1. Rode o 'miaushell':
./minishell

Exemplo

exemplo de miaushell sendo utilizado