On 4/9/22 11:38, Pádraig Brady wrote:
The attached uses an extra stat() to avoid this hang,
but only on these older systems without O_DIRECTORY.
Thanks, good catch.
I think you can simplify the system.h patch a bit, as there's no need
for 'err' in this new code. Also, the "try an open a fifo" should be
"try to open a fifo" or "try and open a fifo". Something like the
attached patch, perhaps?
diff --git a/src/system.h b/src/system.h
index 09498a172..71a2be42a 100644
--- a/src/system.h
+++ b/src/system.h
@@ -136,13 +136,26 @@ target_directory_operand (char const *file)
if (must_be_working_directory (file))
return AT_FDCWD;
- int fd = open (file, O_PATHSEARCH | O_DIRECTORY);
+ int fd = -1;
+ bool is_a_dir = false;
+ struct stat st;
+
+ /* On old systems like Solaris 10, check with stat first
+ lest we try to open a fifo for example and hang. */
+ if (!O_DIRECTORY && stat (file, &st) == 0)
+ {
+ is_a_dir = !!S_ISDIR (st.st_mode);
+ if (!is_a_dir)
+ errno = ENOTDIR;
+ }
+
+ if (O_DIRECTORY || is_a_dir)
+ fd = open (file, O_PATHSEARCH | O_DIRECTORY);
if (!O_DIRECTORY && 0 <= fd)
{
- /* On old systems like Solaris 10 that do not support O_DIRECTORY,
- check by hand whether FILE is a directory. */
- struct stat st;
+ /* On old systems like Solaris 10 double check type,
+ to ensure we've opened a directory. */
int err;
if (fstat (fd, &st) != 0 ? (err = errno, true)
: !S_ISDIR (st.st_mode) && (err = ENOTDIR, true))