Universidade Federal de Ouro Preto Instituto de Ciências Exatas e Biológicas      Departamento de ComputaçãoBCC264 - Siste...
Sumário1   Introdução                                                                                                     ...
19   Função Main . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12                                     3
1       Introdução   Este trabalho tem por objetivo fazer com que os alunos se familiarizem com oambiente Unix, desenvolva...
à entrada padrão do processo seguinte. Para simplicar a implementação,      M yShell não permite o encadeamento de pipes, ...
2.1           Tratamento da Entrada de dados        A função split, representada abaixo, trata a entrada de dados do usuár...
2.3              Função para comando Pwd       O comando pwd, em U N IX , apresenta o diretório corrente do usuário da M y...
25   }                                                      Programa 4: Função cd        Para a implementação dessa função...
}                                                            Programa 6: Função grep     2.7              Função para coma...
w a i t ( s t a t u s 1 ) ;             }     }                                                     Programa 8: Função kil...
Programa 10: Função mkdir     2.11         Função para comandos Mv, Rm e RmDir        Os comandos mv , rm e rmdir, em U N ...
2.12         Função para comando Cp        O comando cp, em U N IX , permite que o usuário faça cópia de um cheiro para   ...
int            vArgumentos [ 0 ]           =     / b i n / ps  ;            if                   pid     =    fork () ; 5 ...
2.16         Função para comando Sleep        O comando sleep, em U N IX , é usado para dar um tempo antes de começar um  ...
void             meu_cat (          char ∗∗            vArgumentos )     {                  vArgumentos [ 0 ]             ...
p r i n t f (  nMYSHELL                 : ) n ) ;30         p r i n t f ( DEBUG:           PID %d ,           PPID %d  n  ...
}    else if     ( strcmp (  cd  ,        comando )   ==   0)       {             meu_cd ( v A r g u m e n t o s ) ; 85   ...
}   else if        ( s t r c m p (  nano  ,    comando )   ==   0) {140                   meu_nano ( v A r g u m e n t o s...
Próximos SlideShares
Carregando em…5
×

MyShell

788 visualizações

Publicada em

Publicada em: Educação
0 comentários
0 gostaram
Estatísticas
Notas
  • Seja o primeiro a comentar

  • Seja a primeira pessoa a gostar disto

Sem downloads
Visualizações
Visualizações totais
788
No SlideShare
0
A partir de incorporações
0
Número de incorporações
2
Ações
Compartilhamentos
0
Downloads
35
Comentários
0
Gostaram
0
Incorporações 0
Nenhuma incorporação

Nenhuma nota no slide

MyShell

  1. 1. Universidade Federal de Ouro Preto Instituto de Ciências Exatas e Biológicas Departamento de ComputaçãoBCC264 - Sistemas Operacionais Terceiro Trabalho Prático Johnnatan Messias Pollyanna Gonçalves Wellington Dores Professor - Fabrício Benevenuto Ouro Preto 1 de junho de 2011
  2. 2. Sumário1 Introdução 1 1.1 Considerações iniciais . . . . . . . . . . . . . . . . . . . . . . . . . . . 1 1.2 O Problema . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1 1.2.1 Linguagem da MyShell . . . . . . . . . . . . . . . . . . . . . . 12 A implementação da MyShell 2 2.1 Tratamento da Entrada de dados . . . . . . . . . . . . . . . . . . . . 3 2.2 Função para comando Ls . . . . . . . . . . . . . . . . . . . . . . . . . 3 2.3 Função para comando Pwd . . . . . . . . . . . . . . . . . . . . . . . . 4 2.4 Função para comando Cd . . . . . . . . . . . . . . . . . . . . . . . . 4 2.5 Função para comando Cat . . . . . . . . . . . . . . . . . . . . . . . . 5 2.6 Função para comando Grep . . . . . . . . . . . . . . . . . . . . . . . 5 2.7 Função para comando Ping . . . . . . . . . . . . . . . . . . . . . . . 6 2.8 Função para comando Kill . . . . . . . . . . . . . . . . . . . . . . . . 6 2.9 Função para comando Date . . . . . . . . . . . . . . . . . . . . . . . 7 2.10 Função para comando Mkdir . . . . . . . . . . . . . . . . . . . . . . . 7 2.11 Função para comandos Mv, Rm e RmDir . . . . . . . . . . . . . . . . 8 2.12 Função para comando Cp . . . . . . . . . . . . . . . . . . . . . . . . 9 2.13 Função para comando Chmod . . . . . . . . . . . . . . . . . . . . . . 9 2.14 Função para comando Ps . . . . . . . . . . . . . . . . . . . . . . . . . 9 2.15 Função para comando Sh e Bash . . . . . . . . . . . . . . . . . . . . 10 2.16 Função para comando Sleep . . . . . . . . . . . . . . . . . . . . . . . 11 2.17 Função para comando Pipe e Background . . . . . . . . . . . . . . . . 11 2.18 Função para comando Exit . . . . . . . . . . . . . . . . . . . . . . . . 11 2.19 Função Principal . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12Lista de Programas 1 Função split . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3 2 Função ls . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3 3 Função pwd . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4 4 Função cd . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4 5 Função cat . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5 6 Função grep . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5 7 Função ping . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6 8 Função kill . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6 9 Função date . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7 10 Função mkdir . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7 11 Funções Rm, Mv e RmDir . . . . . . . . . . . . . . . . . . . . . . . . 8 12 Função cp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9 13 Função chmod . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9 14 Função ps . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9 15 Funções Sh e Bash . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10 16 Função sleep . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11 17 Função Pipe ( )eBackground(&) . . . . . . . . . . . . . . . . . . . . 11 18 Função Exit . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12 2
  3. 3. 19 Função Main . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12 3
  4. 4. 1 Introdução Este trabalho tem por objetivo fazer com que os alunos se familiarizem com oambiente Unix, desenvolvam habilidades de programação defensiva em C, aumentemsua exposição às funcionalidades de interpretadores de comandos e coloquem emprática conceitos sobre gerência de processos (p.ex., disparo e terminação).1.1 Considerações iniciais • Sistema Operacional utilizado: Ubuntu 11.04 • Ambiente de desenvolvimento: NetBeans IDE C/C++ • Ambiente de desenvolvimento da documentação: TeXnicCenter 1 Editor de LTEX. A1.2 O Problema Implementar uma shell mínima, a M yShell, para colocar em prática os princípiosde manipulação de processos. Esse tipo de conhecimento é essencial no desenvolvi-mento de sistemas complexos com diversos processos, como no caso de servidores.1.2.1 Linguagem da MyShell A linguagem compreendida pela M yShell é bem simples. Cada sequência decaracteres diferentes de espaço é considerada um termo. Termos podem ser oper-ações internas da shell, nomes de programas que devem ser executados, argumentosa serem passados para os comandos ou programas e operadores especiais. Oper-ações internas da shell são as sequências de caracteres cd, pwd, wait e exit. Essasoperações devem sempre terminar com um sinal de m de linha (return) e devemser entradas logo em seguida ao prompt (isto é, devem sempre ser entrados comolinhas separadas de quaisquer outros comandos). Operadores são os símbolos (back-ground) e | (pipe), quando ocorrem isoladamente (como um único caractere entreespaços). Programas a serem executados são identicados pelo nome do seu ar-quivo executável e podem ser seguidos por um número máximo de dez argumentos(parâmetros que serão passados ao programa através do vetor argv[]. Cada comandode disparo deve terminar com um dos operadores, ou com o m de linha. • Fim de linha: indica que o processo deve ser disparado e a myshell deve esperar pelo seu m antes de exibir outro prompt. • Background: o processo deve ser disparado e a M yShell deve continuar sua execução. Isso pode signicar a continuação da interpretação da linha de co- mandos, se há outros comandos na linha, ou o retorno imediato ao prompt. Cada vez que um processo é disparado em background, M yShell deve ex- ibir uma mensagem a esse respeito, com o identicador (pid) do processo em questão. • Pipe: o conteúdo após o operador deve ser interpretado outro comando a ser executado, sendo que a saída padrão do primeiro processo deve ser conectada 1
  5. 5. à entrada padrão do processo seguinte. Para simplicar a implementação, M yShell não permite o encadeamento de pipes, isto é, não é permitido colo- car outro pipe na saída do segundo programa. Pode-se, entretanto, colocar ambos os programas em background terminando a sequência com o operador apropriado (nesse caso, uma mensagem sobre a operação em background deve ser exibida para cada processo). Os comandos internos têm as seguintes interpretações: • CD: muda o diretório corrente da shell. Isso terá impacto sobre os arquivos visíveis sem um caminho completo (path). • PWD: exibe o diretório corrente visto pelo processo. • WAIT: faz com que a shell espere pelo término de todos os processos que possam estare m execução antes de exibir um novo prompt. Cada processo que seja encontrado durante um wait deve ser informado através de uma men- sagem na linha de comando. Caso não haja processos pelos quais esperar, uma mensagem a respeito deve ser exibida e M yShell deve continuar sua execução. • EXIT: termina a operação da shell se não há processos em background. Caso contrário, exibe uma mensagem informando o fato e realiza a operação wait antes de terminar.2 A implementação da MyShell Mais adiante apresentamos a implementação das funções que trata um comandoqualquer que vai ser digitado pelo usuário na M yShell, algumas das funções primi-tivas que serão utilizadas em outras funções estão explicadas abaixo: • Primitiva f ork(): única chamada de sistema que possibilita a criação de um processo em U N IX . • Primitiva execv(): função em que o primeiro argumento corresponde ao cam- inho completo para o executável ou script a ser executado e o segundo é o nome do programa a ser executado. • Primitiva wait(): suspende a execução do processo pai até a morte de seu processo lho (se o lho já estiver morto, a função retorna -1, imediatamente). • Primitiva exit(): ADICIONAR!!!! Algumas bibliotecas da linguagem C que foram utilizadas para a execução doprograma: • errno.h • signal.h • sys/types.h • sys/wait.h • unistd.h 2
  6. 6. 2.1 Tratamento da Entrada de dados A função split, representada abaixo, trata a entrada de dados do usuário na M yShell utilizando funções auxiliares da biblioteca string.h denidas na linguagem. 1 char ∗∗ split ( char ∗∗ linha , char ∗∗ vString , char ∗∗ comando , int ∗ tam ) { char ∗ int tok = NULL ; char ∗ sizeof char i ; 5 tok = ( ) malloc ( ( ) ∗200) ; s t r c p y ( tok , ∗ linha ) ; tok = s t r t o k ( tok , n ) ; ∗ comando = s t r t o k ( tok , ) ;10 // P o s i ç ã o 0 reservada para o execv vString [ 1 ] = s t r t o k (NULL, ) ; if ( ! vString [ 0 ] )15 vString [ 0 ] = ; for ( i = 2; vString [ i −1]; i ++){ vString [ i ] = s t r t o k (NULL, ) ; }20 vString [ i − 1] = NULL ; ∗ tam = ( i − 1) ; return f r e e ( tok ) ;25 vString ; } Programa 1: Função split 2.2 Função para comando Ls O comando ls, em U N IX , mostra o conteúdo de um diretório passado como argumento. A função abaixo implementada recebe como parâmetro (em forma de string ) os argumentos que foram passados pelo usuário da M yShell: 2 void meu_ls ( char ∗∗ vArgumentos ) { int vArgumentos [ 0 ] = / b i n / l s ; 5 pid_cd = fork () ; if ( pid_cd == 0) else execv ( / b i n / l s , vArgumentos ) ;10 int { status1 ; w a i t ( s t a t u s 1 ) ; // e s p e r a a morte de um filho } } Programa 2: Função ls 3
  7. 7. 2.3 Função para comando Pwd O comando pwd, em U N IX , apresenta o diretório corrente do usuário da M yShell. Uma implementação para essa função é apresentada em: 3 void meu_pwd ( char ∗∗ vArgumentos ) { vArgumentos [ 0 ] = / b i n / pwd ; 5 int pid = fork () ; if ( pid == 0) {10 p r i n t f ( n ) ; e x e c v ( / b i n / pwd , vArgumentos ) ; p r i n t f ( n ) ; else }15 int { status1 ; w a i t ( s t a t u s 1 ) ; }20 } Programa 3: Função pwd 2.4 Função para comando Cd O comando cd, em U N IX , abre o diretório passado como argumento pelo usuário da M yShell. Uma implementação para essa função é apresentada em: 4 void meu_cd ( char ∗∗ vArgumentos ) { int pid_cd = 0; 5 if ( pid_cd == 0) char { cwd [ 2 0 4 8 ] ; cwd [ 0 ] = 0 ;10 if ( g e t c w d ( cwd , 2048) != NULL) if { ( c h d i r ( vArgumentos [ 1 ] ) != 0) {15 printf ( It wasn t possible set current directory to / n ) ; } } else }20 int { status1 ; w a i t ( s t a t u s 1 ) ; } 4
  8. 8. 25 } Programa 4: Função cd Para a implementação dessa função utilizamos as funções getcwd() (retorna o nome completo do diretório corrente) e chdir (muda o diretório corrente para aquele passado como parâmetro). 2.5 Função para comando Cat O comando cat, em U N IX , combina um ou mais arquivos e os apresenta na saída padrão, ou seja, mostra o conteúdo de um arquivo passado como argumento pelo usuário da M yShell. Uma implementação para essa função é apresentada em: 5 void meu_cat ( char ∗∗ vArgumentos ) { vArgumentos [ 0 ] = / b i n / c a t ; 5 int pid_cat = fork () ; if ( pid_cat == 0) else execv ( / b i n / c a t , vArgumentos ) ;10 int { status1 ; w a i t ( s t a t u s 1 ) ; }15 } Programa 5: Função cat 2.6 Função para comando Grep O comando cat, em U N IX , procura por linhas em arquivos que correspondam a um padrão especicado pelo usuário da M yShell e as apresenta. Uma implemen- tação para essa função é apresentada em: 6 void meu_grep ( char ∗∗ vArgumentos ) { int vArgumentos [ 0 ] = / b i n / grep ; 5 if pid = fork () ; ( pid == 0) { p r i n t f ( n ) ; execv ( / b i n / grep , vArgumentos ) ;10 p r i n t f ( n ) ; else } int {15 status1 ; w a i t ( s t a t u s 1 ) ; } 5
  9. 9. } Programa 6: Função grep 2.7 Função para comando Ping O comando ping , em U N IX , envia pacotes ICM P para um determinado host e mede o tempo de resposta. Uma implementação para essa função é apresentada em: 7 void meu_ping ( char ∗∗ vArgumentos ) { int vArgumentos [ 0 ] = / b i n / ping ; 5 if pid = fork () ; ( pid == 0) { p r i n t f ( n ) ; execv ( / b i n / ping , vArgumentos ) ;10 p r i n t f ( n ) ; else } int {15 status1 ; w a i t ( s t a t u s 1 ) ; } } Programa 7: Função ping 2.8 Função para comando Kill O comando kill, em U N IX , envia sinais a determinados processos em execução. Por padrão é enviado o sinal SIGT ERM que requisita a nalização de um processo. Em geral é utilizado na forma 1 , onde pid é o identicador do processo que pode ser obtido através do comando ps 14. Uma implementação para essa função é apresentada em: 8 void meu_kill ( char ∗∗ vArgumentos ) { int vArgumentos [ 0 ] = / b i n / k i l l ; 5 if pid = fork () ; ( pid == 0) { p r i n t f ( n ) ; execv ( / b i n / k i l l , vArgumentos ) ;10 p r i n t f ( n ) ; else } int {15 status1 ; 1 kill pid 6
  10. 10. w a i t ( s t a t u s 1 ) ; } } Programa 8: Função kill 2.9 Função para comando Date O comando date, em U N IX , simplesmente exibe a data e a hora atual do sistema no prompt da M yShell. Uma implementação para essa função é apresentada em: 9 void meu_date ( char ∗∗ vArgumentos ) { int vArgumentos [ 0 ] = / b i n / d a t e ; 5 if pid = fork () ; ( pid == 0) { p r i n t f ( n ) ; execv ( / b i n / d a t e , vArgumentos ) ;10 p r i n t f ( n ) ; else } int {15 status1 ; w a i t ( s t a t u s 1 ) ; } } Programa 9: Função date 2.10 Função para comando Mkdir O comando mkdir, em U N IX , cria um diretório no diretório atual da M yShell. Uma implementação para essa função é apresentada em: 10 void meu_mkdir ( char ∗∗ vArgumentos ) { int vArgumentos [ 0 ] = / b i n / mkdir ; 5 if pid = fork () ; ( pid == 0) { p r i n t f ( n ) ; execv ( / b i n / mkdir , vArgumentos ) ;10 p r i n t f ( n ) ; else } int {15 status1 ; w a i t ( s t a t u s 1 ) ; } } 7
  11. 11. Programa 10: Função mkdir 2.11 Função para comandos Mv, Rm e RmDir Os comandos mv , rm e rmdir, em U N IX , move (ou renomeia) um diretório ou cheiro, remove um determinado cheiro e um remove um diretório, respectivamente. Uma implementação para essa função é apresentada em: 11 void meu_mv( char ∗∗ vArgumentos ) { int vArgumentos [ 0 ] = / b i n /mv ; if pid = fork () ; 5 ( pid == 0) { p r i n t f ( n ) ; e x e c v ( / b i n /mv , vArgumentos ) ; p r i n t f ( n ) ;10 else int } { status1 ; w a i t ( s t a t u s 1 ) ; } }15 void meu_rm ( char ∗∗ vArgumentos ) { int vArgumentos [ 0 ] = / b i n /rm ; if pid = fork () ;20 ( pid == 0) { p r i n t f ( n ) ; e x e c v ( / b i n /rm , vArgumentos ) ; p r i n t f ( n ) ;25 else int } { status1 ; w a i t ( s t a t u s 1 ) ; } }30 void meu_rmdir ( char ∗∗ vArgumentos ) { int vArgumentos [ 0 ] = / b i n / rmdir ;35 if pid = fork () ; ( pid == 0) { p r i n t f ( n ) ; execv ( / b i n / rmdir , vArgumentos ) ; p r i n t f ( n ) ;40 else int } { status1 ; w a i t ( s t a t u s 1 ) ; }45 } Programa 11: Funções Rm, Mv e RmDir 8
  12. 12. 2.12 Função para comando Cp O comando cp, em U N IX , permite que o usuário faça cópia de um cheiro para outro, onde o primeiro cheiro (passado como argumento) é lido e copiado para o segundo (no caso da inexistência desse, o mesmo é criado). Uma implementação para essa função é apresentada em: 12 void meu_cp ( char ∗∗ vArgumentos ) { int vArgumentos [ 0 ] = / b i n / cp ; if pid = fork () ; 5 ( pid == 0) { p r i n t f ( n ) ; e x e c v ( / b i n / cp , vArgumentos ) ; p r i n t f ( n ) ;10 else int } { status1 ; w a i t ( s t a t u s 1 ) ; } } Programa 12: Função cp 2.13 Função para comando Chmod O comando chmod, em U N IX , permite que o usuário altere as permissões de um cheiro ou diretório no formato drwxrwxrwx, respectivamente: diretório (d), permissão do dono (read/write/execute), do grupo (read/write/execute) e de outros (read/write/execute). Uma implementação para essa função é apresentada em: 13 void meu_chmod ( char ∗∗ vArgumentos ) { int vArgumentos [ 0 ] = / b i n / chmod ; if pid = fork () ; 5 ( pid == 0) { p r i n t f ( n ) ; e x e c v ( / b i n / chmod , vArgumentos ) ; p r i n t f ( n ) ;10 else int } { status1 ; w a i t ( s t a t u s 1 ) ; } } Programa 13: Função chmod 2.14 Função para comando Ps O comando ps, em U N IX , lista a lista de processos em execução, geralmente utilizado quando se necessita para saber o pid de um processo terminá-lo com o comando kill. Uma implementação para essa função é apresentada em: 14 void meu_ps ( char ∗∗ vArgumentos ) { 9
  13. 13. int vArgumentos [ 0 ] = / b i n / ps ; if pid = fork () ; 5 ( pid == 0) { p r i n t f ( n ) ; execv ( / b i n / ps , vArgumentos ) ; p r i n t f ( n ) ;10 else int } { status1 ; w a i t ( s t a t u s 1 ) ; } } Programa 14: Função ps 2.15 Função para comando Sh e Bash Os comandos sh e bash, em U N IX , são interpretadores de comandos feitos para intermediar o usuário e seu sistema. Através deles, o usuário manda um comando, e o interpretador o executa no sistema. Eles são a shelldo sistema. Uma imple- mentação para essa função é apresentada em: 15 void meu_sh ( char ∗∗ vArgumentos ) { int vArgumentos [ 0 ] = / b i n / sh ; if pid = fork () ; 5 ( pid == 0) { p r i n t f ( n ) ; execv ( / b i n / sh , vArgumentos ) ; p r i n t f ( n ) ;10 else int } { status1 ; w a i t ( s t a t u s 1 ) ; } }15 void meu_bash ( char ∗∗ vArgumentos ) { int vArgumentos [ 0 ] = / b i n / bash ; if pid = fork () ;20 ( pid == 0) { p r i n t f ( n ) ; execv ( / b i n / bash , vArgumentos ) ; p r i n t f ( n ) ;25 else int } { status1 ; w a i t ( s t a t u s 1 ) ; } } Programa 15: Funções Sh e Bash 10
  14. 14. 2.16 Função para comando Sleep O comando sleep, em U N IX , é usado para dar um tempo antes de começar um novo processo pela M yShell. Uma implementação para essa função é apresentada em: 16 void meu_sleep ( char ∗∗ vArgumentos ) { int vArgumentos [ 0 ] = / b i n / s l e e p ; if pid = fork () ; 5 ( pid == 0) { p r i n t f ( n ) ; execv ( / b i n / s l e e p , vArgumentos ) ; p r i n t f ( n ) ;10 else int } { status1 ; w a i t ( s t a t u s 1 ) ; } } Programa 16: Função sleep 2.17 Função para comando Pipe e Background O comando (pipe), em U N IX , que faz o encadeamento de processosou seja, ele permite que a saída de um comando seja diretamente utilizado em outro comando. Já o comando (background) permite que um processo seja executado em segundo plano, ou seja, a M yShell não cará impedida de inicializar outros processos durante a execução do anterior. Uma implementação para essas funções é apresentada em: 17 int isPipeOrBk ( char ∗ linha ){ int i , tam = strlen ( linha ) − 1; 5 for if ( i =0; i tam ; i ++) return (( linha [ i ] == | ) || ( linha [ i ] == ) ) { 1; return } 0;10 } Programa 17: Função Pipe ( )eBackground() Ao receber o comando do usuário utilizamos a função isP ipeOrBk para vericar em O(n) se o comando contém ou não os caracteres ou . Caso tenha, a função retornará 1 e 0 caso contrário. 2.18 Função para comando Exit O comando exit, em U N IX , termina a execução da M yShell se não há processos em background, caso contrário a ação deverá ser tratada. Uma implementação para essa função é apresentada em: 18 11
  15. 15. void meu_cat ( char ∗∗ vArgumentos ) { vArgumentos [ 0 ] = / b i n / c a t ; 5 int pid_cat = fork () ; if ( pid_cat == 0) else execv ( / b i n / c a t , vArgumentos ) ;10 int { status1 ; w a i t ( s t a t u s 1 ) ; }15 } Programa 18: Função Exit 2.19 Função Principal Abaixo apresentamos a função principal para o funcionamento da M yShell. No corpo da função principal main é feita a entrada dos dados pelo usuário (comandos e argumentos para tais) e o tratamento de cada caso, chamando as respectivas funções que tratam o comando necessitado e ao nal desaloca a memória utilizada na execução do programa. A implementação da função é apresentada abaixo: 19 / ∗ Mini −i n t e r p r e t a d o r ∗/ #include s t d i o . h 5 #include s t d l i b . h #include s t r i n g . h #include u n i s t d . h10 #include f u n c o e s . h int int char ∗∗ a r g v ) int main ( argc , { linesize = 512; // Tamanho da linha de comando15 char ∗ char ∗∗ linha = NULL ; // Linha de Comando int vArgumentos = NULL ; // Vetor de argumentos char ∗ tam = 0; // Quantidade de Argumentos int comando = NULL ; // Comando a ser executado20 i , linhaMatriz = 40 , colunaMatriz = 100; // dimensoes do vetor int de argumentos char ∗ sizeof char ∗ pos ; char ∗ ∗ sizeof char ∗ linha = ( ) malloc ( ( ) 512) ; ∗ linhaMatriz ) ; char ∗ sizeof char vArgumentos = ( ) malloc ( ( ) vArgumentos [ 0 ] = ( ) malloc ( ( ) ∗( linhaMatriz ∗ for colunaMatriz ) ) ;25 ( i = 1; i linhaMatriz ; i ++) vArgumentos [ i ] = ( v A r g u m e n t o s [ 0 ] [ i ∗ colunaMatriz ] ) ; 12
  16. 16. p r i n t f ( nMYSHELL : ) n ) ;30 p r i n t f ( DEBUG: PID %d , PPID %d n n , getpid () , getppid () ) ; // pid − Process ID ppid − Parent Process ID while (1) {35 char cwd [ 2 0 4 8 ] ; // P a s t a atual cwd [ 0 ] = 0 ; if ( g e t c w d ( cwd , 2048) == NULL) { //40 p e r r o r ( Nao foi possivel obter o diretorio atual . Padronizando para / n ) ; s t r c p y ( cwd , / ) ; if ( c h d i r ( cwd ) != 0) {45 p e r r o r ( Nÿo foi possivel acessar o diretorio a t u a l . n ) ; } }50 newline : p r i n t f ( M y S h e l l :~% s $ , cwd ) ; f g e t s ( linha , linesize , stdin ) ;55 if n ) == 0 ) goto ( strcmp ( l i n h a , newline ; // s e m p r e que nÿo hý comandos volta para newline if ( isPipeOrBk ( l i n h a ) ) { continue system ( l i n h a ) ;60 ; } vArgumentos = s p l i t ( l i n h a , vArgumentos , comando , tam ) ; // Guarda os comandos no vetor de args .65 //A partir desse ponto procura pelo comando digitado e chama a funcao correspondente if ( strcmp ( h e l p , comando ) == 0) { meu_help ( ) ;70 } else if ( strcmp ( c r e d i t o s , comando ) == 0) { creditos () ; } else if ( strcmp ( l s , comando ) == 0) { meu_ls ( v A r g u m e n t o s ) ;75 } else if ( strcmp ( e x i t , comando ) == 0) { meu_exit ( 0 ) ; } else if ( s t r c m p ( pwd , comando ) == 0) {80 meu_pwd ( v A r g u m e n t o s ) ; 13
  17. 17. } else if ( strcmp ( cd , comando ) == 0) { meu_cd ( v A r g u m e n t o s ) ; 85 } else if ( strcmp ( c a t , comando ) == 0) { meu_cat ( v A r g u m e n t o s ) ; } else if ( strcmp ( w a i t , comando ) == 0) { meu_wait ( ) ; 90 } else if ( s t r c m p ( , comando ) == 0) { meu_background ( ) ; } else if ( strcmp ( p i n g , comando ) == 0) { 95 meu_ping ( v A r g u m e n t o s ) ; } else if ( strcmp ( k i l l , comando ) == 0) { m e u _ k i l l ( vArgumentos ) ;100 } else if ( strcmp ( d a t e , comando ) == 0) { meu_date ( v A r g u m e n t o s ) ; } else if ( strcmp ( gr ep , comando ) == 0) { meu_grep ( v A r g u m e n t o s ) ;105 } else if ( strcmp ( mkdir , comando ) == 0) { meu_mkdir ( v A r g u m e n t o s ) ; } else if ( s t r c m p ( mv , comando ) == 0) {110 meu_mv( v A r g u m e n t o s ) ; } else if ( s t r c m p ( rm , comando ) == 0) { meu_rm ( v A r g u m e n t o s ) ;115 } else if ( strcmp ( rmdir , comando ) == 0) { meu_rmdir ( v A r g u m e n t o s ) ; } else if ( strcmp ( cp , comando ) == 0) { meu_cp ( v A r g u m e n t o s ) ;120 } else if ( s t r c m p ( chmod , comando ) == 0) { meu_chmod ( v A r g u m e n t o s ) ; } else if ( strcmp ( echo , comando ) == 0) {125 meu_echo ( v A r g u m e n t o s ) ; } else if ( strcmp ( hostname , comando ) == 0) { meu_hostname ( v A r g u m e n t o s ) ;130 } else if ( strcmp ( ps , comando ) == 0) { meu_ps ( v A r g u m e n t o s ) ; } else if ( strcmp ( sh , comando ) == 0) { meu_sh ( v A r g u m e n t o s ) ;135 } else if ( strcmp ( bash , comando ) == 0) { meu_bash ( v A r g u m e n t o s ) ; 14
  18. 18. } else if ( s t r c m p ( nano , comando ) == 0) {140 meu_nano ( v A r g u m e n t o s ) ; } else if ( strcmp ( s l e e p , comando ) == 0) { meu_sleep ( vArgumentos ) ;145 } else { p r i n t f ( Comando % s nÿo encontrado ! n , comando ) ; } linha [ 0 ] = 0 ;150 } f r e e ( vArgumentos [ 0 ] ) ; f r e e ( vArgumentos ) ; } Programa 19: Função Main Aqui é feita a vericação com a função isP ipeOrBk 17 de modo a escolher qual será o uxo de execução do programa de duas maneiras: • Caso a função isP ipeOrBk retorne 1, ou seja, tendo como instrução a execução de um comando em Background ou utilização do Pipe chamamos o comando System do Linux para fazer uma chamada ao Sistema de modo a executar esses comandos. • Caso não haja o programa será executado normalmente de modo que nós é que contralamos a criação dos processos lhos e da execução dos comandos contidos no bin. Note que também estamos utilizando uma matriz para guardar os dados que serão passados pelo usuário da M yShell. Para essa matriz de char(ou seja, vetor de strings) foi feita uma alocação com a quantidade de linhas da matriz de adjacên- cias e mais uma alocação para a posição matriz[0] com tamanho Linha ∗ Coluna, fazendo, em seguida, um redirecionamento dos endereços da matriz. Para melhor entendimento, vide Figura 1 Figura 1: Representação da Alocação de Matriz 15

×