#### 13.14.4 Getting and Setting File Status Flags

The `fcntl` function can fetch or change file status flags.

— Macro: int F_GETFL

> This macro is used as the command argument to `fcntl`, to read the file status flags for the open file with descriptor filedes.

> The normal return value from `fcntl` with this command is a nonnegative number which can be interpreted as the bitwise OR of the individual flags. Since the file access modes are not single-bit values, you can mask off other bits in the returned flags with `O_ACCMODE` to compare them.

> In case of an error, `fcntl` returns -1. The following `errno` error conditions are defined for this command:

> `EBADF`
>   The filedes argument is invalid.

— Macro: int F_SETFL

> This macro is used as the command argument to `fcntl`, to set the file status flags for the open file corresponding to the filedes argument. This command requires a third `int` argument to specify the new flags, so the call looks like this:

>               fcntl (filedes, F_SETFL, new-flags)

> You can't change the access mode for the file in this way; that is, whether the file descriptor was opened for reading or writing.

> The normal return value from `fcntl` with this command is an unspecified value other than -1, which indicates an error. The error conditions are the same as for the `F_GETFL` command.

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