深入解析linuxexec()

一、linuxexec函數族

在Linux系統開發中,exec()函數族用於將當前進程的代碼替換為新的代碼,並且將原有進程的執行上下文傳遞給新的代碼。

exec()函數族中一共包含六個函數:

#include <unistd.h>

int execl(const char *pathname, const char *arg, ...);
int execlp(const char *file, const char *arg, ...);
int execle(const char *pathname, const char *arg, ..., char * const envp[]);
int execv(const char *pathname, char *const argv[]);
int execvp(const char *file, char *const argv[]);
int execve(const char *filename, char *const argv[], char *const envp[]);

這些函數實現的功能類似,但參數不同且各自具有特殊的用途。下面分別進行詳細的介紹。

二、linux exec命令

除了exec()函數族外,Linux還提供了與之對應的命令:execl、execlp、execle、execv、execvp、execve。用戶可以直接在終端上使用這些命令來替換進程代碼。

Linux exec命令的語法格式如下:

execl(pathname, arg0, arg1, ..., argn, (char *)0);

execlp(file, arg0, arg1, ..., argn, (char *)0);

execle(pathname, arg0, arg1, ..., argn, envp, (char *)0);

execv(pathname, argv);

execvp(file, argv);

execve(filename, argv, envp);

其中,pathname和file表示要執行的程序路徑;arg0到argn表示程序的命令行參數;envp表示程序的環境變量,是一個字符串數組。

需要注意的是,參數列表中必須以NULL結尾,否則會出現未知錯誤。

三、linux文件描述符

進程在Linux中與外部環境進行通信,都是通過文件描述符進行的。每個進程都有自己的一組文件描述符,其值是非負整數。

文件描述符可以是以下三種類型之一:

  • 標準輸入 STDIN_FILENO (值為0)
  • 標準輸出 STDOUT_FILENO (值為1)
  • 標準錯誤 STDERR_FILENO (值為2)

除了標準輸入、輸出、錯誤之外,每個進程還有其他的文件描述符。這些描述符可以表示打開的文件、管道、網絡套接字等資源。

四、與linuxexec相關的系統調用

1. pipe()

pipe()系統調用用於創建父子進程共享的管道。管道實際上是一組文件描述符,它們連接兩個進程的輸出和輸入。

#include <unistd.h>

int pipe(int fd[2]);

參數fd是一個二元數組,調用成功後fd[0]表示管道的讀端文件描述符,fd[1]表示管道的寫端文件描述符。需要注意的是,fd[0]和fd[1]不能交換順序。

2. fork()

fork()系統調用用於創建一個新進程,新進程與原始進程相同,但具有不同的PID、內存空間和其他狀態。

#include <unistd.h>

pid_t fork(void);

調用fork()後,將會返回兩次,一次在父進程中,一次在子進程中。父進程將返回子進程的PID,子進程將返回0。

3. dup2()

dup2()系統調用用於複製文件描述符,並將其賦值給指定的文件描述符。

#include <unistd.h>

int dup2(int oldfd, int newfd);

參數oldfd是要複製的文件描述符,newfd是將要賦予複製後的文件描述符。

4. wait()

wait()系統調用用於等待任意子進程退出,並返回該子進程的PID和退出狀態。

#include <sys/types.h>
#include <sys/wait.h>

pid_t wait(int *status);

如果沒有任何子進程退出,則當前進程將被掛起,直到有子進程退出。

五、完整代碼示例

#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/wait.h>

int main(int argc, char **argv) {
    int fd[2], status;
    pid_t pid;

    if (pipe(fd) == -1) {
        perror("pipe()");
        return -1;
    }

    pid = fork();
    if (pid == -1) {
        perror("fork()");
        return -1;
    }
    else if (pid == 0) {
        close(fd[0]);
        dup2(fd[1], STDOUT_FILENO);
        execlp("ls", "ls", "/", (char *)0);
        close(fd[1]);
        exit(0);
    }

    close(fd[1]);
    dup2(fd[0], STDIN_FILENO);
    execlp("grep", "grep", "bin", (char *)0);
    close(fd[0]);

    wait(&status);
    return 0;
}

代碼說明:

以上代碼實現了將ls命令的結果通過管道傳遞給grep命令進行過濾的功能。具體實現步驟如下:

  1. 創建一個管道,用於將ls的輸出傳遞給grep。
  2. 調用fork()創建一個子進程。
  3. 在子進程中,將標準輸出重定向到管道的寫端,調用execlp()執行ls命令。
  4. 在父進程中,將標準輸入重定向到管道的讀端,調用execlp()執行grep命令。
  5. 調用wait()等待子進程退出。

原創文章,作者:LDKV,如若轉載,請註明出處:https://www.506064.com/zh-hk/n/149860.html

(0)
打賞 微信掃一掃 微信掃一掃 支付寶掃一掃 支付寶掃一掃
LDKV的頭像LDKV
上一篇 2024-11-05 16:54
下一篇 2024-11-05 16:54

相關推薦

  • 深入解析Vue3 defineExpose

    Vue 3在開發過程中引入了新的API `defineExpose`。在以前的版本中,我們經常使用 `$attrs` 和` $listeners` 實現父組件與子組件之間的通信,但…

    編程 2025-04-25
  • 深入理解byte轉int

    一、位元組與比特 在討論byte轉int之前,我們需要了解位元組和比特的概念。位元組是計算機存儲單位的一種,通常表示8個比特(bit),即1位元組=8比特。比特是計算機中最小的數據單位,是…

    編程 2025-04-25
  • 深入理解Flutter StreamBuilder

    一、什麼是Flutter StreamBuilder? Flutter StreamBuilder是Flutter框架中的一個內置小部件,它可以監測數據流(Stream)中數據的變…

    編程 2025-04-25
  • 深入探討OpenCV版本

    OpenCV是一個用於計算機視覺應用程序的開源庫。它是由英特爾公司創建的,現已由Willow Garage管理。OpenCV旨在提供一個易於使用的計算機視覺和機器學習基礎架構,以實…

    編程 2025-04-25
  • 深入了解scala-maven-plugin

    一、簡介 Scala-maven-plugin 是一個創造和管理 Scala 項目的maven插件,它可以自動生成基本項目結構、依賴配置、Scala文件等。使用它可以使我們專註於代…

    編程 2025-04-25
  • 深入了解LaTeX的腳註(latexfootnote)

    一、基本介紹 LaTeX作為一種排版軟件,具有各種各樣的功能,其中腳註(footnote)是一個十分重要的功能之一。在LaTeX中,腳註是用命令latexfootnote來實現的。…

    編程 2025-04-25
  • 深入剖析MapStruct未生成實現類問題

    一、MapStruct簡介 MapStruct是一個Java bean映射器,它通過註解和代碼生成來在Java bean之間轉換成本類代碼,實現類型安全,簡單而不失靈活。 作為一個…

    編程 2025-04-25
  • 深入了解Python包

    一、包的概念 Python中一個程序就是一個模塊,而一個模塊可以引入另一個模塊,這樣就形成了包。包就是有多個模塊組成的一個大模塊,也可以看做是一個文件夾。包可以有效地組織代碼和數據…

    編程 2025-04-25
  • 深入探討馮諾依曼原理

    一、原理概述 馮諾依曼原理,又稱「存儲程序控制原理」,是指計算機的程序和數據都存儲在同一個存儲器中,並且通過一個統一的總線來傳輸數據。這個原理的提出,是計算機科學發展中的重大進展,…

    編程 2025-04-25
  • 深入理解Python字符串r

    一、r字符串的基本概念 r字符串(raw字符串)是指在Python中,以字母r為前綴的字符串。r字符串中的反斜杠(\)不會被轉義,而是被當作普通字符處理,這使得r字符串可以非常方便…

    編程 2025-04-25

發表回復

登錄後才能評論