C 語言中的 execvp 函式
Jinku Hu
2023年10月12日
本文將演示如何在 C 語言中使用 execvp
函式的多種方法。
在 C 語言中使用 execvp
函式替換程序映像
在基於 Unix 的系統中,有兩個獨立的系統呼叫來建立一個新的程序和將新的程式程式碼載入到一個正在執行的程序中。後者使用 exec
系列庫函式來完成,這些函式只是 execve
系統呼叫的不同介面。有 6 種不同的函式原型。execlp
、execle
、execv
、execvp
和 execvpe
。這些函式以一個檔名或一個新程式檔案的路徑名作為第一個引數來載入和執行。execvp
也接受一個程式引數陣列作為第二個引數。
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main(void) {
const char *args[] = {"vim", "/home/ben/tmp3.txt", NULL};
execvp("vim", args);
exit(EXIT_SUCCESS);
}
正確處理 execvp
函式呼叫錯誤方案和相應的輸出訊息
需要注意的是,exec
系列函式只有在發生錯誤時才會返回,所以要實現錯誤檢查例程,並根據需要處理相應的程式碼路徑。
其中 execvp
在失敗時返回 -1
,而且它還會設定 errno
變數。不過要注意,errno
應該在函式呼叫前明確設定為 0,只有在給定的呼叫返回後才檢查該值。execvp
函式可以接受沒有斜線的檔名,這意味著檔案是在 PATH
環境變數指定的目錄中搜尋的。
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main(void) {
const char *args[] = {"vim", "/home/ben/tmp3.txt", NULL};
errno = 0;
if (execvp("vim", args) == -1) {
if (errno == EACCES)
printf("[ERROR] permission is denied for a file\n");
else
perror("execvp");
exit(EXIT_FAILURE);
}
exit(EXIT_SUCCESS);
}
在 C 語言中使用 execvp
與 fork
函式建立一個子程序並執行不同的程式
另外,假設使用者需要建立一個新的程序,並執行給定的程式程式碼,那麼在這種情況下,我們可以利用 fork
函式呼叫與 execvp
相結合。在這種情況下,我們可以利用 fork
函式呼叫與 execvp
相結合。fork
複製呼叫的程序,並建立一個新的程序,稱為-子程序。在下面的例子中,我們實現了一個自定義函式包裝器來建立一個新的程序並載入/執行給定的程式程式碼。請注意,一旦建立了子程序,它就會執行不同的程式碼,而父程序則會等待,直到子程序退出。
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/wait.h>
#include <unistd.h>
pid_t spawnChild(const char* program, char** arg_list) {
pid_t ch_pid = fork();
if (ch_pid == -1) {
perror("fork");
exit(EXIT_FAILURE);
}
if (ch_pid > 0) {
printf("spawn child with pid - %d\n", ch_pid);
return ch_pid;
} else {
execvp(program, arg_list);
perror("execve");
exit(EXIT_FAILURE);
}
}
int main(void) {
const char* args[] = {"vim", "/home/ben/tmp3.txt", NULL};
pid_t child;
int wstatus;
child = spawnChild("vim", args);
if (waitpid(child, &wstatus, WUNTRACED | WCONTINUED) == -1) {
perror("waitpid");
exit(EXIT_FAILURE);
}
exit(EXIT_SUCCESS);
}
作者: Jinku Hu