UNIX环境高级编程fcntl和dup

fcntl函数简介

#include<unistd.h>
#include<fcntl.h>

int fcntl(int fd, int cmd, ... /* arg */ );

//改变打开文件的属性
/*
作用:
(1) 复制一个已有的描述符`cmd = F_DUPFD 或者 F_DUPFD_CLOEXEC`
(2) 获取/设置文件描述符标志`cmd=F_GETFD或F_SETFD`
(3) 获取/设置文件状态标志`cmd=F_GETFL或F_SETFL`
(4) 获取/设置异步I/O所有权`cmd=F_GETOWN或F_SETOWN`
(5) 获取/设置记录锁`cmd=F_GETLK、F_SETLK或F_SETLKW`
*/

文件状态标志

文件状态标志说明
O_RDONLY只读
O_WRONLY只写
O_RDWR读、写
O_EXEC只执行
O_SEARCH只搜索打开目录
O_APPEND追加
O_NONBLOCK非阻塞
O_SYNC等待写完成
O_DSYNC等待写完成
O_RSYNC同步读和写
O_FSYNC等待写完成
O_ASYNC异步I/O

获取文件状态标志

#include "apue.h"
#include <fcntl.h>

int
main(int argc, char *argv[])
{
    int     val;

    if (argc != 2)
        err_quit("usage: a.out <descriptor#>");

    if ((val = fcntl(atoi(argv[1]), F_GETFL, 0)) < 0)
        err_sys("fcntl error for fd %d", atoi(argv[1]));

    switch (val & O_ACCMODE) {
    case O_RDONLY:
        printf("read only");
        break;

    case O_WRONLY:
        printf("write only");
        break;

    case O_RDWR:
        printf("read write");
        break;

    default:
        err_dump("unknown access mode");
    }

    if (val & O_APPEND)
        printf(", append");
    if (val & O_NONBLOCK)
        printf(", nonblocking");
    if (val & O_SYNC)
        printf(", synchronous writes");

#if !defined(_POSIX_C_SOURCE) && defined(O_FSYNC) && (O_FSYNC != O_SYNC)
    if (val & O_FSYNC)
        printf(", synchronous writes");
#endif

    putchar('\n');
    exit(0);
}

设置文件状态标志

先调用fcntl获取文件状态标志,再或等于需要设置的flag以免关闭以前设置的标志位

#include "apue.h"
#include <fcntl.h>

void
set_fl(int fd, int flags) /* flags are file status flags to turn on */
{
    int     val;

    if ((val = fcntl(fd, F_GETFL, 0)) < 0)
        err_sys("fcntl F_GETFL error");

    val |= flags;       /* turn on flags */

    if (fcntl(fd, F_SETFL, val) < 0)
        err_sys("fcntl F_SETFL error");
}

dup函数

dup函数,主要是

#include <unistd.h>

int dup(int oldfd);
int dup2(int oldfd, int newfd);

拷贝描述符,cgi程序中经常使用dup2的供父子进程进行通信。

//子进程中
dup2(cgi_output[1], 1);
dup2(cgi_input[0], 0);
close(cgi_output[0]);
close(cgi_input[1]);

简单解释一下:
cgi_output 和cgi_input是两个管道0-对应管道读 1对应管道写
而我们知道linux系统默认的描述符0,1,2分别表示读、写、错误
dup2可以用下述原子操作替代:

close(1);
fcntl(cgi_output[1],F_DUPFD,1)

也就是说写入到标准输出的内容会被重定向到管道,这样父进程就可以通过cgi_output[0]读入CGI程序的输出了,这样就解释了,为啥CGI程序中有大量的print语句。
同理,从管道读取的内容也将作为CGI 程序的标准输入,父进程通过写管道的方式传给CGI程序参数。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值