O_CLOEXEC模式和FD_CLOEXEC选项

O_CLOEXEC模式和FD_CLOEXEC选项

  • 调用open函数O_CLOEXEC模式打开的文件描述符在执行exec调用新程序中关闭,且为原子操作。
  • 调用open函数不使用O_CLOEXEC模式打开的文件描述符,然后调用fcntl 函数设置FD_CLOEXEC选项,效果和使用O_CLOEXEC选项open函数相同,但分别调用openfcnt两个函数,不是原子操作,多线程环境中存在竞态条件,故用open函数O_CLOEXEC选项代替之。
  • 调用open函数O_CLOEXEC模式打开的文件描述符,或是使用fcntl设置FD_CLOEXEC选项,这二者得到(处理)的描述符在通过fork调用产生的子进程中均不被关闭。
  • 调用dup族类函数得到的新文件描述符将清除O_CLOEXEC模式。

code:

#include <unistd.h>
#include <sys/types.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>

#define err_sys(fmt, arg...) \
do { \
    printf(fmt, ##arg);\
    printf("\nerrno:%d %s\n", errno, strerror(errno));\
    exit(EXIT_FAILURE);\
} while (0)


int main()
{
    int fd, fd2, val;
    pid_t pid;
#ifdef _O_CLOEXEC
    if ((fd = open("my.txt", O_RDWR | O_CREAT | O_CLOEXEC, 0600)) < 0) 
#else
    if ((fd = open("my.txt", O_RDWR | O_CREAT, 0600)) < 0) 
#endif
        err_sys("open error");

#ifdef _DUP
    if ((fd2 = dup(fd)) < 0)
        err_sys("dup error");
    if (write(fd2, "123", 3) < 0)
        err_sys("write error");
#endif

#ifdef _FCNTL_CLOEXEC
    if ((val = fcntl(fd, F_GETFD)) < 0)
        err_sys("fcntl(F_GETFD) error");

    val |= FD_CLOEXEC;
    if (fcntl(fd, F_SETFD, val) < 0)
        err_sys("fcntl( F_SETFD) error");
#endif

#ifndef _FORK 
    if (execl("/bin/sleep", "sleep", "10000", (void*)0) < 0)
        err_sys("execl error");
#else
 switch ((pid = fork())) {
        case -1:
            err_sys("fork error");
        case 0:
            sleep(10000);
            break;
        default:
            sleep(10000);
            break;
    }
#endif

    return 0;
}

通过宏_O_CLOEXEC编译进O_CLOEXEC选项
gcc -D_O_CLOEXEC -o cloexec cloexec.c
执行程序
./cloexec
查看进程和进程资源,注意执行execl后进程名字变为sleep
ps aux|grep sleep
1463068253963
lsof -p 6479
Alt text
可以看出进程资源中没有文件my.txt
不带宏_O_CLOEXEC编译
gcc -o nocloexec cloexec.c
执行程序
./nocloexec
查看进程和进程资源
ps aux|grep sleep
Alt text
lsof -p 6497
Alt text
可以看出进程资源中有文件my.txt
测试fcntl函数可以通过设置编译宏-D_FCNTL_CLOEXEC测试,编译测试过程同上,同理通过开启-D_O_CLOEXEC -D_FORK编译>选项测试使用O_CLOEXEC模式的描述符在子进程中的状态,通过宏-D_DUP编译选项测试dup函数对O_CLOEXEC的影响,编译测试过程略。

  • 3
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值