Как получить флаги открытого fd в C?

Я хочу, чтобы флаги fd были открыты раньше в C.

Но я использую ссылку fcntl(fd,F_GETFD,0) на справочной странице fcntl, она всегда возвращает мне 1.

#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;
}

Он всегда печатает:

fd = 3
flag:1

То, что я думал, это сумма O_RDWR | O_APPEND | O_CREAT


person code_worker    schedule 23.07.2020    source источник
comment
Судя по вашей истории, вы, кажется, не принимаете ответы, которые вам дают. Вы настолько им недовольны? Не большой стимул для сообщества SO.   -  person xhienne    schedule 23.07.2020
comment
@xhienne спасибо за совет, я принимаю ответ, который задавал несколько недель назад.   -  person code_worker    schedule 23.07.2020


Ответы (2)


Вы должны использовать F_GETFL вместо F_GETFD. Также не забудьте печатать в восьмеричном формате для сравнения.

Одна важная вещь заключается в том, что не все флаги возвращаются fcntl. Запоминаются только флаги режима доступа, например O_RDWR. Однако O_CREATE/O_TRUNC и т. д. являются флагами рабочего режима или времени открытия, которые не запоминаются системой и, следовательно, не возвращаются.

Вот ваш модифицированный код

#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;
}

вот вывод вышеуказанного кода

fd = 3
fcntl: Success
flag:102002
flag:2002
person Bhaskar Tallamraju    schedule 23.07.2020
comment
флаг: 102002, что означает первый 1? - person code_worker; 23.07.2020
comment
это O_LARGEFILE. Он может быть установлен по умолчанию. - person Bhaskar Tallamraju; 23.07.2020

F_GETFD не запрашивает открытые флаги, а только FD_CLOEXEC (см. здесь).

Линия

write(fd, "hello c program\n", strlen("hello c program!\n"));

неверно, поскольку вы запрашиваете длину более длинной строки, чем то, что вы пишете, что может привести к переполнению буфера. Более безопасный и эффективный способ сделать это:

static const char str [] = "hello c program!\n";
write(fd, str, sizeof(str)-1);

-1 необходим, чтобы избежать записи завершающего 0 байта.

я не знаю цели

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

но приведение size_t (тип результата sizeof()) к int, вероятно, не очень хорошая идея.

person Erlkoenig    schedule 23.07.2020
comment
Есть ли способ получить флаги открытого fd? Извините за какой-то фиктивный код. - person code_worker; 23.07.2020
comment
Существует F_GETFL. - person Erlkoenig; 23.07.2020