2016-06-18 125 views
0

我的印象是,fcntl(fd, F_SETFD, flg)flg = fcntl(fd, F_GETFD, flg)可用于设置和获取filedescriptor标志。在Linux中设置FD标志

根据https://community.spiceworks.com/linux/man/2/fcntl,linux应该只支持设置一些fd标志。很公平。但是 判断由输出:

#define _GNU_SOURCE 
#include <unistd.h> 
#include <sys/types.h> 
#include <fcntl.h> 
#include <sys/stat.h> 
#include <unistd.h> 
#include <stdio.h> 
#include <errno.h> 

#define XSZ(x) (int)(sizeof(x)*2) 
int main(int argc, char** argv){ 
    int fd, flg; 
    if ((fd = open("/dev/stdout", O_RDWR)) < 0){ perror("open"); return -errno; } 

    //get 
    if ((flg = fcntl(fd, F_GETFD)) < 0){ perror("setfd"); return -errno; } 
    printf("flg=0x%0*x\n", XSZ(flg), flg); 

#define ADD_FLAG(FLG) \ 
    flg |= FLG;\ 
    printf("setting flg=0x%0*x\n", XSZ(flg), flg);\ 
    if ((flg = fcntl(fd, F_SETFD, flg))){ perror("setfd"); return -errno; }\ 
    if ((flg = fcntl(fd, F_GETFD, flg)) < 0){ perror("getfd"); return -errno; }\ 
    printf("flg=0x%0*x\n\n", XSZ(flg), flg); 

    ADD_FLAG(FD_CLOEXEC); 
    ADD_FLAG(O_APPEND); 
    ADD_FLAG(O_DIRECT); 
    ADD_FLAG(O_ASYNC); 
    ADD_FLAG(O_NOATIME); 

    return 0; 
} 

flg=0x00000000 
setting flg=0x00000001 
flg=0x00000001 

setting flg=0x00000401 
flg=0x00000001 

setting flg=0x00004001 
flg=0x00000001 

setting flg=0x00002001 
flg=0x00000001 

setting flg=0x00040001 
flg=0x00000001 

它看起来像只设置的标志是FD_CLOEXEC。 (奇怪的事情:所有设定的电话都会成功返回)。

它看起来对我来说,内核几乎忽略的参数F_SETFD

https://github.com/torvalds/linux/blob/master/fs/fcntl.c#L259

这是怎么回事?我错过了什么吗?

回答

2

F_SETFD的唯一有效标志是FD_CLOEXEC;所有其他人使用的是F_SETFL。当F_SETFD传递任何不存在的标志值时,Linux和POSIX都不会指定任何错误,因此预计这种情况不会导致错误。