execvp
Com execvp, um programa pode iniciar comandos do sistema, como iniciar aplicações ou executar serviços do sistema. Em combinação com a função fork(), também é possível chamar código após execvp.
Como funciona o execvp?
A principal tarefa do execvp é transferir o controlo de um programa para outro sem reiniciar todo o processo. Isso permite alternar facilmente entre diferentes funções ou executar comandos externos com argumentos variáveis. execvp é como um diretor invisível que muda os cenários e salta entre diferentes linhas argumentais.
Graças à execução dinâmica de processos, é possível ajustar o caminho para o programa e até mesmo os seus argumentos durante a execução. A função execvp() é utilizada em chamadas ao sistema que requerem tarefas complexas, como a execução de scripts, comandos do sistema, pipelining e redirecionamentos. Além disso, contribui significativamente para aumentar a flexibilidade dos programas em C.
A sintaxe básica do execvp
A sintaxe de execvp requer o caminho do ficheiro ou o nome do programa a ser executado e uma matriz de cadeias que contenha os argumentos para esse programa.
#include <unistd.h>
int execvp(const char *command, char* argv[]);cconst char *command: esta é a rota do ficheiro ou o nome do programa respetivo. Pode ser uma rota absoluta ou relativa. Quando se usa uma rota relativa,execvpprocura o ficheiro no sistema PATH.char *argv[]: conjunto de cadeias de caracteres que contém os argumentos para o programa a ser executado; o conjunto deve terminar com um ponteiroNULLpara indicar o fim da lista de argumentos. O primeiro elemento emargvé geralmente o nome do próprio programa, seguido dos argumentos.
As funções execvp e outras funções da família exec são específicas dos sistemas operativos baseados em Unix. A instrução #include <unistd.h> é um ficheiro de cabeçalho na programação em C. Contém definições e declarações de funções que interagem com o sistema operativo baseado em Unix e o controlo de processos. Irá encontrar este ficheiro frequentemente ao aprender C.
A aplicação prática de execvp
No programa C presente, usamos a função execvp do ficheiro de cabeçalho unistd.h para iniciar o programa externo ls com os argumentos -l e /usr/bin. A matriz args representa os argumentos do programa. Se a função execvp() for bem-sucedida, o processo atual será substituído pelo programa externo e as linhas seguintes serão ignoradas. Em caso de erro, uma mensagem de erro será exibida através de perror, e o programa retornará o código de estado 1.
#include <unistd.h>
int main() {
char *args[] = {"ls", "-l", "/usr/bin", NULL};
execvp("ls", args);
perror("execvp");
return 1;
}cCom fork(), também pode chamar instruções após execvp(). A função fork() cria um novo processo. Isto significa que o código continuará a ser executado no processo pai, enquanto o novo processo iniciará o programa externo.
#include <stdio.h>
#include <unistd.h>
#include <sys/wait.h>
int main() {
char* command = "ls";
char *args[] = {"ls", "-l", "/usr/bin", NULL};
printf("Before calling execvp()\n");
pid_t child_pid = fork();
if (child_pid == -1) {
// Error creating the process
perror("fork");
return 1;
}
if (child_pid == 0) {
// Code executed in the child process
// Call execvp in the child process to execute "ls" with the specified arguments
int status_code = execvp(command, args);
// This line is reached if execvp encounters an error
perror("execvp");
// Print statement after execvp
printf("ls -l /usr/bin has taken control of this child process. If this is printed, execvp encountered
an error.\n");
// Error handling in the child process
return 1;
} else {
// Code executed in the parent process
// Wait for the completion of the child process
waitpid(child_pid, NULL, 0);
printf("The child process has completed its execution.\n");
}
return 0;
}cA função execvp() faz com que o processo filho assuma o controlo com ls e os seus argumentos. Enquanto isso, o processo pai aguarda a conclusão do processo filho com waitpid e, em seguida, exibe a mensagem.