From aa4669ad178c749a429358c59b547d249d75fb94 Mon Sep 17 00:00:00 2001 From: Martijn Dekker Date: Tue, 4 Aug 2020 01:02:05 +0200 Subject: [PATCH] Fix build on Solaris 11.4 (re: d3cd4cf) It was working on Solaris 11.3, but there were still problems building on Solaris 11.4 with GCC (as on the evaluation VM downloaded directly from Oracle): 1. ksh immediately segfaulted. Experimenting with the compiler flags Oracle uses revealed that we need to define _XPG6 for ksh not to segfault. Why is a mystery. 2. The default path logic used by 'command -p' and the 'getconf PATH' builtin command was still broken: the result did not include any of the /usr/xpg?/bin directories where the standard POSIX utilities actually live. Testing shows that the result of the C language probe 'confstr(_CS_PATH,name,length)' is broken on Solaris (it only yields the paths to the historic non-standard utilities, defeating the purpose) unless _XPG7 is defined; but the latter makes ksh segfault again. So another solution is needed. src/cmd/INIT/package.sh, bin/package: - Add another hack to add the -D_XPG6 flag to CCFLAGS if we're running SunOS aka Solaris. (I've tried to add a 'cc.sol11' script to src/cmd/INIT/ instead, but for some reason that I just don't have time to figure out, the INIT system ignores that on Solaris with gcc, so this is the only way I could come up with. Any patches for less hacky alternatives would be welcome.) src/lib/libast/comp/conf.sh: - Sanitise the code for finding the best 'getconf' utility. src/lib/libast/comp/conf.tab: PATH: - Since the C-languge getconf(_CS_PATH,...) is broken on Solaris 11.4, replace the C language probe with a shell script probe that uses the external 'getconf' utility. - To avoid ksh overriding the result of this probe with the result of its own getconf(_CS_PATH,...) call, which would make Solaris use the wrong value again, specify this as an AST configuration entry instead of a POSIX entry. This should be good enough for all systems; the OS 'getconf' utility should be reliable and the default path value is constant for each OS, so can be hardcoded. src/cmd/ksh93/tests/builtins.sh: - Add another 'sleep .1' to the 'sleep -s 31' test as it was still intermittently failing on Solaris and possibly other systems. --- bin/package | 11 +++++++++++ src/cmd/INIT/package.sh | 11 +++++++++++ src/cmd/ksh93/tests/builtins.sh | 1 + src/lib/libast/comp/conf.sh | 18 +++++++++++------- src/lib/libast/comp/conf.tab | 26 ++++++++++---------------- 5 files changed, 44 insertions(+), 23 deletions(-) diff --git a/bin/package b/bin/package index 47e791db7..66fa89255 100755 --- a/bin/package +++ b/bin/package @@ -5407,6 +5407,17 @@ make|view) esac ;; esac + # Hack for Solaris 11.4, which needs -D_XPG6 in C flags to not segfault + case `uname` in + SunOS) case " $CCFLAGS " in + *" -D_XPG6 "*) + ;; + *) CCFLAGS="-D_XPG6${CCFLAGS:+ $CCFLAGS}" + export CCFLAGS + ;; + esac + ;; + esac cd $PACKAGEROOT case $package in diff --git a/src/cmd/INIT/package.sh b/src/cmd/INIT/package.sh index 48aed7928..7b79942d6 100644 --- a/src/cmd/INIT/package.sh +++ b/src/cmd/INIT/package.sh @@ -5406,6 +5406,17 @@ make|view) esac ;; esac + # Hack for Solaris 11.4, which needs -D_XPG6 in C flags to not segfault + case `uname` in + SunOS) case " $CCFLAGS " in + *" -D_XPG6 "*) + ;; + *) CCFLAGS="-D_XPG6${CCFLAGS:+ $CCFLAGS}" + export CCFLAGS + ;; + esac + ;; + esac cd $PACKAGEROOT case $package in diff --git a/src/cmd/ksh93/tests/builtins.sh b/src/cmd/ksh93/tests/builtins.sh index 130176f3c..db91edab7 100755 --- a/src/cmd/ksh93/tests/builtins.sh +++ b/src/cmd/ksh93/tests/builtins.sh @@ -876,6 +876,7 @@ cat >| "$sleepsig" << 'EOF' sleep -s 31 & sleep .1 kill -CONT $! +sleep .1 if kill -0 $!; then kill -TERM $! # Don't leave a lingering background process exit 1 diff --git a/src/lib/libast/comp/conf.sh b/src/lib/libast/comp/conf.sh index 2976f3189..cc15f7930 100644 --- a/src/lib/libast/comp/conf.sh +++ b/src/lib/libast/comp/conf.sh @@ -344,17 +344,21 @@ for d in \ /usr/sbin \ /sbin \ $PATH -do if test -x $d/getconf - then case `$d/getconf --?-version 2>&1` in +do case $d in + /*) ;; + *) continue ;; + esac + if test -x "$d/getconf" + then case `"$d/getconf" --?-version 2>&1` in *"AT&T"*"Research"*) : presumably an implementation also configured from conf.tab - ;; - *) CONF_getconf=$d/getconf - if $CONF_getconf -a >/dev/null 2>&1 - then CONF_getconf_a=-a - fi + continue ;; esac + CONF_getconf=$d/getconf + if "$CONF_getconf" -a >/dev/null 2>&1 + then CONF_getconf_a=-a + fi break fi done diff --git a/src/lib/libast/comp/conf.tab b/src/lib/libast/comp/conf.tab index 0f8368f97..36e29ce70 100644 --- a/src/lib/libast/comp/conf.tab +++ b/src/lib/libast/comp/conf.tab @@ -368,22 +368,16 @@ PAGESIZE POSIX SC 1 MU PAGESIZE PAGE_SIZE 4096 cc{ } PAGE_SIZE POSIX SC 1 MU _AST_PAGESIZE PASS_MAX SVID SC 1 CDLMU 8 -PATH POSIX CS 1 MU cc{ - #include - #include - int main() - { - size_t length = confstr(_CS_PATH, 0, 0); - if(!length) - printf("\\"/bin:/usr/bin\\""); - else - { - char path[length]; - confstr(_CS_PATH, path, length); - printf("\\"%s\\"", path); - } - return 0; - } +PATH AST CS 1 MU sh{ + CONF_path= + case $CONF_getconf in + '') ;; + *) CONF_path=`"$CONF_getconf" PATH` ;; + esac + case $CONF_path in + '') echo '"/bin:/usr/bin"' ;; + *) echo "\\"$CONF_path\\"" ;; + esac } PATH_MAX POSIX PC 1 CDLMUX MAXPATHLEN 1024 PBS POSIX SC 2 FUW