C 語言中的 execvp 函式

Jinku Hu 2023年10月12日
  1. 在 C 語言中使用 execvp 函式替換程序映像
  2. 正確處理 execvp 函式呼叫錯誤方案和相應的輸出訊息
  3. 在 C 語言中使用 execvpfork 函式建立一個子程序並執行不同的程式
C 語言中的 execvp 函式

本文將演示如何在 C 語言中使用 execvp 函式的多種方法。

在 C 語言中使用 execvp 函式替換程序映像

在基於 Unix 的系統中,有兩個獨立的系統呼叫來建立一個新的程序和將新的程式程式碼載入到一個正在執行的程序中。後者使用 exec 系列庫函式來完成,這些函式只是 execve 系統呼叫的不同介面。有 6 種不同的函式原型。execlpexecleexecvexecvpexecvpe。這些函式以一個檔名或一個新程式檔案的路徑名作為第一個引數來載入和執行。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 語言中使用 execvpfork 函式建立一個子程序並執行不同的程式

另外,假設使用者需要建立一個新的程序,並執行給定的程式程式碼,那麼在這種情況下,我們可以利用 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
Jinku Hu avatar Jinku Hu avatar

DelftStack.com 創辦人。Jinku 在機器人和汽車行業工作了8多年。他在自動測試、遠端測試及從耐久性測試中創建報告時磨練了自己的程式設計技能。他擁有電氣/ 電子工程背景,但他也擴展了自己的興趣到嵌入式電子、嵌入式程式設計以及前端和後端程式設計。

LinkedIn Facebook

相關文章 - C Process