Вопрос

int fcntl(int fd, int command, ... /* arg */ );

Является ли это портативным: flags = fcntl(fd, F_GETFL); (примечание:НЕТ arg)?

И то, и другое Linux и FreeBSD справочные страницы говорят, что arg игнорируется:

F_GETFL (void)
    Get the file access mode and the file status flags; arg
    is ignored.

void в документации Linux это означает, что arg не требуется.

Вот такой пример использования из POSIX для связанного F_GETFD Отметить:

#include <unistd.h>
#include <fcntl.h>
...
    int flags;


    flags = fcntl(fd, F_GETFD);
    if (flags == -1)
        /* Handle error */;
    flags |= FD_CLOEXEC;
    if (fcntl(fd, F_SETFD, flags) == -1)
        /* Handle error */;"

Это показывает , что arg не требуется для F_GETFD (сегодня).Затем он говорит:

Значения аргументов для F_GETFD, F_SETFD, F_GETFL и F_SETFL представляют собой значения флагов для обеспечения будущего роста.

Подразумевает ли это , что F_GETFL мог бы использовать arg в будущем?

Быстрый поиск "F_GETFL" в коде Ohloh создает впечатление, что большинство проектов с открытым исходным кодом действительно проходят arg(обычно 0, иногда NULL, или даже (сломанный?) &fl).Я не понимаю, почему fcntl(fd, F_GETFL, 0) является предпочтительной формой. @Вумпус В.Вамбли предлагает что это может быть вызвано книга "Расширенное программирование в среде UNIX" это также использует fcntl(fd, F_GETFL, 0) форма.

Существует ли система / компилятор, для которого требуется 3-й аргумент: flags = fcntl(fd, F_GETFL, 0);?Может fcntl(fd, F_GETFL) и fcntl(fd, F_GETFL, 0) дают разные результаты сегодня или в будущем (при условии соответствующей реализации)?

Это было полезно?

Решение

Посмотрите на остальные команды fcntl.Обратите внимание, как некоторые из них (F_DUPFD, F_SETFL и другие) сообщают вам, для чего используется третий аргумент.Вам необходимо указать третий аргумент при использовании одного из них.Не при использовании F_GETFL или F_GETFD.

В КРАТКОМ ОБЗОРЕ вы можете видеть, что fcntl принимает 2 аргумента плюс ... это означает, что третий аргумент может быть опущен, если он не будет использоваться.

Проведя еще некоторое исследование, я обнаружил, что есть несколько старых справочных страниц (примерно со времен первого APUE), в которых КРАТКИЙ ОБЗОР подразумевает, что требуются все 3 аргумента.Пример: http://www.freebsd.org/cgi/man.cgi ?запрос=fcntl&manpath=FreeBSD+2.2.7-РЕЛИЗ

SYNOPSIS
     #include <fcntl.h>

     int
     fcntl(int fd, int cmd, int arg);

Я не могу найти никаких доказательств того, что это когда-либо действительно было объявлено таким образом в заголовке, но если бы это было так, то компиляция завершилась бы неудачей, если бы она была вызвана только с 2 аргументами.Это было бы хорошей причиной включить дополнительный аргумент 0 в ваш код.

Если мое предположение верно, и это фактическая причина исторического использования F_GETFL с 3 аргументами, то это бесполезное ископаемое того времени, когда прототипы функций были новыми и пугающими, а поставщики ОС ошибались в них.

Другие советы

В базовой системе FreeBSD оба fcntl(fd, F_GETFL) и fcntl(fd, F_GETFL, 0) используются.Но в большинстве случаев используется третий аргумент 0.Это могло быть вызвано историческими причинами, поскольку fcntl восходит к версии 4.2BSD и был импортирован во FreeBSD с помощью исходного кода 4.4BSD-Lite.

В версии 4.4BSD (и FreeBSD 2.0) на странице руководства аргумент указан как обязательный: int fcntl(int fd, int cmd, int arg), даже несмотря на то , что фактический заголовок старой школы делает не: int fcntl(int, int, ...).

Что касается почему, на это будет трудно ответить.Нам пришлось бы спросить первоначального автора (ов).Но поскольку в исходных тегах управления версиями нет имен пользователей, я бы не знал, как их отследить.

Дополнительный аргумент 0, вероятно, никогда не удалялся из кодовой базы FreeBSD, потому что он ничего не нарушает и поэтому недостаточно важен для "исправления".

Эти два звонка

flags = fcntl(fd, F_GETFL);
flags = fcntl(fd, F_GETFL, 0);

эквивалентны, поскольку третий переменный параметр игнорируется.Если вы взглянете на fs/fcntl.c:262 и fs/fcntl.c:269 вы увидите, что arg не используется.
Однако, когда вам нужно установить какое-то значение, вы должны передать значение, которое вы хотите установить.
Вы могли бы рассмотреть fcntl как ООП-эквивалент геттеров и сеттеров.

Существует ли система, для которой требуется 3-й аргумент:флаги = fcntl(fd, F_GETFL, 0);?

Я не знаю ни о чем таком.Linux, по крайней мере, этого не делает.В документации четко указано, что это игнорируется, поскольку не было бы никакого использования arg.Тот факт, что вы можете что-то передать, не означает, что вы должны это делать.

Может fcntl(fd, F_GETFL) и fcntl(fd, F_GETFL, 0) возвращать другой результат в какой-либо системе (в прошлом, сегодня и в будущем (при условии соответствующей реализации))?

lxr позволяет нам копаться в более старых версиях Linux и даже в 1991 году, с Linux 2.0.4, fcntl передано по третьему аргументу.Нет смысла принимать какие-либо дальнейшие аргументы.Следовательно, если и существует система, в которой этот третий аргумент имеет значение, то это точно не Linux.


Я провел кое-какие дальнейшие исследования и обнаружил несколько противоречивых результатов.Посмотрите на здесь:есть несколько книг (я не размещаю прямую ссылку на них, поскольку они могли бы быть protected) которые действительно предлагают fcntl как функция с тремя аргументами.Но, по крайней мере, в отношении GETFL/GETFD, не упоминается о arg.
ИМХО, его поведение никогда не воспринималось всерьез:то есть то, что заставляет вас задуматься.Более того, я бы даже счел вредным использовать этот третий аргумент:что, если это имеет / будет иметь значение?

Я снова прошелся по Linux, и третий аргумент для этих команд так и не был передан.

Наконец - то

Существует ли система / компилятор, для которого требуется 3-й аргумент:флаги = fcntl(fd, F_GETFL, 0);?Могут ли fcntl(fd, F_GETFL) и fcntl(fd, F_GETFL, 0) давать разные результаты сегодня или в будущем (при условии совместимой реализации)?

Будущее - это тайна.Сегодня я чувствую себя достаточно уверенно, чтобы исключить это.Однако в прошлом это мог бы было бы так.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top