2016-06-18 81 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都不會指定任何錯誤,因此預計這種情況不會導致錯誤。