[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
getcwd: Fix test failure when building on a Linux 9p file system
From: |
Bruno Haible |
Subject: |
getcwd: Fix test failure when building on a Linux 9p file system |
Date: |
Sun, 13 Jan 2019 19:22:43 +0100 |
User-agent: |
KMail/5.1.3 (Linux/4.4.0-141-generic; KDE/5.18.0; x86_64; ; ) |
I'm testing a POSIX testdir of gnulib on a 9p file system [1], which
serves as a shared directory between the host and the guest VM. 'mount'
reports this line:
/dev/share on /share type 9p
(rw,sync,dirsync,relatime,access=client,trans=virtio)
I see several test failures:
FAIL: test-fchdir
FAIL: test-fstatat
FAIL: test-getcwd-lgpl
FAIL: test-getcwd.sh
FAIL: test-linkat
FAIL: test-renameat
FAIL: test-renameatu
FAIL: test-stat
FAIL: test-statat
The cause is that the configure test in getcwd-path-max.m4 has experienced
an unexpected errno value:
...
mkdirat(AT_FDCWD, "confdir3", 0700) = 0
chdir("confdir3") = 0
mkdirat(AT_FDCWD, "confdir3", 0700) = -1 EINVAL (Invalid argument)
unlinkat(AT_FDCWD, "confdir3", AT_REMOVEDIR) = -1 ENOENT (No such file or
directory)
chdir("..") = 0
...
leading to an exit code of 20.
As a consequence, the normal glibc / system call getcwd(), which would succeed:
getcwd("/share/home/bruno", 4096) = 18
is overridden by a gnulib getcwd(), which fails:
newfstatat(AT_FDCWD, ".", {st_mode=S_IFREG|071600022, st_size=0, ...},
AT_SYMLINK_NOFOLLOW) = 0
newfstatat(AT_FDCWD, "/", {st_mode=002, st_size=0, ...}, AT_SYMLINK_NOFOLLOW)
= 0
openat(AT_FDCWD, "..", O_RDONLY|O_LARGEFILE) = 3
fstat(3, {st_mode=S_IFREG|071600015, st_size=0, ...}) = 0
fstat(3, {st_mode=S_IFREG|071600015, st_size=0, ...}) = 0
fcntl(3, F_GETFL) = 0x8000 (flags O_RDONLY|O_LARGEFILE)
fcntl(3, F_SETFD, FD_CLOEXEC) = 0
getdents64(3, 0x15190, 32768) = -1 EPROTO (Protocol error)
close(3) = 0
It's not required to investigate the precise cause of this EPROTO error;
we know that on Linux the getcwd() system call is good and that therefore
the gnulib getcwd() override is suboptimal.
This patch fixes the issue.
[1] https://www.kernel.org/doc/Documentation/filesystems/9p.txt
2019-01-13 Bruno Haible <address@hidden>
getcwd: Fix test failure when building on a Linux 9p file system.
* m4/getcwd-path-max.m4 (gl_FUNC_GETCWD_PATH_MAX): On Linux, treat error
EINVAL from mkdir like ENAMETOOLONG.
* tests/test-getcwd.c (test_long_name): Likewise.
diff --git a/m4/getcwd-path-max.m4 b/m4/getcwd-path-max.m4
index 2cefc00..0ae3e1e 100644
--- a/m4/getcwd-path-max.m4
+++ b/m4/getcwd-path-max.m4
@@ -1,4 +1,4 @@
-# serial 21
+# serial 22
# Check for several getcwd bugs with long file names.
# If so, arrange to compile the wrapper function.
@@ -111,12 +111,20 @@ main ()
/* If mkdir or chdir fails, it could be that this system cannot create
any file with an absolute name longer than PATH_MAX, such as cygwin.
If so, leave fail as 0, because the current working directory can't
- be too long for getcwd if it can't even be created. For other
- errors, be pessimistic and consider that as a failure, too. */
+ be too long for getcwd if it can't even be created. On Linux with
+ the 9p file system, mkdir fails with error EINVAL when cwd_len gets
+ too long; ignore this failure because the getcwd() system call
+ produces good results whereas the gnulib substitute calls getdents64
+ which fails with error EPROTO.
+ For other errors, be pessimistic and consider that as a failure,
+ too. */
if (mkdir (DIR_NAME, S_IRWXU) < 0 || chdir (DIR_NAME) < 0)
{
if (! (errno == ERANGE || is_ENAMETOOLONG (errno)))
- fail = 20;
+ #ifdef __linux__
+ if (! (errno == EINVAL))
+ #endif
+ fail = 20;
break;
}
diff --git a/tests/test-getcwd.c b/tests/test-getcwd.c
index 31c9037..b5f8155 100644
--- a/tests/test-getcwd.c
+++ b/tests/test-getcwd.c
@@ -166,12 +166,20 @@ test_long_name (void)
/* If mkdir or chdir fails, it could be that this system cannot create
any file with an absolute name longer than PATH_MAX, such as cygwin.
If so, leave fail as 0, because the current working directory can't
- be too long for getcwd if it can't even be created. For other
- errors, be pessimistic and consider that as a failure, too. */
+ be too long for getcwd if it can't even be created. On Linux with
+ the 9p file system, mkdir fails with error EINVAL when cwd_len gets
+ too long; ignore this failure because the getcwd() system call
+ produces good results whereas the gnulib substitute calls getdents64
+ which fails with error EPROTO.
+ For other errors, be pessimistic and consider that as a failure,
+ too. */
if (mkdir (DIR_NAME, S_IRWXU) < 0 || chdir (DIR_NAME) < 0)
{
if (! (errno == ERANGE || errno == ENAMETOOLONG || errno == ENOENT))
- fail = 2;
+ #ifdef __linux__
+ if (! (errno == EINVAL))
+ #endif
+ fail = 2;
break;
}
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- getcwd: Fix test failure when building on a Linux 9p file system,
Bruno Haible <=