From b6892537a4d89615abd39d38aafaea30680e852b Mon Sep 17 00:00:00 2001 From: Calvin Buckley Date: Thu, 24 Oct 2019 13:04:20 -0300 Subject: [PATCH] Fix eglib on AIX/PASE (mono/mono#17476) * fix eglib on AIX/PASE * Work around access(2) syscall bug on PASE On PASE, X_OK will always returns true. This is contrary to how AIX behaves (though corresponds to documentation!). This is probably because it's an upcall to the ILE version of access, and that seemingly always returns true. * Always export the dummy function in the test suite The AIX linker didn't export this properly, without using the giant sledgehammer of -bexpall. Write an export file and use it. This required some build system changes to expose an AIX-only automake conditional. * Use a file that exists on PASE for tests PASE doesn't use Unix-style DNS resolution, so /etc/hosts is missing. Use /etc/magic, since that seems to be present. * Don't use /bin on AIX/PASE for tests This is a symlink to /usr/bin, and it seems chdir/getcwd follows links. Use /usr instead, that is unlikely to be a symlink. * Make a note what directory we're in if we fail test_cwd * Change manual executable access check change per Jay * Change test on POSIXy platforms to always use root directory Commit migrated from https://github.com/mono/mono/commit/638e2c6a8614d25aad591112d3414e28641b97e0 --- src/mono/configure.ac | 3 +++ src/mono/mono/eglib/gfile-unix.c | 18 ++++++++++++++++++ src/mono/mono/eglib/test/Makefile.am | 6 +++++- src/mono/mono/eglib/test/file.c | 3 +++ src/mono/mono/eglib/test/path.c | 8 ++++++-- src/mono/mono/eglib/test/test-eglib.exp | 3 +++ 6 files changed, 38 insertions(+), 3 deletions(-) create mode 100644 src/mono/mono/eglib/test/test-eglib.exp diff --git a/src/mono/configure.ac b/src/mono/configure.ac index 1afcf0b..5936374 100644 --- a/src/mono/configure.ac +++ b/src/mono/configure.ac @@ -473,6 +473,8 @@ case "$host" in mono_cv_clang=no ;; *-*-aix*|*-*-os400*) + AC_DEFINE(HOST_AIX,1,[Targeting the AIX and PASE platforms]) + host_aix=yes dnl IMPORTANT: For svr4 sonames on AIX, you should set dnl `OBJECT_MODE=64` when configuring. dnl libtool cannot generate functioning svr4 sonames on @@ -576,6 +578,7 @@ AM_CONDITIONAL(HOST_ANDROID, test x$platform_android = xyes) AM_CONDITIONAL(HOST_TIZEN, test x$platform_tizen = xyes) AM_CONDITIONAL(HOST_IOS, test x$platform_ios = xyes) AM_CONDITIONAL(HOST_WASM, test x$platform_wasm = xyes) +AM_CONDITIONAL(HOST_AIX, test x$host_aix = xyes) if test -z "$HOST_DARWIN_TRUE"; then : PLATFORM_AOT_SUFFIX=.dylib diff --git a/src/mono/mono/eglib/gfile-unix.c b/src/mono/mono/eglib/gfile-unix.c index 5ba01df..eab9066 100644 --- a/src/mono/mono/eglib/gfile-unix.c +++ b/src/mono/mono/eglib/gfile-unix.c @@ -55,8 +55,26 @@ g_file_test (const gchar *filename, GFileTest test) } if ((test & G_FILE_TEST_IS_EXECUTABLE) != 0) { +#if !defined(__PASE__) if (access (filename, X_OK) == 0) return TRUE; +#else + /* + * PASE always returns true for X_OK; contrary to how AIX + * behaves (but *does* correspond to how it's documented!). + * This behaviour is also consistent with the ILE, so it's + * probably just an upcall returning the same results. As + * such, workaround it. + */ + if (!have_stat) + have_stat = (stat (filename, &st) == 0); + /* Hairy parens, but just manually try all permission bits */ + if (have_stat && ( + ((st.st_mode & S_IXOTH) + || ((st.st_mode & S_IXUSR) && (st.st_uid == getuid())) + || ((st.st_mode & S_IXGRP) && (st.st_gid == getgid()))))) + return TRUE; +#endif } #ifdef HAVE_LSTAT if ((test & G_FILE_TEST_IS_SYMLINK) != 0) { diff --git a/src/mono/mono/eglib/test/Makefile.am b/src/mono/mono/eglib/test/Makefile.am index 68b68d6..c925bad 100644 --- a/src/mono/mono/eglib/test/Makefile.am +++ b/src/mono/mono/eglib/test/Makefile.am @@ -1,6 +1,6 @@ include $(top_srcdir)/mk/common.mk -EXTRA_DIST = UTF-8.txt UTF-16BE.txt UTF-16LE.txt UTF-32BE.txt UTF-32LE.txt +EXTRA_DIST = UTF-8.txt UTF-16BE.txt UTF-16LE.txt UTF-32BE.txt UTF-32LE.txt test-eglib.exp SOURCES = \ enum.cpp \ @@ -37,6 +37,10 @@ test_eglib_SOURCES = $(SOURCES) GLIB_TEST_FLAGS_COMMON = -Wall -DEGLIB_TESTS=1 -D_FORTIFY_SOURCE=2 -I$(srcdir)/.. -I.. -DDRIVER_NAME=\"EGlib\" CFLAGS += $(GLIB_TEST_FLAGS_COMMON) CXXFLAGS += $(GLIB_TEST_FLAGS_COMMON) @CXXFLAGS_COMMON@ +if HOST_AIX +# This export file is required so test symbols are visible. +LDFLAGS += -Wl,-bE:test-eglib.exp +endif test_eglib_LDADD = ../libeglib.la $(LTLIBICONV) assertf_LDADD = ../libeglib.la $(LTLIBICONV) diff --git a/src/mono/mono/eglib/test/file.c b/src/mono/mono/eglib/test/file.c index 88023c3..25473c0 100644 --- a/src/mono/mono/eglib/test/file.c +++ b/src/mono/mono/eglib/test/file.c @@ -22,6 +22,9 @@ test_file_get_contents (void) gsize length; #ifdef G_OS_WIN32 const gchar *filename = "c:\\Windows\\system.ini"; +#elif defined(__PASE__) + /* Most etc files don't exist in PASE. Try one that should exist. */ + const gchar *filename = "/etc/magic"; #else const gchar *filename = "/etc/hosts"; #endif diff --git a/src/mono/mono/eglib/test/path.c b/src/mono/mono/eglib/test/path.c index bd62bb7..3af25b1 100644 --- a/src/mono/mono/eglib/test/path.c +++ b/src/mono/mono/eglib/test/path.c @@ -300,7 +300,11 @@ test_cwd (void) #ifdef G_OS_WIN32 const gchar *newdir = "C:\\Windows"; #else - const gchar *newdir = "/bin"; + /* + * AIX/PASE have /bin -> /usr/bin, and chdir/getcwd follows links. + * Use a directory available on all systems that shouldn't be a link. + */ + const gchar *newdir = "/"; #endif if (dir == NULL) @@ -312,7 +316,7 @@ test_cwd (void) dir = g_get_current_dir (); if (strcmp (dir, newdir) != 0) - return FAILED("Did not go to %s?", newdir); + return FAILED("Did not go to %s? Instead in %s", newdir, dir); g_free (dir); return OK; diff --git a/src/mono/mono/eglib/test/test-eglib.exp b/src/mono/mono/eglib/test/test-eglib.exp new file mode 100644 index 0000000..9c7cce2 --- /dev/null +++ b/src/mono/mono/eglib/test/test-eglib.exp @@ -0,0 +1,3 @@ +* This file is required so that the symbol is visibile and not GCed on AIX. +dummy_test_export + -- 2.7.4