clinuxfcntl

How to get flags of opened fd in C?


I want to get flags of fd was opened before in C.

But I use fcntl(fd,F_GETFD,0) reference by fcntl man page, it always return 1 to me.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>

#define XSZ(x) (int)(sizeof(x)*2)

int main()
{
    int ret;
    static const char str [] = "hello c program!\n";
    int fd = open("test.txt", O_RDWR | O_APPEND | O_CREAT, 0777);
    if(fd < 0)
    {
        perror("open");
        return -1;
    }
    printf("fd = %d\n", fd);

    ret = fcntl(fd, F_GETFD, 0);
    printf("flag:%d\n",ret);
    write(fd, str, strlen(str)-1);

    return 0;
}

It always print:

fd = 3
flag:1

What I thought the ret is the sum of O_RDWR | O_APPEND | O_CREAT


Solution

  • You should use F_GETFL instead of F_GETFD. Also remember to print in octal to compare.

    One important thing is not all flags are returned by fcntl. Only the access mode flags are remembered, like O_RDWR. However O_CREATE/O_TRUNC etc. are operating mode or open-time flags which are not remembered by the system and hence not returned.

    Here is your modified code

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <unistd.h>
    #include <fcntl.h>
    
    #define XSZ(x) (int)(sizeof(x)*2)
    
    int main()
    {
        int ret;
        int fd = open("test.txt", O_RDWR | O_APPEND | O_CREAT, 0777);
        if(fd < 0)
        {
            perror("open");
            return -1;
        }
        printf("fd = %d\n", fd);
        ret = fcntl(fd, F_GETFL);
        perror("fcntl");
        printf("flag:%o\n",ret);
        printf("flag:%o\n",O_RDWR|O_APPEND);
        write(fd, "hello c program\n", strlen("hello c program!\n"));
    
        return 0;
    }
    

    here is the output of the above code

    fd = 3
    fcntl: Success
    flag:102002
    flag:2002