In a QEMU user-mode environment (for various CPUs), the test-getcwd.sh test fails, with exit code 5. This happens with qemu 6.1.0, but did not happen with qemu 4.1.0 and older versions.
It's not easy to fix, because the code is involved. What I see, is that * The test invokes rpl_getcwd, * rpl_getcwd invokes the system's getcwd (under the fake name getcwd_system), which is in fact __getcwd from sysdeps/unix/sysv/linux/getcwd.c that calls __getcwd_generic from sysdeps/posix/getcwd.c). This glibc routine triggers the following system calls: getcwd(0x40001528,4096) = -1 errno=248 (File name too long) lstat64(".",0x400066c8) = 0 lstat64("/",0x400066c8) = 0 openat(AT_FDCWD,"..",O_RDONLY|O_LARGEFILE|O_CLOEXEC) = 4 fstat64(4,0x400066c8) = 0 fstat64(4,0x40006808) = 0 fcntl64(4,F_GETFL) = 0 fcntl64(4,F_SETFD,1) = 0 brk(NULL) = 0x00015000 brk(0x00036000) = 0x00036000 getdents64(4,86448,32768,86408,2065,0) = 80 close(4) = 0 and the system's getcwd thus fails with errno = 248 = EOVERFLOW (!). rpl_getcwd then fails with errno = 2 = ENOENT. It's too complex to fix this properly. So I just disable this test under QEMU. 2021-08-29 Bruno Haible <br...@clisp.org> getcwd tests: Avoid test failure when running under QEMU user-mode. * modules/getcwd-tests (Files): Add qemu.h. (Depends-on): Add stdbool. * tests/test-getcwd.c: Include qemu.h. (test_long_name): Skip this test when running under QEMU user-mode. (main): Consider return code 77 from test_long_name. diff --git a/modules/getcwd-tests b/modules/getcwd-tests index e5a7bd78b..c842c7711 100644 --- a/modules/getcwd-tests +++ b/modules/getcwd-tests @@ -1,12 +1,14 @@ Files: -tests/test-getcwd.c tests/test-getcwd.sh +tests/test-getcwd.c +tests/qemu.h Depends-on: errno fcntl-h getcwd-lgpl pathmax +stdbool sys_stat test-framework-sh diff --git a/tests/test-getcwd.c b/tests/test-getcwd.c index 061c69eb1..051d4f26a 100644 --- a/tests/test-getcwd.c +++ b/tests/test-getcwd.c @@ -27,6 +27,7 @@ #include <sys/stat.h> #include "pathmax.h" +#include "qemu.h" #include "macros.h" #if !(HAVE_GETPAGESIZE || defined getpagesize) @@ -138,6 +139,13 @@ test_long_name (void) this should be done in a compile test. */ return 0; #else + /* For a process running under QEMU user-mode, the "/" directory is not + really the root directory, but the value of the QEMU_LD_PREFIX environment + variable or of the -L command-line option. This causes the logic from + glibc/sysdeps/posix/getcwd.c to fail. In this case, skip the test. */ + if (is_running_under_qemu_user ()) + return 77; + char buf[PATH_MAX * (DIR_NAME_SIZE / DOTDOTSLASH_LEN + 1) + DIR_NAME_SIZE + BUF_SLOP]; char *cwd = getcwd (buf, PATH_MAX); @@ -256,5 +264,7 @@ test_long_name (void) int main (int argc, char **argv) { - return test_abort_bug () * 10 + test_long_name (); + int err1 = test_abort_bug (); + int err2 = test_long_name (); + return err1 * 10 + (err1 != 0 && err2 == 77 ? 0 : err2); }