2016-06-18 4 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; 
} 

のみ設定可能フラグがFD_CLOEXECあるように見えます

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 

です。 (奇妙なこと:すべてのセットコールはを返します。)。

そしてかなりのカーネルはF_SETFDに引数を無視するように、それは私になります

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

ここで何が起こっていますか?何か不足していますか?

答えて

2

F_SETFDの唯一の有効なフラグは、FD_CLOEXECです。あなたが使用する他のすべてはF_SETFLです。 F_SETFDに存在しないフラグの値が渡された場合、LinuxでもPOSIXもエラーを指定しないため、このような状況ではエラーは発生しません。

関連する問題