fcntl与close-on-exec、execl
fcntl与close-on-exec
fcntl系统调用是控制文件描述符属性的通用POSIX(POSIX是一种通用的规范)方法。
//头文件:
#include <unistd.h>
#include <fcntl.h>
//定义函数:
int fcntl(int fd, int cmd);
int fcntl(int fd, int cmd, long arg);
int fcntl(int fd, int cmd, struct flock * lock);
fd:文件描述符
cmd:对fd的操作,具体内容请参考:链接2
close-on-exec:子进程默认会继承父进程的所有文件描述符,但是如果某个文件描述符设置了close-on-exec,那么从父进程中继承得到的文件描述符会在子进程(fork生成子进程)中被关闭。实例如下:
#include <unistd.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
int main()
{
int pipefd[2];
if (pipe(pipefd) == -1) {
perror("pipe");
exit(EXIT_FAILURE);
}
// 将管道的写端标记为 close-on-exec
if (fcntl(pipefd[1], F_SETFD, FD_CLOEXEC) == -1) {
perror("fcntl");
exit(EXIT_FAILURE);
}
pid_t pid = fork();
if (pid == -1) {
perror("fork");
exit(EXIT_FAILURE);
}
if (pid == 0) {
// 子进程
close(pipefd[0]);
// ...
exit(EXIT_SUCCESS);
} else {
// 父进程
close(pipefd[1]);
// ...
exit(EXIT_SUCCESS);
}
}
在 fork() 调用后,子进程会继承 pipefd[1] 这个文件描述符,但由于它已经被标记为 close-on-exec,子进程在执行任何操作之前就会将它关闭。
execl函数
execl函数:在代码中调用其他可执行程序,验证程序如下:
// test2.cpp
#include<iostream>
using namespace std;
int main(){
cout<< "这是测试程序!" << endl;
return 0;
}
生成可执行文件test2:
g++ test2.cpp -o test2
// test.cpp
#include <unistd.h>
#include <fcntl.h>
#include <stdio.h>
#include <sys/types.h>
#include <string.h>
int main(int argc, char *argv[])
{
// execl函数
// int execl(const char *pathname, const char *arg, ...
// pathname: 要执行的文件的路径(推荐使用绝对路径)
// 接下来的参数代表执行该文件时传递过去的argv[0], argv[1], ..., 最后一个参数必须用空指针(NULL)作结束.
// argv[0]是程序名称,argv[1],...为程序后面所需要跟着的参数
if (fork() > 0)
{
printf("I'm parent process: pid: %d\n", getpid());
sleep(1);
}
else
{
execl("./test2", "test2", NULL); // 调用上面我们生成的可执行文件test2
// execl("/bin/ps", "ps", "a", "u", "x", NULL); // 调用系统中的可执行文件
printf("I'm child process: %d", getpid());
}
for (int i = 0; i < 3; i++)
{
printf("i=%d, pid: %d\n", i, getpid());
}
}
输出:
I'm parent process: pid: 25554
这是测试程序!
i=0, pid: 25554
i=1, pid: 25554
i=2, pid: 25554
execl函数是没有返回值的,因为从调用该函数开始,用户区就被调用的二进制程序给替换掉了,已经不再受我们控制。所以可以看到在程序运行时,printf("I'm child process: %d", getpid())
并没有执行
参考:链接1