#include
int execl(const char *path, const char *arg0, ..., (char *)NULL);
int execlp(const char *file, const char *arg0, ..., (char *)NULL);
int execle(const char *path, const char *arg0, ..., (char *)NULL, char *const envp[]);
int execv(const char *path, char *const argv[]);
int execvp(const char *file, char *const argv[]);
int execvpe(const char *file, char *const argv[], char *const envp[]);
int execve(const char *path, char *const argv[], char *const envp[]); // 系統調用入口
main() 開始執行;失敗返回 -1 (errno 指示錯誤),原程序繼續執行。
#include
#include
int main() {
printf("Before execl, PID=%d\n", getpid());
// execl(path, arg0, arg1, ..., NULL)
// arg0 習慣為程序名,實際由 argv[0] 接收
if (execl("/bin/ls", "ls", "-l", "/etc/passwd", (char *)NULL) < 0) {
perror("execl failed");
}
// 此行僅在 execl 失敗時執行
printf("This line only prints if execl fails\n");
return 0;
}
輸出:直接顯示 ls -l /etc/passwd 結果,無 "This line..." 輸出,證明進程已被替換。
// file_creat.c (被調用程序)
#include
#include
#include
void create_file(char *filename) {
if (creat(filename, 0666) < 0) {
perror("create file failed");
exit(EXIT_FAILURE);
}
printf("File %s created successfully\n", filename);
}
int main(int argc, char *argv[]) {
if (argc < 2) {
fprintf(stderr, "Usage: %s \n", argv[0]);
exit(EXIT_FAILURE);
}
create_file(argv[1]);
return 0;
}
// execl_test.c (主程序)
#include
#include
#include
int main(int argc, char *argv[]) {
if (argc < 2) {
fprintf(stderr, "Usage: %s \n", argv[0]);
exit(EXIT_FAILURE);
}
// 執行 ./file_creat filename
if (execl("./file_creat", "file_creat", argv[1], (char *)NULL) < 0) {
perror("execl error");
}
return 0;
}
編譯運行:
gcc file_creat.c -o file_creat
gcc execl_test.c -o execl_test
./execl_test testfile.txt
# 輸出: File testfile.txt created successfully
| 錯誤 | 後果 | 修正 |
|---|---|---|
| 參數列表未以 NULL 結尾 | 棧溢出、未定義行為 | 務必以 (char *)NULL 結尾 |
| arg0 與程序名不一致 | 程序內 argv[0] 顯示異常,影響日志/用法提示 | arg0 設為程序名 (不含路徑) |
| execl 後有代碼預期執行 | 邏輯錯誤,exec 成功不返回 | 需 fork() 創建子進程再 exec,父進程 wait() |
| 環境變量未傳遞 (execle/execvpe) | 子進程環境異常 | 顯式構造 envp[] 或使用 execvp 繼承當前 environ |
pid_t pid = fork();
if (pid < 0) { perror("fork"); exit(1); }
if (pid == 0) { // 子進程
execlp("myprogram", "myprogram", "arg1", "arg2", (char *)NULL);
perror("execlp failed"); // 僅執行失敗時到達
_exit(127); // 子進程異常退出碼
} else { // 父進程
int status;
waitpid(pid, &status, 0);
if (WIFEXITED(status))
printf("Child exited with %d\n", WEXITSTATUS(status));
}