C言語システムコール-execve

execve

概要

execveは引数に指定したプログラム及びスクリプトを実行します。


execveは実行すると、呼び出し元プロセスが新しいプログラムを読み込んで置き換わります。

そのためexecveの実行が成功した場合、呼び出し元のプログラムに処理が戻りません。

execveからリターンするのはエラーが発生した場合のみとなります。


execveを使用する場合には、まずforkで子プロセスを生成して、その子プロセス上でexecveを呼び出す方式が一般的です。

forkせずにexecveを呼び出すと、コマンドが実行終了となります。


execveではPATH環境変数が自動的には参照されません。

実行するプログラムの絶対パスまたは相対パスを明示的に指定する必要があります。


実効ユーザについて

execveではセットユーザIDの実行バイナリを実行すると、実効ユーザIDに「実行バイナリの所有者ID」が設定されます。

実ユーザIDは変更しません。


execファミリーについて

Cライブラリ関数にはexecveを呼び出す関数が用意されています。

環境件数の継承を自動で行うか、プログラマが明示するかという差異があります。

また、呼び出すコマンドを参照するためのPATH環境変数を自動で参照するかどうかという差異もあります。

  • execl
  • execlp
  • execle
  • execv
  • execvp

サンプルプログラム

環境変数の指定としてグローバル変数の「environ」を使用しています。


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

static void
child_process(void)
{
    char *argv[3];
    extern char **environ;

    argv[0] = "echo";
    argv[1] = "child_process";
    argv[2] = NULL;

    execve("/bin/echo", argv, environ);
    printf("Error: execve(%d) %s\n", errno, strerror(errno));
}

int
main(void)
{
    pid_t pid = 0;

    pid = fork();
    if(pid < 0){
        printf("Error: fork(%d) %s\n", errno, strerror(errno));
        return(-1);
    }
    if(pid == 0){
        child_process();
        _exit(-1);
    }
    printf("parent process\n");

    return(0);
}

関連ページ