UNIX环境高级编程fcntl和dup

来源:互联网 发布:淘宝上买车保险便宜吗 编辑:程序博客网 时间:2024/06/06 03:59

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>intmain(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>voidset_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 0
原创粉丝点击