* xopen() is the same as open(), but it die()s if the open() fails. */
| 169 | * xopen() is the same as open(), but it die()s if the open() fails. |
| 170 | */ |
| 171 | int xopen(const char *path, int oflag, ...) |
| 172 | { |
| 173 | mode_t mode = 0; |
| 174 | va_list ap; |
| 175 | |
| 176 | /* |
| 177 | * va_arg() will have undefined behavior if the specified type is not |
| 178 | * compatible with the argument type. Since integers are promoted to |
| 179 | * ints, we fetch the next argument as an int, and then cast it to a |
| 180 | * mode_t to avoid undefined behavior. |
| 181 | */ |
| 182 | va_start(ap, oflag); |
| 183 | if (oflag & O_CREAT) |
| 184 | mode = va_arg(ap, int); |
| 185 | va_end(ap); |
| 186 | |
| 187 | for (;;) { |
| 188 | int fd = open(path, oflag, mode); |
| 189 | if (fd >= 0) |
| 190 | return fd; |
| 191 | if (errno == EINTR) |
| 192 | continue; |
| 193 | |
| 194 | if ((oflag & (O_CREAT | O_EXCL)) == (O_CREAT | O_EXCL)) |
| 195 | die_errno(_("unable to create '%s'"), path); |
| 196 | else if ((oflag & O_RDWR) == O_RDWR) |
| 197 | die_errno(_("could not open '%s' for reading and writing"), path); |
| 198 | else if ((oflag & O_WRONLY) == O_WRONLY) |
| 199 | die_errno(_("could not open '%s' for writing"), path); |
| 200 | else |
| 201 | die_errno(_("could not open '%s' for reading"), path); |
| 202 | } |
| 203 | } |
| 204 | |
| 205 | static int handle_nonblock(int fd, short poll_events, int err) |
| 206 | { |