Why fcntl(fd, F_SETFL, 0) use in serial port programming

msc picture msc · Jan 22, 2016 · Viewed 8.7k times · Source

I am starting serial port programming in Linux. After reading several examples on the web, I don't understand exact effect of fcntl(fd, F_SETFL, 0)? It is clearing bits, but what flags does it affect? What does it set and or clear?

Answer

Jeegar Patel picture Jeegar Patel · Jan 22, 2016

Take one by one

1) Function call used

fcntl() - It perform the operation on file descriptor passed in argument.

2) 2nd argument in call

F_SETFL (int)

Set the file status flags to the value specified by arg. File access mode (O_RDONLY, O_WRONLY, O_RDWR) and file creation flags (i.e., O_CREAT, O_EXCL, O_NOCTTY, O_TRUNC) in arg are ignored. On Linux this command can change only the O_APPEND, O_ASYNC, O_DIRECT, O_NOATIME, and O_NONBLOCK flags.

3) 3rd argument in call

It is 0 means, It set file status flag to zero. As Jean-Baptiste Yunès said in comment.

file access mode and file creation flags are ignored. This command reset every other flags: no append, no async, no direct, no atime, and no nonblocking


So finally

fcntl(fd, F_SETFL, 0)

This call will set opened file desciptor's file status flag to value 0.


But idealy this way we should not change file status flag. Best way is to first get the current file status flag using F_GETFL and then just change required bit in that. See example:

If you want to modify the file status flags, you should get the current flags with F_GETFL and modify the value. Don’t assume that the flags listed here are the only ones that are implemented; your program may be run years from now and more flags may exist then. For example, here is a function to set or clear the flag O_NONBLOCK without altering any other flags:

/* 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);
}