当使用fork()创建了一个子进程后,通常接着会使用 exec 族函数指定新的程序来覆盖子进程的代码段、数据段、堆和栈。从而让子进程去执行一个新的程序,而不是执行父进程的副本。
=====================================================
exec 族函数中总共有 6 个函数:
上面 5 个函数属于库函数,这些函数都最终调用了下面的 execve 函数,这6个函数中,只有execve 函数属于Linux的系统调用。
出错返回:
- 这些函数在调用成功时不会返回,只有在调用出错时才返回 -1
====================================================
这几个函数的区别(通过函数名来区分):
- 带 l 的(list):意思是命令行参数以 单独参数 形式给出
- 带 v 的(vector):意思是命令行参数以 字符指针数组 的形式给出
- 带 p 的(path):意思是在 PATH 环境变量中搜索给出的文件名,(当然,如果给出文件的路径名也是可以的,只给出文件名的时候会去PATH变量中去寻找)
- 不带 p 的:意思是必须给出完整的可执行文件名
- 带 e 的(environment):意思是给可执行文件传递新的环境变量
- 不带 e 的:意思是不传递环境变量,使用从父进程复制而来的环境变量
=======================================================
当调用 exec 族函数来让新的程序覆盖原来进程的代码段、数据段和堆栈的时候:
- 并不会创建新的进程,所以进程的 进程ID 和父进程ID 仍然保持不变,也就说 父子关系 是不会因为调用 exec 族函数而改变的。
- 子进程中从父进程复制而来的文件描述符默认是不会关闭的,在新程序中仍然是可以使用的。除非调用 fcntl 函数来关闭了close-on-exec标志。
- 打开的目录流是会关闭的,这是由于opendir函数实现的,opendir函数会打开close-on-exec标志。
- 实际用户 ID 是不变的,有效用户ID是根据新的可执行文件来决定的,如果新的可执行文件设置了set-user-id位,那么有效用户ID将被设置成文件的用户ID,否则有效用户ID就维持原来子进程的有效用户ID不变。
时间: 2024-10-04 04:17:50