| 2036 | in ADD_FLAGS. The file's name is NAME. */ |
| 2037 | |
| 2038 | static void |
| 2039 | set_fd_flags (int fd, int add_flags, char const *name) |
| 2040 | { |
| 2041 | /* Ignore file creation flags that are no-ops on file descriptors. */ |
| 2042 | add_flags &= ~ (O_NOCTTY | O_NOFOLLOW); |
| 2043 | |
| 2044 | if (add_flags) |
| 2045 | { |
| 2046 | int old_flags = fcntl (fd, F_GETFL); |
| 2047 | int new_flags = old_flags | add_flags; |
| 2048 | bool ok = true; |
| 2049 | if (old_flags < 0) |
| 2050 | ok = false; |
| 2051 | else if (old_flags != new_flags) |
| 2052 | { |
| 2053 | if (new_flags & (O_DIRECTORY | O_NOLINKS)) |
| 2054 | { |
| 2055 | /* NEW_FLAGS contains at least one file creation flag that |
| 2056 | requires some checking of the open file descriptor. */ |
| 2057 | struct stat st; |
| 2058 | if (ifstat (fd, &st) != 0) |
| 2059 | ok = false; |
| 2060 | else if ((new_flags & O_DIRECTORY) && ! S_ISDIR (st.st_mode)) |
| 2061 | { |
| 2062 | errno = ENOTDIR; |
| 2063 | ok = false; |
| 2064 | } |
| 2065 | else if ((new_flags & O_NOLINKS) && 1 < st.st_nlink) |
| 2066 | { |
| 2067 | errno = EMLINK; |
| 2068 | ok = false; |
| 2069 | } |
| 2070 | new_flags &= ~ (O_DIRECTORY | O_NOLINKS); |
| 2071 | } |
| 2072 | |
| 2073 | if (ok && old_flags != new_flags |
| 2074 | && fcntl (fd, F_SETFL, new_flags) == -1) |
| 2075 | ok = false; |
| 2076 | } |
| 2077 | |
| 2078 | if (!ok) |
| 2079 | error (EXIT_FAILURE, errno, _("setting flags for %s"), quoteaf (name)); |
| 2080 | } |
| 2081 | } |
| 2082 | |
| 2083 | /* The main loop. */ |
| 2084 | |