进程控制-进程程序替换(exec函数簇)

1.系统调用exec系列
exec功能:将一个新程序装入调用进程的内存空间,来改变调用进程的执行代码,从而形成新进程。
如果exec调用成功,当前进程将被覆盖,然后开始执行新程序,并且不会返回原进程,这样就产生了一个新进程,但是它的进程标识符与调用进程相同。这说明什么?说明exec并没有像fork()一样创建一个与调用进程并发执行的新进程,而是用新进程取代了原来的进程。所以,exec调用成功后,没有任何返回数据。调用失败返回-1;
有六种以exec开头的函数,统称exec函数
头文件:unistd.h
声明:
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 execve(const char *path, char *const argv[], char *const env
p[]);

这些函数原型看起来很容易混淆,但是只要掌握规律就好了。
不带字母p(表⽰path)的exec函数 ,第⼀个参数必须是程序的相对路径或绝对路径,例如
/bin/ls“或”./a.out”,⽽不能 是”ls”或”a.out”。对于带字母p的函数,如果参数中包含/,则将其视为路径名。否则视为不带路径的程序名,在PATH环境变量的⽬录列表中搜索这个程序。
带有字母l(表⽰list)的exec函数,要求将新程序的每个命令⾏参数都当作⼀个参数传给它,命令⾏ 参数的个数是可变的,因此函数原型中有…,…中的最后⼀个可变参数应该是NULL, 起sentinel的作⽤。
带有字母v(表⽰vector)的函数,则应该先构造⼀个指向各参数的指针数 组,然后将该数组的⾸地址当作参数传给它,数组中的最后⼀个指针也应该是NULL,就像main函数 的argv参数或者环境变量表⼀样。
对于以e(表⽰environment)结尾的exec函数,可以把⼀份新的环境变量表传给它,其他exec函数仍使⽤当前的环境变量表执⾏新程序。
运用实例:

char *const ps_argv[] ={"ps", "-o", "pid,ppid,pgrp,session,tpgid,comm", NULL};
char *const ps_envp[] ={"PATH=/bin:/usr/bin", "TERM=console", NULL}; execl("/bin/
ps", "ps", "-o", "pid,ppid,pgrp,session,tpgid,comm", NULL);
execv("/bin/ps", ps_argv);
execle("/bin/ps", "ps", "-o", "pid,ppid,pgrp,session,tpgid,comm", NULL, ps_envp);
execve("/bin/ps", ps_argv, ps_envp);
execlp("ps", "ps", "-o", "pid,ppid,pgrp,session,tpgid,comm", NULL); execvp("ps", ps_argv);

进程控制-进程程序替换(exec函数簇)_第1张图片
2.对exec传送变量的访问
任何被 exec 调用所执行的程序,都可以访问 exec 调用中的参数。这些参数是调用 exec的程序传送给它的。我们可以通过定义程序 main()函数的参数来使用这些参数,方法如下:main( int argc, char* argv[] );
这对于大多数人来说应该是熟悉的,这种方法就是 C 语言程序访问命令行参数的方法。这也显示了 shell 本身就是使用 exec 启动进程的。
实例:
test.c中,生成一个可执行文件为test

#include 
main(int argc,char* argv[])
{
while(--argc>0)
{
    printf("%s ",*(++argv));
    printf("\n");]
    }
}

fun.c中

#include
#include
int main()
{
    char* argin[]={"./test", "hello", "world", NULL};
    execvp(argin[0],argin);
    exit(1);
}

执行fun后会打印出来
hello
world

你可能感兴趣的:(初入Linux,exec函数簇,进程程序替换)