全部学习汇总: https://github.com/GreyZhang/little_bits_of_linux
说起exec,其实不是一个函数,而是一个函数族。我参考了一下网络上的文章简单学习了一下,顺便敲了两行代码测试了其中的两个函数。
exec函数族包括6个函数:
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 envp[]);
其实,看上面的命名方式很容易把上面的函数分为两组。前面的3个函数是逐个参数传入的方式,而后面的3个函数,有点类似main函数的参数传递方式,传入的参数可以作为一个数组传入。我没有去查为什么这么命名,但是我觉得v的意思可能是vector。
两组函数中,以e结尾的主要是用于错误处理的。如果出错了可以去查看错误的原因。不考虑错误的话,这样典型的两个函数就是前两个。第一个,需要指明执行命令的具体目录,第二个则是从环境变量PATH中寻找。另外一组的函数名称以及功能也是类似的。
接下来,看一下我自己的测试代码。首先,我自己定义了一个命令print_a_string。
函数编译后测试的效果:
接下来,设计exec的测试代码:
编译后的运行效果:
有时候,运行效果会不同:
其实也很容易理解,具体的原因在fork函数学习的时候已经知道了。几个创建的任务其实执行先后有一定的不确定性。
exec虽然可以用来让fork的子进程与父进程运行不同的程序,但是其实这个函数并不是跟fork函数绑定在一起的,可以独立使用。另外一点,如果运行了一个程序,其实相应的功能继承子进程的PID。再一点,这些函数运行成功则不返回,否则返回-1。先大概了解这么多,不是很详细,但是算是对这个开发的套路有了一点点了解了。我只是想在深入理解linux内核设计之前,增补更多的常识概念,暂且看这么多。