[19]. Quantas vezes o código abaixo imprime a palavra “hello”?
int main(int argc, char **argv) {
int i;
for (i=0; i < 3; i++) {
execl("/bin/echo", “echo”, “hello”, 0);
}
}
int main(int argc, char **argv) {
int i;
for (i=0; i < 3; i++) {
execl("/bin/echo", “echo”, “hello”, 0);
}
}
Passo 1
O enunciado pergunta: “Quantas vezes o código abaixo imprime a palavra ‘hello’?” e fornece o código:
int main(int argc, char **argv) {
int i;
for (i=0; i < 3; i++) {
execl("/bin/echo", “echo”, “hello”, 0);
}
}
Informações relevantes extraídas do enunciado:
int main(int argc, char **argv) {
int i;
for (i=0; i < 3; i++) {
execl("/bin/echo", “echo”, “hello”, 0);
}
}
Informações relevantes extraídas do enunciado:
- Há um laço for que tenta executar 3 iterações (i = 0, 1, 2).
- Em cada iteração chama-se execl("/bin/echo", “echo”, “hello”, 0);
- Não há chamadas a fork() nem tratamento de erro após execl no código dado.
- A pergunta é quantas vezes a palavra “hello” é impressa na execução desse programa.
Passo 2
O que faz execl: explicação didática e simples.
- execl pertence à família exec (execv, execl, execle, execvp, execvpe, execve). A ideia geral: essas funções substituem a imagem do processo atual pela imagem de um novo programa.
- Propriedade fundamental: se a chamada exec tem sucesso, ela NUNCA retorna para o chamador. Ou seja, o processo atual passa a executar o novo programa indicado e o código depois da chamada exec no programa original não é mais executado.
- Se a chamada exec falha (por exemplo, arquivo não existe ou não tem permissão), então exec retorna
e errno é setado; nesse caso o fluxo continua no programa original depois da chamada (podendo repetir o laço). - Protótipo (resumido): int execl(const char *path, const char *arg0, …, (char *)0);
- O último argumento deve ser um ponteiro nulo ((char *)0 ou NULL) para marcar o fim da lista de argumentos.
Passo 3
Aplicando esse comportamento ao código: não há fork nem outro processo criado antes de execl. Então, quando a primeira chamada a execl for bem-sucedida ela substitui totalmente o programa atual pelo programa /bin/echo. A partir desse ponto o que passa a rodar é o programa /bin/echo (com os argumentos “echo” e “hello”), e o laço for do programa original jamais continua porque o processo original deixou de existir como tal.
Passo 4
Simulação passo a passo da execução (assumindo que /bin/echo existe e execl tem sucesso):
- Iteração 1 (i = 0): chama-se execl("/bin/echo", “echo”, “hello”, 0).
- execl encontra /bin/echo e substitui a imagem do processo por /bin/echo.
- /bin/echo é executado com argumento “hello” e escreve “hello” (normalmente com newline) uma vez para a saída padrão.
- Quando /bin/echo termina, o processo termina (exit do echo), não retorna ao laço do programa original.
- Portanto não há iteração 2 nem 3 do laço no programa original, porque ele foi substituído na primeira chamada.
Passo 5
Observações e casos especiais (para ficar seguro na prova):
- Caso execl falhe (por exemplo, caminho errado ou permissão negada), execl retorna
e o laço continua; se isso ocorrer em todas as três chamadas, nada será impresso (ou seja, zero vezes). Mas o enunciado fornece “/bin/echo”, caminho padrão que normalmente existe, então o comportamento esperado é sucesso. - /bin/echo imprime a palavra uma vez por execução. Não há redirecionamentos nem pipes no código dado.
- Conclusão prática: com /bin/echo presente e execl bem-sucedido, o programa imprime “hello” apenas uma vez.
Resposta
1 vez