if (must_be_working_directory (file))
return AT_FDCWD;
- int fd = -1;
- int try_to_open = 1;
- int stat_result;
-
- /* On old systems without O_DIRECTORY, like Solaris 10, check with
- stat first lest we try to open a fifo for example and hang. */
- if (!O_DIRECTORY)
- {
- stat_result = stat (file, st);
- if (stat_result == 0)
- {
- try_to_open = S_ISDIR (st->st_mode);
- errno = ENOTDIR;
- }
- else
- {
- /* On EOVERFLOW failure, give up on checking, as there is no
- easy way to check. This should be rare. */
- try_to_open = errno == EOVERFLOW;
- }
- }
-
- if (try_to_open)
- {
- fd = open (file, O_PATHSEARCH | O_DIRECTORY);
-
- /* On platforms lacking O_PATH, using O_SEARCH | O_DIRECTORY to
- open an overly-protected non-directory can fail with either
- EACCES or ENOTDIR. Prefer ENOTDIR as it makes for better
- diagnostics. */
- if (O_PATHSEARCH == O_SEARCH && fd < 0 && errno == EACCES)
- errno = (((O_DIRECTORY ? stat (file, st) : stat_result) == 0
- && !S_ISDIR (st->st_mode))
- ? ENOTDIR : EACCES);
- }
-
- if (!O_DIRECTORY && 0 <= fd)
- {
- /* On old systems like Solaris 10 double check type,
- to ensure we've opened a directory. */
- int err;
- if (fstat (fd, st) == 0
- ? !S_ISDIR (st->st_mode) && (err = ENOTDIR, true)
- : (err = errno) != EOVERFLOW)
- {
- close (fd);
- errno = err;
- fd = -1;
- }
- }
+ int fd = open (file, O_PATHSEARCH | O_DIRECTORY);
+
+ /* On platforms lacking O_PATH, using O_SEARCH | O_DIRECTORY to
+ open an overly-protected non-directory can fail with either
+ EACCES or ENOTDIR. Prefer ENOTDIR as it makes for better
+ diagnostics. */
+ if (O_PATHSEARCH == O_SEARCH && fd < 0 && errno == EACCES)
+ errno = stat (file, st) < 0 || S_ISDIR (st->st_mode) ? EACCES : ENOTDIR;
return fd - (AT_FDCWD == -1 && fd < 0);
}
fputs (_(" cio use concurrent I/O for data\n"), stdout);
if (O_DIRECT)
fputs (_(" direct use direct I/O for data\n"), stdout);
- if (O_DIRECTORY)
- fputs (_(" directory fail unless a directory\n"), stdout);
+ fputs (_(" directory fail unless a directory\n"), stdout);
if (O_DSYNC)
fputs (_(" dsync use synchronized I/O for data\n"), stdout);
if (O_SYNC)
int flags = (O_PATHSEARCH | O_DIRECTORY
| (dereference_dest_dir_symlinks ? 0 : O_NOFOLLOW));
destdir_fd = openat_safer (AT_FDCWD, d, flags);
- int err = errno;
- if (!O_DIRECTORY && 0 <= destdir_fd)
- {
- struct stat st;
- err = (fstat (destdir_fd, &st) != 0 ? errno
- : S_ISDIR (st.st_mode) ? 0 : ENOTDIR);
- if (err != 0)
- {
- close (destdir_fd);
- destdir_fd = -1;
- }
- }
if (0 <= destdir_fd)
{
n_files -= !target_directory;
target_directory = d;
}
else if (! (n_files == 2 && !target_directory))
- error (EXIT_FAILURE, err, _("target %s"), quoteaf (d));
+ error (EXIT_FAILURE, errno, _("target %s"), quoteaf (d));
}
}