linuxプロセス---execファミリー関数(execl,execlp,execle,execv,execvp,execvpe)


execファミリー関数の役割:
fork関数で新しいプロセスを作成すると、新しいプロセスでexec関数を呼び出して別のプログラムを実行することがよくあります.プロセスがexec関数を呼び出すと、プロセスは完全に新しいプログラムに置き換えられます.exec関数を呼び出すと新しいプロセスは作成されないため、前後のプロセスのIDは変更されません.
execファミリー関数定義:
このWebサイトでクエリーできます:linux関数クエリー機能:呼び出しプロセス内で実行可能ファイルを実行します.実行可能ファイルは、バイナリファイルであってもよいし、Linuxで実行可能なスクリプトファイルであってもよい.関数ファミリー:exec関数ファミリーは、execl、execlp、execle、execv、execvp、execvpe関数のプロトタイプです.
#include 
extern char **environ;

int execl(const char *path, const char *arg, ...);
int execlp(const char *file, const char *arg, ...);
int execle(const char *path, const char *arg,..., 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[]);

戻り値:exec関数ファミリーの関数が正常に実行された後は戻りません.呼び出しに失敗した場合、errnoを設定して-1を返し、元のプログラムの呼び出し点から下へ実行します.パラメータ説明:path:実行可能ファイルのパス名arg:実行可能プログラムが持つパラメータ、最初のパラメータは実行可能ファイル名であり、パスがなく、argはNULLでfileを終了しなければならない:パラメータfileに/が含まれている場合はパス名と見なし、そうでない場合はPATH環境変数で指定した各ディレクトリで実行可能ファイルを検索する.
execファミリー関数パラメータは記憶と分解が極めて難しく、関数名の文字は私たちにいくつかの助けを与えます:l:パラメータリストpを使用する:ファイル名を使用して、PATH環境から実行可能なファイルvを探します:まず各パラメータを指すポインタ配列を構築して、それからこの配列のアドレスをこれらの関数のパラメータとします.e:envp[]配列が多くなり、呼び出しプロセスの環境変数の代わりに新しい環境変数を使用
次にexac関数をバンドl,バンドp,バンドv,バンドeの4種類に分類してパラメータの特徴を説明する.
一、l付きのexac関数(lはlistを表す)のクラスで、execl、execlp、execleを含む.新しいプログラムの各コマンドラインパラメータを個別のパラメータとして説明する必要がある.このパラメータテーブルは空のポインタで終わります.execl関数を例に説明します.
//  execl.c
#include 
#include 
#include 
//    :int execl(const char *path, const char *arg, ...);

int main(void)
{
    printf("before execl
"
); if(execl("./bin/echoarg","echoarg","abc",NULL) == -1) { printf("execl failed!
"
); } printf("after execl
"
); return 0; }
//  echoarg.c
#include 

int main(int argc,char *argv[])
{
    int i = 0;
    for(i = 0; i < argc; i++)
    {
        printf("argv[%d]: %s
"
,i,argv[i]); } return 0; }

実験結果:
ubuntu:~/test/exec_test$ ./execl
before execl****
argv[0]: echoarg
argv[1]: abc

実験説明:まずgccでechoargをコンパイルする.c,実行可能ファイルechoargを生成し,現在のパスbinディレクトリの下に置く.ファイルechoargの役割は、コマンドラインパラメータを印刷することです.次にexeclをコンパイルします.c execl実行可能ファイルを実行します.execlでechoargを見つけて実行し、現在のプロセスmainを置き換えるため、「after execl」は端末に印刷されません.
二、p付きのexac関数の一種で、execlp、execvp、execvpeを含み、パラメータfileに/が含まれている場合はパス名と見なし、そうでない場合はPATH環境変数に従って、指定した各ディレクトリで実行可能ファイルを検索する.例として、PATH=/bin:/usr/bin
//  execl_no_path.c
#include 
#include 
#include 
//    :int execl(const char *path, const char *arg, ...);
int main(void)
{
    printf("before execl****
"
); if(execl("ps","ps","-l",NULL) == -1) { printf("execl failed!
"
); } printf("after execl*****
"
); return 0; }

実験結果:
ubuntu:~/test/exec_test$ gcc execl_no_path.c -o execl_no_path
ubuntu:~/test/exec_test$ ./execl_no_path 
before execl****
execl failed!
after execl*****

上記の例では、パラメータにパスがないため、execlでは実行可能なファイルが見つかりません.次の例を見てみましょう.
//  execlp.c
#include 
#include 
#include 
//    :int execlp(const char *file, const char *arg, ...);
int main(void)
{
    printf("before execlp****
"
); if(execlp("ps","ps","-l",NULL) == -1) { printf("execlp failed!
"
); } printf("after execlp*****
"
); return 0; }

実験結果:
ubuntu:~/test/exec_test$ gcc execlp.c -o execlp
ubuntu:~/test/exec_test$ ./execlp
before execlp****
F S   UID   PID  PPID  C PRI  NI ADDR SZ WCHAN  TTY          TIME CMD
0 R  1048 35976 74920  0  80   0 -  2860 -      pts/4    00:00:00 ps
0 S  1048 74920 74916  0  80   0 -  7579 wait   pts/4    00:00:00 bash

以上の実験結果から,上のexaclp関数はpを持つため,環境変数PATHにより実行可能ファイルpsを見つけることができることが分かった.
三、v付きlなしのexac関数の一種であり、execv、execvp、execveを含む.まず各パラメータを指すポインタ配列を構築し、その後、その配列のアドレスをこれらの関数のパラメータとする.char*arg[]のように、argの最後の要素はNULLでなければなりません.例えば、char*arg[]={"ls"、"-l"、NULL};次にexecvp関数を例に挙げて説明します.
//  execvp.c
#include 
#include 
#include 
//    :int execvp(const char *file, char *const argv[]);

int main(void)
{
    printf("before execlp****
"
); char *argv[] = {"ps","-l",NULL}; if(execvp("ps",argv) == -1) { printf("execvp failed!
"
); } printf("after execlp*****
"
); return 0; }

実験結果:
ubuntu:~/test/exec_test$ gcc execvp.c -o execvp
ubuntu:~/test/exec_test$ ./execvp
before execlp****
F S   UID   PID  PPID  C PRI  NI ADDR SZ WCHAN  TTY          TIME CMD
0 R  1048 63491 74920  0  80   0 -  2860 -      pts/4    00:00:00 ps
0 S  1048 74920 74916  0  80   0 -  7579 wait   pts/4    00:00:00 bash

四、e付きのexac関数の一種で、execle、execvpeを含み、環境文字列のポインタ配列を指すポインタを渡すことができる.パラメータ例char*env_init[] = {“AA=aa”,”BB=bb”,NULL}; バンドeは、この関数がenvp[]配列を取り、現在の環境を使用しないことを示します.次にexecle関数を例に挙げます.
//  execle.c
#include 
#include 
#include 
//    :int execle(const char *path, const char *arg,..., char * const envp[]);

char *env_init[] = {"AA=aa","BB=bb",NULL};
int main(void)
{
    printf("before execle****
"
); if(execle("./bin/echoenv","echoenv",NULL,env_init) == -1) { printf("execle failed!
"
); } printf("after execle*****
"
); return 0; }
//  echoenv.c
#include 
#include 
extern char** environ;
int main(int argc , char *argv[])
{
    int i;
    char **ptr;
    for(ptr = environ;*ptr != 0; ptr++)
        printf("%s
"
,*ptr); return 0; }

実験結果:
ubuntu:~/test/exec_test$ gcc execle.c -o execle
ubuntu:~/test/exec_test$ ./execle
before execle****
AA=aa
BB=bb

まず、echoenvという名前のすべての環境テーブルを表示するプログラムを書きます.c、実行可能ファイルにコンパイルして./binディレクトリの下.次に実行可能ファイルexecleを実行すると、設定した環境変数が確実に転送されていることがわかります.