Funções exec
Estas funções substituem a imagem de um processo por outra imagem de acordo com os argumentos especificados. Com o fork podemos criar novos processos e com as funções exec podemos executar novos programas ( estas funções não criam um novo processo para executar o programa, em vez disso substituem a imagem do processo pelo programa que se vai executar).
Funcionamento das funções exec
Nota: Se não existir espaço suficiente, a função exec retorna um erro e o processo original continua a executar na instrução exactamente a seguir à função exec.
int execl(const char *caminho, const char * argumento0, … , (char *) 0 );
int execv(const char *caminho, const char * argumentos[]);
Estas duas primeiras funções executam um programa, tendo a variável caminho, o local onde o ficheiro executável se encontra. O primeiro argumento deve ter o nome do ficheiro executável. A única diferença entre estas duas funções é o facto de uma receber os argumentos um por um, terminando com a string nula, enquanto que a segunda função recebe todos os argumentos num array de strings.
int execle(const char *caminho, const char * argumento0, … , (char *) 0, const char *envp[] );
int execve(const char *caminho, const char * argumentos[], const char *envp[] );
Estas duas funções também "passam" para o programa as variáveis ambiente.
int execlp(const char *ficheiro, const char * argumento0, … , (char *) 0 );
int execvp(const char *ficheiro, const char * argumentos[]);
Estas duas funções recebem como parâmetros o nome do ficheiro executável (também podemos utilizar o caminho completo para executar o ficheiro). Se a variável ficheiro não contém um caminho, o ficheiro executável vai ser procurado nos directórios especificados na variável ambiente PATH.
Exercícios
1- Considere a seguinte parte de um programa:
...
for (i=0;i<5; i++)
execlp(“SO2”,”SO2”,0);
...
Quantas vezes é executado o programa “SO2”? Justifique.
2- Considere a seguinte parte de um programa:
...
for(i=0;i<3;i++)
{
pid = fork();
if (pid == 0)
pid = fork();
if (pid > 0)
execlp("SO2", "SO2",0);
}
...
Quantas vezes é executado o programa "SO2"? Justifique.
3- Considere a seguinte parte de um programa:
...
pid = fork();
pid = fork();
for(i=0; i<5; i++)
{
pid = fork();
execlp(“exame”, “exame”, 0);
if (pid == 0)
break;
}
execlp(“alunos”, “alunos”,”so2”,0);
...
Quantas vezes vão ser executados os programas exame e alunos? Justifique.
4- Faça um programa que recebe como parâmetros os nomes dos comandos que tem de executar. O programa executa esses comandos e só quando lançar todos os comandos é que fica à espera que eles terminem.
Exemplo: executa ps ls who
Este exemplo deve executar os comandos ps, ls e who e esperar que terminem.
5- Faça um programa que simule uma shell (interpretador de comandos). O programa só termina quando se introduz o comando saír. Só deve aceitar outro comando quando o comando que está a ser executado terminar. Se estiver interessado(a), faça com que o programa também receba os parâmetros dos comandos (Ex: ls -la).
6- Um fanático por apostas pretende que implemente um jogo que lhe permita simular a aposta de uma dada quantia num número. As regras do jogo são simples:
- o jogador escolhe um número entre 1 e 5;
- o programa “lança” um número entre 1 e 5;
- se o jogador tiver acertado recebe o dobro da aposta.
Para lançar um número deve ser usado o programa "batota". Este programa retorna como “valor de saída” um número entre 1 e 5. O jogador começa com 25 euros e escolhe a quantia a apostar em cada ronda. O programa termina quando o jogador perder todo o dinheiro.
Sugestão: para impementar o programa “batota” utilize as funções rand e srand.