Почему fcntl(fd, F_SETFL, 0) используется в программировании последовательного порта

Я начинаю программировать последовательный порт в Linux. Прочитав несколько примеров в Интернете, я не понимаю точного эффекта fcntl(fd, F_SETFL, 0)? Это очищает биты, но на какие флаги это влияет? Что он устанавливает и/или очищает?


person msc    schedule 22.01.2016    source источник
comment
прочитайте это сначала, пожалуйста.   -  person Sourav Ghosh    schedule 22.01.2016


Ответы (2)


Возьмите один за другим

1) Используемый вызов функции

fcntl() — выполняет операцию над файловым дескриптором, переданным в аргументе.

2) 2-й аргумент в вызове

F_SETFL (целое число)

Установите флаги состояния файла на значение, указанное в arg. Режим доступа к файлу (O_RDONLY, O_WRONLY, O_RDWR) и флаги создания файла (например, O_CREAT, O_EXCL, O_NOCTTY, O_TRUNC) в arg игнорируются. В Linux эта команда может изменить только флаги O_APPEND, O_ASYNC, O_DIRECT, O_NOATIME и O_NONBLOCK.

3) 3-й аргумент в вызове

Это 0 означает, что установлено флаг состояния файла в ноль. Как сказал в комментарии Жан-Батист Юнес.

флаги режима доступа к файлам и создания файлов игнорируются. Эта команда сбрасывает все остальные флаги: без добавления, без асинхронности, без прямого, без атайма и без неблокировки.


Итак, наконец

fcntl(fd, F_SETFL, 0)

Этот вызов установит флаг file status дескриптора открытого файла в значение 0.


Но в идеале таким образом мы не должны менять флаг состояния файла. Лучший способ - сначала получить текущий флаг состояния файла, используя F_GETFL, а затем просто изменить в нем требуемый бит. См. пример:

Если вы хотите изменить флаги состояния файла, вы должны получить текущие флаги с помощью F_GETFL и изменить значение. Не думайте, что реализованы только перечисленные здесь флаги; ваша программа может быть запущена через несколько лет, и тогда может появиться больше флагов. Например, вот функция для установки или очистки флага O_NONBLOCK без изменения каких-либо других флагов:

/* Set the O_NONBLOCK flag of desc if value is nonzero,
   or clear the flag if value is 0.
   Return 0 on success, or -1 on error with errno set. */

int
set_nonblock_flag (int desc, int value)
{
  int oldflags = fcntl (desc, F_GETFL, 0);
  /* If reading the flags failed, return error indication now. */
  if (oldflags == -1)
    return -1;
  /* Set just the flag we want to set. */
  if (value != 0)
    oldflags |= O_NONBLOCK;
  else
    oldflags &= ~O_NONBLOCK;
  /* Store modified flag word in the descriptor. */
  return fcntl (desc, F_SETFL, oldflags);
}
person Jeegar Patel    schedule 22.01.2016
comment
Неверно, флаги режима доступа к файлу и создания файла игнорируются. Эта команда сбрасывает все остальные флаги: без добавления, без асинхронности, без прямого, без атайма и без неблокировки. - person Jean-Baptiste Yunès; 22.01.2016
comment
@Jigar Patel - Большое спасибо за четкий ответ - person msc; 22.01.2016
comment
Я думаю, что value нужно сделать bool. Я знаю, очень новый-sk00l, но ... лучше, чем целый int. - person unwind; 22.01.2016
comment
@msc Спасибо в stackoveflow - это голосование и принятие ответа. В любом случае удачного кодирования - person Jeegar Patel; 22.01.2016

на справочной странице для fcntl()

F_SETFL (целое число)

Установите флаги состояния файла на значение, указанное в arg. Режим доступа к файлу (O_RDONLY, O_WRONLY, O_RDWR) и флаги создания файла (например, O_CREAT, O_EXCL, O_NOCTTY, O_TRUNC) в arg игнорируются. В Linux эта команда может изменить только флаги O_APPEND, O_ASYNC, O_DIRECT, O_NOATIME и O_NONBLOCK. Невозможно изменить флаги O_DSYNC и O_SYNC; см. ОШИБКИ ниже.

Это взято с man страницы. .

person user3629249    schedule 24.01.2016
comment
Пожалуйста, при отрицании какого-либо ответа объясните хотя бы причины отрицательного ответа, чтобы люди могли улучшить свои ответы или отредактировать их, чтобы в следующий раз они не получили отрицательных голосов. - person Luis Colorado; 25.01.2016