Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
SUSE:SLE-15:Update
zsh
CVE-2019-20044.patch
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File CVE-2019-20044.patch of Package zsh
diff --color -Naur zsh-5.6.ori/configure.ac zsh-5.6.new/configure.ac --- zsh-5.6.ori/configure.ac 2018-09-03 15:37:10.000000000 +0200 +++ zsh-5.6.new/configure.ac 2022-03-01 17:09:37.419809709 +0100 @@ -1260,6 +1260,7 @@ getlogin getpwent getpwnam getpwuid getgrgid getgrnam \ initgroups nis_list \ setuid seteuid setreuid setresuid setsid \ + setgid setegid setregid setresgid \ memcpy memmove strstr strerror strtoul \ getrlimit getrusage \ setlocale \ diff --color -Naur zsh-5.6.ori/configure.ac.orig zsh-5.6.new/configure.ac.orig --- zsh-5.6.ori/configure.ac.orig 1970-01-01 01:00:00.000000000 +0100 +++ zsh-5.6.new/configure.ac.orig 2018-09-03 15:37:10.000000000 +0200 @@ -0,0 +1,3254 @@ +dnl +dnl configure.ac: Configure template for zsh. +dnl Process this file with autoconf to produce a configure script. +dnl +dnl Copyright (c) 1995-1997 Richard Coleman +dnl All rights reserved. +dnl +dnl Permission is hereby granted, without written agreement and without +dnl license or royalty fees, to use, copy, modify, and distribute this +dnl software and to distribute modified versions of this software for any +dnl purpose, provided that the above copyright notice and the following +dnl two paragraphs appear in all copies of this software. +dnl +dnl In no event shall Richard Coleman or the Zsh Development Group be liable +dnl to any party for direct, indirect, special, incidental, or consequential +dnl damages arising out of the use of this software and its documentation, +dnl even if Richard Coleman and the Zsh Development Group have been advised of +dnl the possibility of such damage. +dnl +dnl Richard Coleman and the Zsh Development Group specifically disclaim any +dnl warranties, including, but not limited to, the implied warranties of +dnl merchantability and fitness for a particular purpose. The software +dnl provided hereunder is on an "as is" basis, and Richard Coleman and the +dnl Zsh Development Group have no obligation to provide maintenance, +dnl support, updates, enhancements, or modifications. +dnl + +AC_INIT +AC_CONFIG_SRCDIR([Src/zsh.h]) +AC_PREREQ([2.69]) +AC_CONFIG_HEADER(config.h) + +dnl What version of zsh are we building ? +. ${srcdir}/Config/version.mk +echo "configuring for zsh $VERSION" + +dnl ---------------------------------------------- +dnl CHECK FOR MACHINE/VENDOR/OPERATING SYSTEM TYPE +dnl ---------------------------------------------- +dnl Find out machine type, vendor, and operating system +dnl What type of host is this? +AC_CANONICAL_HOST +AC_DEFINE_UNQUOTED(MACHTYPE, "$host_cpu", +[Define to be the machine type (microprocessor class or machine model).]) +AC_DEFINE_UNQUOTED(VENDOR, "$host_vendor", +[Define to be a string corresponding the vendor of the machine.]) +AC_DEFINE_UNQUOTED(OSTYPE, "$host_os", +[Define to be the name of the operating system.]) + +dnl ----------------------------- +dnl CHECKING COMMAND LINE OPTIONS +dnl ----------------------------- +dnl Handle --program-prefix, --program-suffix, etc. +zsh_ARG_PROGRAM + +dnl Handle setting of compile flags (CPPFLAGS, CFLAGS, LDFLAGS, LIBS). +zsh_COMPILE_FLAGS($CPPFLAGS, $CFLAGS, $LDFLAGS, $LIBS) + +dnl Do you want to debug zsh? +ifdef([zsh-debug],[undefine([zsh-debug])])dnl +AH_TEMPLATE([DEBUG], +[Define to 1 if you want to debug zsh.]) +AC_ARG_ENABLE(zsh-debug, +AS_HELP_STRING([--enable-zsh-debug],[compile with debug code and debugger symbols]), +[if test x$enableval = xyes; then + AC_DEFINE(DEBUG) +fi]) + +dnl Do you want zsh memory allocation routines. +ifdef([zsh-mem],[undefine([zsh-mem])])dnl +AH_TEMPLATE([ZSH_MEM], +[Define to 1 if you want to use zsh's own memory allocation routines]) +AC_ARG_ENABLE(zsh-mem, +AS_HELP_STRING([--enable-zsh-mem],[compile with zsh memory allocation routines]), +[if test x$enableval = xyes; then + AC_DEFINE(ZSH_MEM) +fi]) + +dnl Do you want to debug zsh memory allocation routines. +ifdef([zsh-mem-debug],[undefine([zsh-mem-debug])])dnl +AH_TEMPLATE([ZSH_MEM_DEBUG], +[Define to 1 if you want to debug zsh memory allocation routines.]) +AC_ARG_ENABLE(zsh-mem-debug, +AS_HELP_STRING([--enable-zsh-mem-debug],[debug zsh memory allocation routines]), +[if test x$enableval = xyes; then + AC_DEFINE(ZSH_MEM_DEBUG) +fi]) + +dnl Do you want to print warnings when errors in memory allocation. +AH_TEMPLATE([ZSH_MEM_WARNING], +[Define to 1 if you want to turn on warnings of memory allocation errors]) +ifdef([zsh-mem-warning],[undefine([zsh-mem-warning])])dnl +AC_ARG_ENABLE(zsh-mem-warning, +AS_HELP_STRING([--enable-zsh-mem-warning],[print warnings for errors in memory allocation]), +[if test x$enableval = xyes; then + AC_DEFINE(ZSH_MEM_WARNING) +fi]) + +dnl Do you want to turn on error checking for free(). +ifdef([zsh-secure-free],[undefine([zsh-secure-free])])dnl +AH_TEMPLATE([ZSH_SECURE_FREE], +[Define to 1 if you want to turn on memory checking for free().]) +AC_ARG_ENABLE(zsh-secure-free, +AS_HELP_STRING([--enable-zsh-secure-free],[turn on error checking for free()]), +[if test x$enableval = xyes; then + AC_DEFINE(ZSH_SECURE_FREE) +fi]) + +dnl Do you want to debug zsh heap allocation? +dnl Does not depend on zsh-mem. +ifdef([zsh-heap-debug],[undefine([zsh-heap-debug])])dnl +AH_TEMPLATE([ZSH_HEAP_DEBUG], +[Define to 1 if you want to turn on error checking for heap allocation.]) +AC_ARG_ENABLE(zsh-heap-debug, +AS_HELP_STRING([--enable-zsh-heap-debug],[turn on error checking for heap allocation]), +[if test x$enableval = xyes; then + AC_DEFINE(ZSH_HEAP_DEBUG) +fi]) + +dnl Do you want to allow Valgrind to debug heap allocation? +ifdef([zsh-valgrind],[undefine([zsh-valgrind])])dnl +AH_TEMPLATE([ZSH_VALGRIND], +[Define to 1 if you want to add code for valgrind to debug heap memory.]) +AC_ARG_ENABLE(zsh-valgrind, +AS_HELP_STRING([--enable-zsh-valgrind],[turn on support for valgrind debugging of heap memory]), +[if test x$enableval = xyes; then + AC_DEFINE(ZSH_VALGRIND) +fi]) + +dnl Do you want debugging information on internal hash tables. +dnl This turns on the `hashinfo' builtin command. +ifdef([zsh-hash-debug],[undefine([zsh-hash-debug])])dnl +AH_TEMPLATE([ZSH_HASH_DEBUG], +[Define to 1 if you want to get debugging information on internal + hash tables. This turns on the `hashinfo' builtin.]) +AC_ARG_ENABLE(zsh-hash-debug, +AS_HELP_STRING([--enable-zsh-hash-debug],[turn on debugging of internal hash tables]), +[if test x$enableval = xyes; then + AC_DEFINE(ZSH_HASH_DEBUG) +fi]) + +dnl Do you want to dynamically allocate memory on the stack where possible? +ifdef([stack-allocation],[undefine([stack-allocation])])dnl +AH_TEMPLATE([USE_STACK_ALLOCATION], +[Define to 1 if you want to allocate stack memory e.g. with `alloca'.]) +AC_ARG_ENABLE(stack-allocation, +AS_HELP_STRING([--enable-stack-allocation],[allocate stack memory e.g. with `alloca']), +[if test x$enableval = xyes; then + AC_DEFINE(USE_STACK_ALLOCATION) +fi]) + +dnl Pathnames for global zsh scripts +ifdef([etcdir],[undefine([etcdir])])dnl +AC_ARG_ENABLE(etcdir, +AS_HELP_STRING([--enable-etcdir=DIR],[the default directory for global zsh scripts]), +[etcdir="$enableval"], [etcdir=/etc]) + +ifdef([zshenv],[undefine([zshenv])])dnl +AC_ARG_ENABLE(zshenv, +AS_HELP_STRING([--enable-zshenv=FILE],[the full pathname of the global zshenv script]), +[zshenv="$enableval"], +[if test "x$etcdir" = xno; then + zshenv=no +else + zshenv="$etcdir/zshenv" +fi]) +AH_TEMPLATE([GLOBAL_ZSHENV], +[The global file to source absolutely first whenever zsh is run; + if undefined, don't source anything.]) +if test "x$zshenv" != xno; then + AC_DEFINE_UNQUOTED(GLOBAL_ZSHENV, "$zshenv") +fi + +ifdef([zshrc],[undefine([zshrc])])dnl +AC_ARG_ENABLE(zshrc, +AS_HELP_STRING([--enable-zshrc=FILE],[the full pathname of the global zshrc script]), +[zshrc="$enableval"], +[if test "x$etcdir" = xno; then + zshrc=no +else + zshrc="$etcdir/zshrc" +fi]) +AH_TEMPLATE([GLOBAL_ZSHRC], +[The global file to source whenever zsh is run; + if undefined, don't source anything]) +if test "x$zshrc" != xno; then + AC_DEFINE_UNQUOTED(GLOBAL_ZSHRC, "$zshrc") +fi + +ifdef([zprofile],[undefine([zprofile])])dnl +AC_ARG_ENABLE(zprofile, +AS_HELP_STRING([--enable-zprofile=FILE],[the full pathname of the global zprofile script]), +[zprofile="$enableval"], +[if test "x$etcdir" = xno; then + zprofile=no +else + zprofile="$etcdir/zprofile" +fi]) +AH_TEMPLATE([GLOBAL_ZPROFILE], +[The global file to source whenever zsh is run as a login shell, + before zshrc is read; if undefined, don't source anything.]) +if test "x$zprofile" != xno; then + AC_DEFINE_UNQUOTED(GLOBAL_ZPROFILE, "$zprofile") +fi + +ifdef([zlogin],[undefine([zlogin])])dnl +AC_ARG_ENABLE(zlogin, +AS_HELP_STRING([--enable-zlogin=FILE],[the full pathname of the global zlogin script]), +[zlogin="$enableval"], +[if test "x$etcdir" = xno; then + zlogin=no +else + zlogin="$etcdir/zlogin" +fi]) +AH_TEMPLATE([GLOBAL_ZLOGIN], +[The global file to source whenever zsh is run as a login shell; + if undefined, don't source anything]) +if test "x$zlogin" != xno; then + AC_DEFINE_UNQUOTED(GLOBAL_ZLOGIN, "$zlogin") +fi + +ifdef([zlogout],[undefine([zlogout])])dnl +AC_ARG_ENABLE(zlogout, +AS_HELP_STRING([--enable-zlogout=FILE],[the full pathname of the global zlogout script]), +[zlogout="$enableval"], +[if test "x$etcdir" = xno; then + zlogout=no +else + zlogout="$etcdir/zlogout" +fi]) +AH_TEMPLATE([GLOBAL_ZLOGOUT], +[The global file to source whenever zsh was run as a login shell. + This is sourced right before exiting. If undefined, don't source + anything.]) +if test "x$zlogout" != xno; then + AC_DEFINE_UNQUOTED(GLOBAL_ZLOGOUT, "$zlogout") +fi + +AC_SUBST(zshenv)dnl +AC_SUBST(zshrc)dnl +AC_SUBST(zprofile)dnl +AC_SUBST(zlogin)dnl +AC_SUBST(zlogout)dnl + +dnl Do you want dynamically loaded binary modules. +ifdef([dynamic],[undefine([dynamic])])dnl +AC_ARG_ENABLE(dynamic, +AS_HELP_STRING([--disable-dynamic],[turn off dynamically loaded binary modules]), +[dynamic="$enableval"], [dynamic=yes]) + +dnl Do you want to disable restricted on r* commands +ifdef([restricted-r],[undefine([restricted-r])])dnl +AH_TEMPLATE([RESTRICTED_R], +[Undefine this if you don't want to get a restricted shell + when zsh is exec'd with basename that starts with r. + By default this is defined.]) +AC_ARG_ENABLE(restricted-r, +AS_HELP_STRING([--disable-restricted-r],[turn off r* invocation for restricted shell]), +[if test x$enableval = xyes; then + AC_DEFINE(RESTRICTED_R) +fi], +AC_DEFINE(RESTRICTED_R) +) + +dnl Do you want to disable use of locale functions +AH_TEMPLATE([CONFIG_LOCALE], +[Undefine if you don't want local features. By default this is defined.]) +AC_ARG_ENABLE([locale], +AS_HELP_STRING([--disable-locale],[turn off locale features]), +[if test x$enableval = xyes; then + AC_DEFINE(CONFIG_LOCALE) +fi], +AC_DEFINE(CONFIG_LOCALE) +) + +dnl Do you want to compile as K&R C. +AC_ARG_ENABLE(ansi2knr, +AS_HELP_STRING([--enable-ansi2knr],[translate source to K&R C before compiling]), +[ansi2knr="$enableval"], [ansi2knr=default]) + +ifdef([runhelpdir],[undefine([runhelpdir])])dnl +AC_ARG_ENABLE(runhelpdir, +AS_HELP_STRING([--enable-runhelpdir=DIR],[the directory in which to install run-help files]), +[if test x"$enableval" = xno; then + runhelpdir= +else + runhelpdir="$enableval" +fi], [runhelpdir=yes]) +if test x"$runhelpdir" = xyes; then + runhelpdir=${datadir}/${tzsh_name}/'${VERSION}'/help +fi +if test x"$runhelpdir" = x; then + runhelp= +else + runhelp=runhelp +fi + +ifdef([fndir],[undefine([fndir])])dnl +AC_ARG_ENABLE(fndir, +AS_HELP_STRING([--enable-fndir=DIR],[the directory in which to install functions]), +dnl ${VERSION} to be determined at compile time. +[if test x$enableval = xyes; then + fndir=${datadir}/${tzsh_name}/'${VERSION}'/functions +else + fndir="$enableval" +fi], [fndir=${datadir}/${tzsh_name}/'${VERSION}'/functions]) + +ifdef([sitefndir],[undefine([sitefndir])])dnl +AC_ARG_ENABLE(site-fndir, +AS_HELP_STRING([--enable-site-fndir=DIR],[same for site functions (not version specific)]), +[if test x$enableval = xyes; then + sitefndir=${datadir}/${tzsh_name}/site-functions +else + sitefndir="$enableval" +fi], [sitefndir=${datadir}/${tzsh_name}/site-functions]) + +dnl Add /usr/local/share/zsh/site-functions if not yet present +dnl owing to $sitefndir, whether or not explicitly given. +dnl If not explicitly given, it hasn't been expanded yet. +if test X$sitefndir = X/usr/local/share/zsh/site-functions || \ + test X$sitefndir = Xno +then fixed_sitefndir='' +elif test X$prefix != X/usr/local; then + if test X$prefix = XNONE && test X$ac_default_prefix = X/usr/local; then + if test X$tzsh_name != Xzsh + then fixed_sitefndir=/usr/local/share/zsh/site-functions + else fixed_sitefndir='' + fi + else fixed_sitefndir=/usr/local/share/zsh/site-functions + fi +elif test X$tzsh_name != Xzsh +then fixed_sitefndir=/usr/local/share/zsh/site-functions +else fixed_sitefndir='' +fi + +ifdef([function_subdirs],[undefine([function_subdirs])]) +AC_ARG_ENABLE(function-subdirs, +AS_HELP_STRING([--enable-function-subdirs],[install functions in subdirectories])) + +if test "x${enable_function_subdirs}" != x && + test "x${enable_function_subdirs}" != xno; then + FUNCTIONS_SUBDIRS=yes +else + FUNCTIONS_SUBDIRS=no +fi + +ifdef([additionalfpath],[undefine([additionalfpath])])dnl +AC_ARG_ENABLE(additional-fpath, +AS_HELP_STRING([--enable-additional-fpath=DIR],[add directories to default function path]), +[if test x$enableval = xyes; then + additionalfpath="" +else + additionalfpath="${enableval}" +fi], [additionalfpath=""]) + +AC_SUBST(runhelpdir)dnl +AC_SUBST(runhelp)dnl +AC_SUBST(additionalfpath)dnl +AC_SUBST(fndir)dnl +AC_SUBST(sitefndir)dnl +AC_SUBST(fixed_sitefndir)dnl +AC_SUBST(FUNCTIONS_SUBDIRS)dnl + +dnl Directories for scripts such as newuser. + +ifdef([scriptdir],[undefine([scriptdir])])dnl +AC_ARG_ENABLE(scriptdir, +AS_HELP_STRING([--enable-scriptdir=DIR],[the directory in which to install scripts]), +dnl ${VERSION} to be determined at compile time. +[if test x$enableval = xyes; then + scriptdir=${datadir}/${tzsh_name}/'${VERSION}'/scripts +else + scriptdir="$enableval" +fi], [scriptdir=${datadir}/${tzsh_name}/'${VERSION}'/scripts]) + +ifdef([sitescriptdir],[undefine([sitescriptdir])])dnl +AC_ARG_ENABLE(site-scriptdir, +AS_HELP_STRING([--enable-site-scriptdir=DIR],[same for site scripts (not version specific)]), +[if test x$enableval = xyes; then + sitescriptdir=${datadir}/${tzsh_name}/scripts +else + sitescriptdir="$enableval" +fi], [sitescriptdir=${datadir}/${tzsh_name}/scripts]) + +AC_SUBST(scriptdir)dnl +AC_SUBST(sitescriptdir)dnl + +dnl htmldir is already handled, but if it wasn't set, use +dnl the standard zsh default. +if test x$htmldir = x'${docdir}' || test x$htmldir = x; then + htmldir='$(datadir)/$(tzsh)/htmldoc' +fi + +AH_TEMPLATE([CUSTOM_PATCHLEVEL], +[Define to a custom value for the ZSH_PATCHLEVEL parameter]) +AC_ARG_ENABLE(custom-patchlevel, +AS_HELP_STRING([--enable-custom-patchlevel],[set a custom ZSH_PATCHLEVEL value]), +[if test x$enableval != x && test x$enableval != xno; then + AC_DEFINE_UNQUOTED([CUSTOM_PATCHLEVEL], ["$enableval"]) +fi]) + +dnl Do you want maildir support? +ifdef([maildir_support],[undefine([maildir_support])])dnl +AH_TEMPLATE([MAILDIR_SUPPORT], +[Define for Maildir support]) +AC_ARG_ENABLE(maildir-support, +AS_HELP_STRING([--enable-maildir-support],[enable maildir support in MAIL and MAILPATH]), +[if test x$enableval = xyes; then + AC_DEFINE(MAILDIR_SUPPORT) +fi]) + +dnl Do you want to set a maximum function depth? +ifdef([max_function_depth],[undefine([max_function_depth])])dnl +AH_TEMPLATE([MAX_FUNCTION_DEPTH], +[Define for function depth limits]) +AC_ARG_ENABLE(max-function-depth, +AS_HELP_STRING([--enable-max-function-depth=MAX],[limit function depth to MAX, default 500]), +[if test x$enableval = xyes; then + AC_DEFINE(MAX_FUNCTION_DEPTH, 500) +elif test x$enableval != xno; then + AC_DEFINE_UNQUOTED(MAX_FUNCTION_DEPTH, $enableval) +fi], +[AC_DEFINE(MAX_FUNCTION_DEPTH, 500)] +) + +ifdef([default_readnullcmd],[undefine([default_readnullcmd])])dnl +AH_TEMPLATE([DEFAULT_READNULLCMD], +[Define default pager used by readnullcmd]) +AC_ARG_ENABLE(readnullcmd, +AS_HELP_STRING([--enable-readnullcmd=PAGER],[pager used when READNULLCMD is not set]), +[if test x$enableval = xyes; then + AC_DEFINE(DEFAULT_READNULLCMD,"more") +elif test x$enableval != xno; then + AC_DEFINE_UNQUOTED(DEFAULT_READNULLCMD,"$enableval") +fi], +[AC_DEFINE(DEFAULT_READNULLCMD,"more")] +) + +dnl Do you want to look for pcre support? +AC_ARG_ENABLE(pcre, +AS_HELP_STRING([--enable-pcre],[enable the search for the pcre library (may create run-time library dependencies)])) + +dnl Do you want to look for capability support? +AC_ARG_ENABLE(cap, +AS_HELP_STRING([--enable-cap],[enable the search for POSIX capabilities (may require additional headers to be added by hand)])) + +AC_ARG_ENABLE(gdbm, +AS_HELP_STRING([--disable-gdbm],[turn off search for gdbm library]), +[gdbm="$enableval"], [gdbm=yes]) + +dnl ------------------ +dnl CHECK THE COMPILER +dnl ------------------ +dnl We want these before the checks, so the checks can modify their values. +test -z "${CFLAGS+set}" && CFLAGS= auto_cflags=1 +test -z "${LDFLAGS+set}" && LDFLAGS= auto_ldflags=1 + +AC_PROG_CC + +dnl Check for large file support. + +dnl Gross hack for ReliantUNIX - GCC does not understand getconf options +dnl For now just disable LFS in this case +dnl Any takers? +if test "$host" = mips-sni-sysv4 && test -n "$GCC"; then + : +else + AC_SYS_LARGEFILE +fi + +dnl if the user hasn't specified CFLAGS, then +dnl if compiler is gcc, then use -O2 and some warning flags +dnl else use -O +if test -n "$auto_cflags" && test ."$ansi2knr" != .yes; then + if test "${enable_zsh_debug}" = yes; then + if test -n "$GCC"; then + CFLAGS="$CFLAGS -Wall -Wmissing-prototypes -ggdb" + else + CFLAGS="$CFLAGS -g" + fi + else + if test -n "$GCC"; then + CFLAGS="$CFLAGS -Wall -Wmissing-prototypes -O2" + else + CFLAGS="$CFLAGS -O" + fi + fi +fi +if test -n "$auto_ldflags"; then + case "${enable_zsh_debug}$host_os" in + yesaix*|yeshpux*|yesnetbsd*|yesopenbsd*) ;; # "ld -g" is not valid on these systems + darwin*) LDFLAGS=-Wl,-x ;; + yes*) LDFLAGS=-g ;; + *) LDFLAGS=-s ;; + esac +fi + +dnl ---------- +dnl SCO KLUDGE +dnl ---------- +dnl Sco doesn't define any useful compiler symbol, +dnl so we will check for sco and define __sco if +dnl found. +case "$host_os" in + sco*) CFLAGS="-D__sco $CFLAGS" ;; +esac + +sed=':1 + s/ -s / /g + t1 + s/^ *// + s/ *$//' + +case " $LDFLAGS " in + *" -s "*) strip_exeldflags=true strip_libldflags=true + LDFLAGS=`echo " $LDFLAGS " | sed "$sed"` ;; + *) strip_exeldflags=false strip_libldflags=false ;; +esac + +case " ${EXELDFLAGS+$EXELDFLAGS }" in + " ") ;; + *" -s "*) strip_exeldflags=true + EXELDFLAGS=`echo " $EXELDFLAGS " | sed "$sed"` ;; + *) strip_exeldflags=false ;; +esac + +case " ${LIBLDFLAGS+$LIBLDFLAGS }" in + " ") ;; + *" -s "*) strip_libldflags=true + LIBLDFLAGS=`echo " $LIBLDFLAGS " | sed "$sed"` ;; + *) strip_libldflags=false ;; +esac + +AC_SUBST(CFLAGS)dnl +AC_SUBST(LDFLAGS)dnl +AC_SUBST(EXELDFLAGS)dnl +AC_SUBST(LIBLDFLAGS)dnl + +AC_PROG_CPP dnl Figure out how to run C preprocessor. +AC_C_CONST dnl Does compiler support `const'. + +dnl Default preprocessing on Mac OS X produces warnings +dnl Mac OS X 10.6 (darwin10.x.x) does not need this. +case "$host_os" in + darwin[[0-9]].*) CPP="$CPP -traditional-cpp" ;; +esac + +fp_PROG_CC_STDC +AC_MSG_CHECKING([whether to use prototypes]) +if test ."$ansi2knr" = .yes || test ."$ansi2knr" = .no; then + msg="(overridden) " +else + msg= + if test ."$fp_cv_prog_cc_stdc" = .no; then + ansi2knr=yes + else + ansi2knr=no + fi +fi +AH_TEMPLATE([PROTOTYPES], +[Define to 1 if ANSI function prototypes are usable.]) +if test "$ansi2knr" = yes; then + AC_MSG_RESULT(${msg}no) + U=_ +else + AC_MSG_RESULT(${msg}yes) + AC_DEFINE(PROTOTYPES) + U= +fi +AC_SUBST(U) + +AC_FUNC_ALLOCA dnl Check how to get `alloca'. + +dnl If the compiler supports union initialisation +AC_CACHE_CHECK(if the compiler supports union initialisation, +zsh_cv_c_have_union_init, +[AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[union{void *p;long l;}u={0};]], [[u.l=1;]])],[zsh_cv_c_have_union_init=yes],[zsh_cv_c_have_union_init=no])]) +AH_TEMPLATE([HAVE_UNION_INIT], +[Define to 1 if the compiler can initialise a union.]) +if test x$zsh_cv_c_have_union_init = xyes; then + AC_DEFINE(HAVE_UNION_INIT) +fi + +dnl Checking if compiler correctly cast signed to unsigned. +AC_CACHE_CHECK(if signed to unsigned casting is broken, +zsh_cv_c_broken_signed_to_unsigned_casting, +[AC_RUN_IFELSE([AC_LANG_SOURCE([[main(){return((int)(unsigned char)((char) -1) == 255);}]])],[zsh_cv_c_broken_signed_to_unsigned_casting=yes],[zsh_cv_c_broken_signed_to_unsigned_casting=no],[zsh_cv_c_broken_signed_to_unsigned_casting=no])]) +AH_TEMPLATE([BROKEN_SIGNED_TO_UNSIGNED_CASTING], +[Define to 1 if compiler incorrectly cast signed to unsigned.]) +if test x$zsh_cv_c_broken_signed_to_unsigned_casting = xyes; then + AC_DEFINE(BROKEN_SIGNED_TO_UNSIGNED_CASTING) +fi + +dnl Checking if the compiler supports variable-length arrays +AC_CACHE_CHECK(if the compiler supports variable-length arrays, +zsh_cv_c_variable_length_arrays, +[AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[int foo(), n;]], [[int i[foo()], a[n+1];]])],[zsh_cv_c_variable_length_arrays=yes],[zsh_cv_c_variable_length_arrays=no])]) +AH_TEMPLATE([HAVE_VARIABLE_LENGTH_ARRAYS], +[Define to 1 if compiler supports variable-length arrays]) +if test x$zsh_cv_c_variable_length_arrays = xyes; then + AC_DEFINE(HAVE_VARIABLE_LENGTH_ARRAYS) +fi + +dnl ------------------ +dnl CHECK FOR PROGRAMS +dnl ------------------ +AC_PROG_MAKE_SET dnl Does make define $MAKE +AC_PROG_INSTALL dnl Check for BSD compatible `install' +AC_PROG_AWK dnl Check for mawk,gawk,nawk, then awk. +AC_PROG_LN dnl Check for working ln, for "make install" +AC_PROG_LN_S dnl Use ln -s/ln/cp for "make install.runhelp" +AC_PROG_EGREP dnl sets $EGREP to grep -E or egrep +AC_CHECK_PROGS([YODL], [yodl], [: yodl]) + +YODL_OPTIONS='' +if test "x$ac_cv_prog_YODL" = xyodl; then + case `yodl --version` in + *"version 2."*) YODL_OPTIONS='-k' ;; + *"version 3."*) YODL_OPTIONS='-k -L' ;; + *"version 4."*) YODL_OPTIONS='-k -L' ;; + esac +fi +AC_SUBST(YODL_OPTIONS) + +AC_CHECK_PROGS([TEXI2DVI], [texi2dvi], [: texi2dvi]) +AC_CHECK_PROGS([TEXI2PDF], [texi2pdf], [: texi2pdf]) +AC_CHECK_PROGS([TEXI2HTML], [texi2any texi2html], [: texi2html]) + +if test x"$TEXI2PDF" != xtexi2pdf && test x"$TEXI2DVI" = xtexi2dvi; then + TEXI2PDF='texi2dvi --pdf' +fi + +if test x"$TEXI2HTML" = xtexi2any; then + TEXI2HTML='texi2any -c TEXI2HTML=1' +fi + +case "$LC_PAPER" in + ??_US*) PAPERSIZE=us ;; + *) PAPERSIZE=a4 ;; +esac +AC_SUBST(PAPERSIZE) + +AC_CHECK_PROGS([ANSI2KNR], [ansi2knr], [: ansi2knr]) + +if test x"$ansi2knr" = xyes && test x"$ANSI2KNR" = x": ansi2knr"; then + echo "----------" + echo "configure fatal error:" + echo "ansi2knr was specified (--enable-ansi2knr) but the program could not be found." + echo "Either remove the configure option if it is not required or build the ansi2knr" + echo "program before reconfiguring Zsh. The source code for ansi2knr is also" + echo "available in the GPL directory on Zsh distribution sites." + exit 1 +fi + +dnl ------------------ +dnl CHECK HEADER FILES +dnl ------------------ +AC_HEADER_DIRENT +AC_HEADER_STDC +AC_HEADER_TIME +AC_HEADER_STAT +AC_HEADER_SYS_WAIT + +oldcflags="$CFLAGS" +if test x$enable_pcre = xyes; then +AC_CHECK_PROG([PCRECONF], pcre-config, pcre-config) +dnl Typically (meaning on this single RedHat 9 box in front of me) +dnl pcre-config --cflags produces a -I output which needs to go into +dnl CPPFLAGS else configure's preprocessor tests don't pick it up, +dnl producing a warning. +if test "x$ac_cv_prog_PCRECONF" = xpcre-config; then + CPPFLAGS="$CPPFLAGS `pcre-config --cflags`" +fi +fi + +AC_CHECK_HEADERS(sys/time.h sys/times.h sys/select.h termcap.h termio.h \ + termios.h sys/param.h sys/filio.h string.h memory.h \ + limits.h fcntl.h libc.h sys/utsname.h sys/resource.h \ + locale.h errno.h stdio.h stdarg.h varargs.h stdlib.h \ + unistd.h sys/capability.h \ + utmp.h utmpx.h sys/types.h pwd.h grp.h poll.h sys/mman.h \ + netinet/in_systm.h pcre.h langinfo.h wchar.h stddef.h \ + sys/stropts.h iconv.h ncurses.h ncursesw/ncurses.h \ + ncurses/ncurses.h) +if test x$dynamic = xyes; then + AC_CHECK_HEADERS(dlfcn.h) + AC_CHECK_HEADERS(dl.h) +fi + +dnl Some SCO systems cannot include both sys/time.h and sys/select.h +AH_TEMPLATE([TIME_H_SELECT_H_CONFLICTS], +[Define if sys/time.h and sys/select.h cannot be both included.]) +if test x$ac_cv_header_sys_time_h = xyes && test x$ac_cv_header_sys_select_h = xyes; then + AC_CACHE_CHECK(for conflicts in sys/time.h and sys/select.h, + zsh_cv_header_time_h_select_h_conflicts, + [AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <sys/time.h> +#include <sys/select.h>]], [[int i;]])],[zsh_cv_header_time_h_select_h_conflicts=no],[zsh_cv_header_time_h_select_h_conflicts=yes])]) + if test x$zsh_cv_header_time_h_select_h_conflicts = xyes; then + AC_DEFINE(TIME_H_SELECT_H_CONFLICTS) + fi +fi + +AH_TEMPLATE([GWINSZ_IN_SYS_IOCTL], +[Define if TIOCGWINSZ is defined in sys/ioctl.h but not in termios.h.]) +if test x$ac_cv_header_termios_h = xyes; then + AC_CACHE_CHECK(TIOCGWINSZ in termios.h, + zsh_cv_header_termios_h_tiocgwinsz, + [AC_LINK_IFELSE([AC_LANG_PROGRAM([[ +#ifdef HAVE_SYS_TYPES_H +# include <sys/types.h> +#endif +#include <termios.h>]], [[int x = TIOCGWINSZ;]])],[zsh_cv_header_termios_h_tiocgwinsz=yes],[zsh_cv_header_termios_h_tiocgwinsz=no])]) +else + zsh_cv_header_termios_h_tiocgwinsz=no +fi +if test x$zsh_cv_header_termios_h_tiocgwinsz = xno; then + AC_CACHE_CHECK(TIOCGWINSZ in sys/ioctl.h, + zsh_cv_header_sys_ioctl_h_tiocgwinsz, + [AC_LINK_IFELSE([AC_LANG_PROGRAM([[ +#ifdef HAVE_SYS_TYPES_H +# include <sys/types.h> +#endif +#include <sys/ioctl.h>]], [[int x = TIOCGWINSZ;]])],[zsh_cv_header_sys_ioctl_h_tiocgwinsz=yes],[zsh_cv_header_sys_ioctl_h_tiocgwinsz=no])]) + if test x$zsh_cv_header_sys_ioctl_h_tiocgwinsz = xyes; then + AC_DEFINE(GWINSZ_IN_SYS_IOCTL) + fi +fi + +AH_TEMPLATE([WINSIZE_IN_PTEM], +[Define if your should include sys/stream.h and sys/ptem.h.]) +AC_CACHE_CHECK(for streams headers including struct winsize, +ac_cv_winsize_in_ptem, +[AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <sys/stream.h> +#include <sys/ptem.h>]], [[struct winsize wsz]])],[ac_cv_winsize_in_ptem=yes],[ac_cv_winsize_in_ptem=no])]) +if test x$ac_cv_winsize_in_ptem = xyes; then + AC_DEFINE(WINSIZE_IN_PTEM) +fi + +dnl ------------------- +dnl CHECK FOR LIBRARIES +dnl ------------------- + +dnl On some systems, modules need to be linked against libc explicitly, +dnl in case they require objects that exist only in the static version +dnl and might not be compiled into the zsh executable. +dnl On ReliantUNIX -lc better be the last library, else funny things +dnl may happen. +AC_CHECK_LIB(c, printf, [LIBS="$LIBS -lc"]) + +AC_CHECK_LIB(m, pow) + +AC_CHECK_LIB(rt, clock_gettime) + +dnl Various features of ncurses depend on having the right header +dnl (the system's own curses.h may well not be good enough). +dnl So don't search for ncurses unless we found the header. +if test x$ac_cv_header_ncurses_h = xyes || test x$ac_cv_header_ncurses_ncurses_h = xyes || test x$ac_cv_header_ncursesw_ncurses_h = xyes; then + ncursesw_test=ncursesw + ncurses_test=ncurses +else + ncursesw_test= + ncurses_test= +fi + +dnl Prefer BSD termcap library to SysV curses library, except on certain +dnl SYSV-derived systems. However, if we find terminfo and termcap +dnl stuff in the same library we will use that; typically this +dnl is ncurses or curses. +dnl On pre-11.11 HPUX, Hcurses is reported to work better than curses. +dnl Prefer ncurses to curses on all systems. tinfo isn't very common now. +AC_ARG_WITH(term-lib, +AS_HELP_STRING([--with-term-lib=LIBS],[search space-separated LIBS for terminal handling]), +[if test "x$withval" != xno && test "x$withval" != x ; then + termcap_curses_order="$withval" + AC_SEARCH_LIBS(tigetstr, [$termcap_curses_order]) +else + termcap_curses_order="$ncursesw_test tinfo termcap $ncurses_test curses" +fi], +[case "$host_os" in + solaris*) + termcap_curses_order="$ncursesw_test $ncurses_test curses termcap" ;; + hpux10.*|hpux11.*) + DL_EXT="${DL_EXT=sl}" + termcap_curses_order="Hcurses $ncursesw_test $ncurses_test curses termcap" ;; + *) + termcap_curses_order="$ncursesw_test tinfo termcap $ncurses_test curses" ;; +esac])dnl + +AH_TEMPLATE([ZSH_NO_XOPEN], +[Define if _XOPEN_SOURCE_EXTENDED should not be defined to avoid clashes]) +AC_CACHE_CHECK(if _XOPEN_SOURCE_EXTENDED should not be defined, +zsh_cv_no_xopen, +[[case "$host_os" in + *freebsd5*|*freebsd6.[012]*|*aix*) + zsh_cv_no_xopen=yes + ;; + *) + zsh_cv_no_xopen=no + ;; +esac]]) +if test x$zsh_cv_no_xopen = xyes; then + AC_DEFINE(ZSH_NO_XOPEN) +fi + +dnl Check for tigetflag (terminfo) before tgetent (termcap). +dnl That's so that on systems where termcap and [n]curses are +dnl both available and both contain termcap functions, while +dnl only [n]curses contains terminfo functions, we only link against +dnl [n]curses. +AC_SEARCH_LIBS(tigetflag, [$termcap_curses_order]) +AC_SEARCH_LIBS(tgetent, [$termcap_curses_order], + true, + AC_MSG_FAILURE(["No terminal handling library was found on your system. +This is probably a library called 'curses' or 'ncurses'. You may +need to install a package called 'curses-devel' or 'ncurses-devel' on your +system."], 255)) +AC_CHECK_HEADERS(curses.h, [], +[AC_CACHE_CHECK(for Solaris 8 curses.h mistake, ac_cv_header_curses_solaris, +AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <curses.h>]], [[]])],[ac_cv_header_curses_h=yes +ac_cv_header_curses_solaris=yes],[ac_cv_header_curses_h=no +ac_cv_header_curses_solaris=no])) +if test x$ac_cv_header_curses_solaris = xyes; then +AC_DEFINE(HAVE_CURSES_H) +fi]) + +dnl If our terminal library is not ncurses, don't try including +dnl any ncurses headers. +AC_CACHE_CHECK(if we need to ignore ncurses, zsh_cv_ignore_ncurses, +[case $LIBS in + *-lncurses*) + zsh_cv_ignore_ncurses=no + ;; + *) + zsh_cv_ignore_ncurses=yes + ;; +esac]) + +AC_SEARCH_LIBS(getpwnam, nsl) + +dnl I am told that told that unicos reqire these for nis_list +if test `echo $host_os | sed 's/^\(unicos\).*/\1/'` = unicos; then + LIBS="-lcraylm -lkrb -lnisdb -lnsl -lrpcsvc $LIBS" +fi + +if test "x$dynamic" = xyes; then + AC_CHECK_LIB(dl, dlopen) +fi + +if test x$enable_cap = xyes; then + AC_CHECK_LIB(cap, cap_get_proc) +fi + +AC_CHECK_LIB(socket, socket) +AC_SEARCH_LIBS(gethostbyname2, bind) + +case $LIBS in + *-lbind*) + AC_CHECK_HEADERS(bind/netdb.h) + ;; +esac + +dnl --------------- +dnl CHECK FOR ICONV +dnl --------------- + +dnl Find iconv. It may be in libiconv and may be iconv() or libiconv() +if test "x$ac_cv_header_iconv_h" = "xyes"; then + AC_CHECK_FUNC(iconv, ac_found_iconv=yes, ac_found_iconv=no) + if test "x$ac_found_iconv" = "xno"; then + AC_CHECK_LIB(iconv, iconv, ac_found_iconv=yes) + if test "x$ac_found_iconv" = "xno"; then + AC_CHECK_LIB(iconv, libiconv, ac_found_iconv=yes) + fi + if test "x$ac_found_iconv" != "xno"; then + LIBS="-liconv $LIBS" + fi + else + dnl Handle case where there is a native iconv but iconv.h is from libiconv + AC_CHECK_DECL(_libiconv_version, + [ AC_CHECK_LIB(iconv, libiconv, LIBS="-liconv $LIBS") ],, + [ #include <iconv.h> ]) + fi +fi +AH_TEMPLATE([ICONV_FROM_LIBICONV], +[Define to 1 if iconv() is linked from libiconv]) +if test "x$ac_found_iconv" = xyes; then + AC_DEFINE(HAVE_ICONV, 1, [Define if you have the iconv() function.]) + AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include <iconv.h>]], [[int myversion = _libiconv_version]])],[AC_DEFINE(ICONV_FROM_LIBICONV)],[]) +fi + +dnl Check if iconv uses const in prototype declaration +if test "x$ac_found_iconv" = "xyes"; then + AC_CACHE_CHECK(for iconv declaration, ac_cv_iconv_const, + [AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <stdlib.h> + #include <iconv.h>]], + [[#ifdef __cplusplus + "C" + #endif + #if defined(__STDC__) || defined(__cplusplus) + size_t iconv (iconv_t cd, char * *inbuf, size_t *inbytesleft, char * *outbuf, size_t *outbytesleft); + #else + size_t iconv(); + #endif]])], + [ac_cv_iconv_const=], + [ac_cv_iconv_const=const])]) + AC_DEFINE_UNQUOTED([ICONV_CONST], $ac_cv_iconv_const, + [Define as const if the declaration of iconv() needs const.]) +fi + +if test x$enable_pcre = xyes; then +dnl pcre-config should probably be employed here +dnl AC_SEARCH_LIBS(pcre_compile, pcre) + LIBS="`$ac_cv_prog_PCRECONF --libs` $LIBS" +fi + +dnl --------------------- +dnl CHECK TERMCAP LIBRARY +dnl --------------------- +dnl Checks for external variable ospeed in the termcap library. +AC_CACHE_CHECK(if an include file defines ospeed, +zsh_cv_decl_ospeed_include_defines, +[AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include <sys/types.h> +#if HAVE_TERMIOS_H +#include <termios.h> +#endif +#if HAVE_TERMCAP_H +#include <termcap.h> +#endif]], [[ospeed = 0;]])],[zsh_cv_decl_ospeed_include_defines=yes],[zsh_cv_decl_ospeed_include_defines=no])]) + +if test x$zsh_cv_decl_ospeed_include_defines = xno; then + AC_CACHE_CHECK(if you must define ospeed, + zsh_cv_decl_ospeed_must_define, + [AC_LINK_IFELSE([AC_LANG_PROGRAM([[]], [[extern short ospeed; ospeed = 0;]])],[zsh_cv_decl_ospeed_must_define=yes],[zsh_cv_decl_ospeed_must_define=no])]) +fi + +AH_TEMPLATE([HAVE_OSPEED], +[Define to 1 if your termcap library has the ospeed variable]) +AH_TEMPLATE([MUST_DEFINE_OSPEED], +[Define to 1 if you have ospeed, but it is not defined in termcap.h]) +if test x$zsh_cv_decl_ospeed_include_defines = xyes; then + AC_DEFINE(HAVE_OSPEED) +elif test x$zsh_cv_decl_ospeed_must_define = xyes; then + AC_DEFINE(HAVE_OSPEED) + AC_DEFINE(MUST_DEFINE_OSPEED) +fi + +if test x$gdbm != xno; then + AC_CHECK_HEADERS(gdbm.h) + AC_CHECK_LIB(gdbm, gdbm_open) +fi + +AC_CHECK_HEADERS(sys/xattr.h) + +dnl -------------- +dnl CHECK TYPEDEFS +dnl -------------- + +AC_TYPE_PID_T +AC_TYPE_OFF_T +AC_CHECK_TYPE(ino_t, unsigned long) +AC_TYPE_MODE_T +AC_TYPE_UID_T +AC_TYPE_SIZE_T + +dnl ------------------------------------------------ +dnl Check size of long and try to find a 64-bit type +dnl ------------------------------------------------ +dnl AC_CHECK_SIZEOF is no good, because we need the result here, +dnl and that doesn't seem to define a shell parameter. +AC_CACHE_CHECK(if long is 64 bits, zsh_cv_long_is_64_bit, +[AC_RUN_IFELSE([AC_LANG_SOURCE([[int main() { return sizeof(long) < 8; }]])],[zsh_cv_long_is_64_bit=yes],[zsh_cv_long_is_64_bit=no],[zsh_cv_long_is_64_bit=no])]) + +AH_TEMPLATE([ino_t], +[Define to `unsigned long' if <sys/types.h> doesn't define.]) +AH_TEMPLATE([LONG_IS_64_BIT], +[Definitions used when a long is less than eight byte, to try to + provide some support for eight byte operations. + + Note that ZSH_64_BIT_TYPE, OFF_T_IS_64_BIT, INO_T_IS_64_BIT do *not* get + defined if long is already 64 bits, since in that case no special handling + is required. + + Define to 1 if long is 64 bits]) +AH_TEMPLATE([ZSH_64_BIT_TYPE], +[Define to a 64 bit integer type if there is one, but long is shorter.]) +AH_TEMPLATE([ZSH_64_BIT_UTYPE], +[Define to an unsigned variant of ZSH_64_BIT_TYPE if that is defined.]) +AH_TEMPLATE([OFF_T_IS_64_BIT], +[Define to 1 if off_t is 64 bit (for large file support)]) +AH_TEMPLATE([INO_T_IS_64_BIT], +[Define to 1 if ino_t is 64 bit (for large file support).]) +if test x$zsh_cv_long_is_64_bit = xyes; then + AC_DEFINE(LONG_IS_64_BIT) +else + AC_CACHE_CHECK(if off_t is 64 bit, zsh_cv_off_t_is_64_bit, + [AC_RUN_IFELSE([AC_LANG_SOURCE([[ +#include <sys/types.h> + +main() { return sizeof(off_t) < 8; } +]])],[zsh_cv_off_t_is_64_bit=yes],[zsh_cv_off_t_is_64_bit=no],[zsh_cv_off_t_is_64_bit=no])]) + if test x$zsh_cv_off_t_is_64_bit = xyes; then + AC_DEFINE(OFF_T_IS_64_BIT) + fi + + AC_CACHE_CHECK(if ino_t is 64 bit, zsh_cv_ino_t_is_64_bit, + [AC_RUN_IFELSE([AC_LANG_SOURCE([[ +#include <sys/types.h> + +main() { return sizeof(ino_t) < 8; } +]])],[zsh_cv_ino_t_is_64_bit=yes],[zsh_cv_ino_t_is_64_bit=no],[zsh_cv_ino_t_is_64_bit=no])]) + if test x$zsh_cv_ino_t_is_64_bit = xyes; then + AC_DEFINE(INO_T_IS_64_BIT) + fi + + if test x$enable_largefile != xno -o x$zsh_cv_off_t_is_64_bit = xyes \ + -o $zsh_cv_ino_t_is_64_bit = yes; then + AC_CACHE_CHECK(if compiler has a 64 bit type, zsh_cv_64_bit_type, + [zsh_64_BIT_TYPE(long long, zsh_cv_64_bit_type) + if test "$zsh_cv_64_bit_type" = no; then + zsh_64_BIT_TYPE(quad_t, zsh_cv_64_bit_type) + fi + if test "$zsh_cv_64_bit_type" = no; then + zsh_64_BIT_TYPE(__int64_t, zsh_cv_64_bit_type) + fi + dnl As a last resort, if we know off_t has 64 bits, use that as + dnl the 64-bit integer type. I don't dare try ino_t since there's + dnl probably nothing to stop that being unsigned. + if test "$zsh_cv_64_bit_type" = no && + test "$zsh_cv_off_t_is_64_bit" = yes; then + zsh_64_BIT_TYPE(off_t, zsh_cv_64_bit_type) + fi]) + if test "$zsh_cv_64_bit_type" != no; then + AC_DEFINE_UNQUOTED(ZSH_64_BIT_TYPE, $zsh_cv_64_bit_type) + + dnl Handle cases where unsigned type cannot be simply + dnl `unsigned ZSH_64_BIT_TYPE'. More tests may be required. + AC_CACHE_CHECK(for a corresponding unsigned 64 bit type, + zsh_cv_64_bit_utype, + [zsh_64_BIT_TYPE(unsigned $zsh_cv_64_bit_type, zsh_cv_64_bit_utype, + force) + if test "$zsh_cv_64_bit_utype" = no; then + zsh_64_BIT_TYPE(__uint64_t, zsh_cv_64_bit_utype) + fi]) + if test "$zsh_cv_64_bit_utype" != no; then + AC_DEFINE_UNQUOTED(ZSH_64_BIT_UTYPE, $zsh_cv_64_bit_utype) + fi + fi + fi +fi +AH_TEMPLATE([ZLONG_IS_LONG_LONG], +[Define to 1 if the zlong type uses long long int.]) +AH_TEMPLATE([ZLONG_IS_LONG_64], +[Define to 1 if the zlong type uses 64-bit long int.]) +if test "$zsh_cv_64_bit_type" = "long long"; then + dnl Remember this so we can get (s)printf output right. + AC_DEFINE(ZLONG_IS_LONG_LONG) +else + if test "$zsh_cv_64_bit_type" = "long"; then + AC_DEFINE(ZLONG_IS_LONG_64) + fi +fi + +dnl We'll blithely assume (f)printf supports the same types as sprintf. +AC_CACHE_CHECK(for %lld printf support, zsh_cv_printf_has_lld, +[AC_RUN_IFELSE([AC_LANG_SOURCE([[#include <stdio.h> +#include <string.h> +int main(int argc, char **argv) +{ + long long foo = ((long long)0xdead << 40) | 0xf00d; + char buf[80]; + sprintf(buf, "before%lldafter", foo); + if (!strcmp(buf, "before62677660341432333after")) { + return 0; + } + return 1; +} +]])],[zsh_cv_printf_has_lld=yes],[zsh_cv_printf_has_lld=no],[zsh_cv_printf_has_lld=no])]) +AH_TEMPLATE(PRINTF_HAS_LLD, +[Define to 1 if printf and sprintf support %lld for long long.]) +if test x$zsh_cv_printf_has_lld = xyes; then + AC_DEFINE(PRINTF_HAS_LLD) +fi + +dnl Check for sigset_t. Currently I'm looking in +dnl <sys/types.h> and <signal.h>. Others might need +dnl to be added. +AC_CACHE_CHECK(for sigset_t, zsh_cv_type_sigset_t, +[AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#define _POSIX_C_SOURCE 200809L +#include <sys/types.h> +#include <signal.h>]], [[sigset_t tempsigset;]])],[zsh_cv_type_sigset_t=yes],[zsh_cv_type_sigset_t=no])]) +AH_TEMPLATE([sigset_t], +[Define to `unsigned int' if <sys/types.h> or <signal.h> doesn't define]) +if test x$zsh_cv_type_sigset_t = xno; then + AC_DEFINE(sigset_t, unsigned int) +fi + +dnl check structures for high resolution timestamps +AC_CHECK_MEMBERS([struct stat.st_atim.tv_nsec, + struct stat.st_atimespec.tv_nsec, + struct stat.st_atimensec, + struct stat.st_mtim.tv_nsec, + struct stat.st_mtimespec.tv_nsec, + struct stat.st_mtimensec, + struct stat.st_ctim.tv_nsec, + struct stat.st_ctimespec.tv_nsec, + struct stat.st_ctimensec]) + +dnl Check for struct timezone since some old SCO versions do not define it +zsh_TYPE_EXISTS([ +#define _GNU_SOURCE 1 +#ifdef HAVE_SYS_TIME_H +# include <sys/time.h> +#endif +], struct timezone) + +dnl Check for struct timespec since POSIX only gained it in 2008 +zsh_TYPE_EXISTS([ +#define _GNU_SOURCE 1 +#ifdef HAVE_SYS_TIME_H +# include <sys/time.h> +#endif +], struct timespec) + +dnl Check for utmp structures, for watch +zsh_TYPE_EXISTS([ +#ifdef HAVE_SYS_TYPES_H +# include <sys/types.h> +#endif +#ifdef HAVE_UTMP_H +# include <utmp.h> +#endif +], struct utmp) +zsh_TYPE_EXISTS([ +#ifdef HAVE_SYS_TYPES_H +# include <sys/types.h> +#endif +#ifdef HAVE_UTMPX_H +# include <utmpx.h> +#endif +], struct utmpx) + +dnl Check contents of utmp structures +zsh_STRUCT_MEMBER([ +#ifdef HAVE_SYS_TYPES_H +# include <sys/types.h> +#endif +#ifdef HAVE_UTMP_H +# include <utmp.h> +#endif +], struct utmp, ut_host) +zsh_STRUCT_MEMBER([ +#ifdef HAVE_SYS_TYPES_H +# include <sys/types.h> +#endif +#ifdef HAVE_UTMPX_H +# include <utmpx.h> +#endif +], struct utmpx, ut_host) +zsh_STRUCT_MEMBER([ +#ifdef HAVE_SYS_TYPES_H +# include <sys/types.h> +#endif +#ifdef HAVE_UTMPX_H +# include <utmpx.h> +#endif +], struct utmpx, ut_xtime) +zsh_STRUCT_MEMBER([ +#ifdef HAVE_SYS_TYPES_H +# include <sys/types.h> +#endif +#ifdef HAVE_UTMPX_H +# include <utmpx.h> +#endif +], struct utmpx, ut_tv) + +dnl Check for inode numbers in directory entry structures +zsh_STRUCT_MEMBER([ +#ifdef HAVE_SYS_TYPES_H +# include <sys/types.h> +#endif +#ifdef HAVE_DIRENT_H +# include <dirent.h> +#endif +], struct dirent, d_ino) +zsh_STRUCT_MEMBER([ +#ifdef HAVE_SYS_TYPES_H +# include <sys/types.h> +#endif +#ifdef HAVE_DIRENT_H +# include <dirent.h> +#endif +], struct dirent, d_stat) +zsh_STRUCT_MEMBER([ +#ifdef HAVE_SYS_TYPES_H +# include <sys/types.h> +#endif +#ifdef HAVE_SYS_NDIR_H +# include <sys/ndir.h> +#endif +#ifdef HAVE_SYS_DIR_H +# include <sys/dir.h> +#endif +#ifdef HAVE_NDIR_H +# include <ndir.h> +#endif +], struct direct, d_ino) +zsh_STRUCT_MEMBER([ +#ifdef HAVE_SYS_TYPES_H +# include <sys/types.h> +#endif +#ifdef HAVE_SYS_NDIR_H +# include <sys/ndir.h> +#endif +#ifdef HAVE_SYS_DIR_H +# include <sys/dir.h> +#endif +#ifdef HAVE_NDIR_H +# include <ndir.h> +#endif +], struct direct, d_stat) + +dnl Check IPv6 socket address structure type +zsh_STRUCT_MEMBER([ +#ifdef HAVE_SYS_TYPES_H +# include <sys/types.h> +#endif +#include <netinet/in.h> +], struct sockaddr_in6, sin6_scope_id) + +dnl Check for h_errno external variable +AH_TEMPLATE([USE_LOCAL_H_ERRNO], +[Define to 1 if h_errno is not defined by the system.]) +AC_CACHE_CHECK(if we need our own h_errno, + zsh_cv_decl_h_errno_use_local, + [AC_LINK_IFELSE([AC_LANG_PROGRAM([[]], [[extern int h_errno; h_errno = 0;]])],[zsh_cv_decl_h_errno_use_local=no],[zsh_cv_decl_h_errno_use_local=yes])]) + +if test x$zsh_cv_decl_h_errno_use_local = xyes; then + AC_DEFINE(USE_LOCAL_H_ERRNO) +fi + +dnl --------------- +dnl CHECK FUNCTIONS +dnl --------------- + +dnl need to integrate this function +dnl AC_FUNC_STRFTIME + +AC_CHECK_FUNCS(strftime strptime mktime timelocal \ + difftime gettimeofday clock_gettime \ + select poll \ + readlink faccessx fchdir ftruncate \ + fstat lstat lchown fchown fchmod \ + fseeko ftello \ + mkfifo _mktemp mkstemp \ + waitpid wait3 \ + sigaction sigblock sighold sigrelse sigsetmask sigprocmask \ + killpg setpgid setpgrp tcsetpgrp tcgetattr nice \ + gethostname gethostbyname2 getipnodebyname \ + inet_aton inet_pton inet_ntop \ + getlogin getpwent getpwnam getpwuid getgrgid getgrnam \ + initgroups nis_list \ + setuid seteuid setreuid setresuid setsid \ + memcpy memmove strstr strerror strtoul \ + getrlimit getrusage \ + setlocale \ + isblank iswblank \ + uname \ + signgam tgamma \ + log2 \ + scalbn \ + putenv getenv setenv unsetenv xw\ + brk sbrk \ + pathconf sysconf \ + tgetent tigetflag tigetnum tigetstr setupterm initscr resize_term \ + getcchar setcchar waddwstr wget_wch win_wch use_default_colors \ + pcre_compile pcre_study pcre_exec \ + nl_langinfo \ + erand48 open_memstream \ + posix_openpt \ + wctomb iconv \ + grantpt unlockpt ptsname \ + htons ntohs \ + regcomp regexec regerror regfree \ + gdbm_open getxattr \ + realpath canonicalize_file_name \ + symlink getcwd \ + cygwin_conv_path \ + nanosleep \ + srand_deterministic \ + setutxent getutxent endutxent getutent) +AC_FUNC_STRCOLL + +# isinf() and isnan() can exist as either functions or macros. +AH_TEMPLATE([HAVE_ISINF], + [Define to 1 if you have the `isinf' macro or function.]) +AC_MSG_CHECKING([for isinf]) +AC_LINK_IFELSE([AC_LANG_SOURCE( +[[#include <math.h> +int main () { return (isinf(1.0) != 0); }]])], + [AC_MSG_RESULT([yes]) + AC_DEFINE([HAVE_ISINF])], + [AC_MSG_RESULT([no])]) + +AH_TEMPLATE([HAVE_ISNAN], + [Define to 1 if you have the `isnan' macro or function.]) +AC_MSG_CHECKING([for isnan]) +AC_LINK_IFELSE([AC_LANG_SOURCE([[ +#include <math.h> +int main () { return (isnan(1.0) != 0); }]])], + [AC_MSG_RESULT([yes]) + AC_DEFINE([HAVE_ISNAN])], + [AC_MSG_RESULT([no])]) + +AH_TEMPLATE([REALPATH_ACCEPTS_NULL], +[Define if realpath() accepts NULL as its second argument.]) +AC_CACHE_CHECK([if realpath accepts NULL], +zsh_cv_func_realpath_accepts_null, +[AC_RUN_IFELSE([AC_LANG_PROGRAM([ +#include <stdlib.h> +#include <limits.h> +],[ +exit(!realpath("/", (char*)0)); +])], +[zsh_cv_func_realpath_accepts_null=yes], +[zsh_cv_func_realpath_accepts_null=no], +[zsh_cv_func_realpath_accepts_null=$ac_cv_func_canonicalize_file_name])]) +if test x$zsh_cv_func_realpath_accepts_null = xyes; then + AC_DEFINE(REALPATH_ACCEPTS_NULL) +fi + +if test x$enable_cap = xyes; then + AC_CHECK_FUNCS(cap_get_proc) +fi + +dnl Check if tgetent accepts NULL (and will allocate its own termcap buffer) +dnl Some termcaps reportedly accept a zero buffer, but then dump core +dnl in tgetstr(). +dnl Under Cygwin test program crashes but exit code is still 0. So, +dnl we test for a file that porgram should create +AH_TEMPLATE([TGETENT_ACCEPTS_NULL], +[Define to 1 if tgetent() accepts NULL as a buffer.]) +AC_CACHE_CHECK(if tgetent accepts NULL, +zsh_cv_func_tgetent_accepts_null, +[AC_RUN_IFELSE([AC_LANG_SOURCE([[ +main() +{ + char buf[4096]; + int r1 = tgetent(buf, "vt100"); + int r2 = tgetent((char*)0,"vt100"); + if (r1 >= 0 && r1 == r2) { + char tbuf[1024], *u; + u = tbuf; + tgetstr("cl", &u); + creat("conftest.tgetent", 0640); + } + exit((r1 != r2) || r2 == -1); +} +]])],[if test -f conftest.tgetent; then + zsh_cv_func_tgetent_accepts_null=yes + else + zsh_cv_func_tgetent_accepts_null=no + fi],[zsh_cv_func_tgetent_accepts_null=no],[zsh_cv_func_tgetent_accepts_null=no])]) +if test x$zsh_cv_func_tgetent_accepts_null = xyes; then + AC_DEFINE(TGETENT_ACCEPTS_NULL) +fi +AC_CACHE_CHECK(if tgetent returns 0 on success, +zsh_cv_func_tgetent_zero_success, +[AC_RUN_IFELSE([AC_LANG_SOURCE([[ +main() +{ + char buf[4096]; + int r1 = tgetent(buf, "!@#$%^&*"); + int r2 = tgetent(buf, "vt100"); + if (r1 < 0 && r2 == 0) { + char tbuf[1024], *u; + u = tbuf; + tgetstr("cl", &u); + creat("conftest.tgetent0", 0640); + } + exit(r1 == r2); +} +]])],[if test -f conftest.tgetent0; then + zsh_cv_func_tgetent_zero_success=yes + else + zsh_cv_func_tgetent_zero_success=no + fi],[zsh_cv_func_tgetent_zero_success=no],[zsh_cv_func_tgetent_zero_success=no])]) +AH_TEMPLATE([TGETENT_SUCCESS], +[Define to what tgetent() returns on success (0 on HP-UX X/Open curses).]) +if test x$zsh_cv_func_tgetent_zero_success = xyes; then + AC_DEFINE(TGETENT_SUCCESS, 0) +else + AC_DEFINE(TGETENT_SUCCESS, 1) +fi + +AC_FUNC_MMAP +if test x$ac_cv_func_mmap_fixed_mapped = xyes; then + AC_CHECK_FUNCS(munmap msync) +fi + +if test x$ac_cv_func_setpgrp = xyes; then + AC_FUNC_GETPGRP +else + dnl If there is no setpgrp, the test for getpgrp(void) will fail + dnl because the program will not compile. However, in that case + dnl we can be reasonably confident we are not dealing with a + dnl Berkeleyesque system, so assume getpgrp does take void. + ac_cv_func_getpgrp_void=yes + AC_DEFINE(GETPGRP_VOID) +fi + +if test x$dynamic = xyes; then + AC_CHECK_FUNCS(dlopen dlerror dlsym dlclose load loadquery loadbind unload \ + shl_load shl_unload shl_findsym) +fi + +AH_TEMPLATE([XATTR_EXTRA_ARGS], +Define if getxattr() etc. require additional MacOS-style arguments) +if test x$ac_cv_func_getxattr = xyes && test x$ac_cv_header_sys_xattr_h = xyes +then + AC_CACHE_CHECK(if getxattr etc. are Linux-like, + zsh_cv_getxattr_linux, + [AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <sys/types.h> +#include <sys/xattr.h>]], + [[ + (void)listxattr("", 0, 0); + (void)getxattr("", "", 0, 0); + (void)setxattr("", "", "", 0, 0); + (void)removexattr("", ""); + ]])], + [zsh_cv_getxattr_linux=yes], + [zsh_cv_getxattr_linux=no])]) + + if test x$zsh_cv_getxattr_linux != xyes; then + AC_CACHE_CHECK(if getxattr etc. are MAC-like, + zsh_cv_getxattr_mac, + [AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <sys/types.h> +#include <sys/xattr.h>]], + [[(void)listxattr("", 0, 0, 0); + (void)getxattr("", "", 0, 0, 0, 0); + (void)setxattr("", "", "", 0, 0, 0); + (void)removexattr("", "", 0);]])], + [zsh_cv_getxattr_mac=yes], + [zsh_cv_getxattr_mac=no])]) + + if test x$zsh_cv_getxattr_mac = xyes; then + AC_DEFINE(XATTR_EXTRA_ARGS) + fi + fi +fi + +AC_CACHE_CHECK(if getxattr etc. are usable, +zsh_cv_use_xattr, +[if test x$zsh_cv_getxattr_linux = xyes || test x$zsh_cv_getxattr_mac = xyes +then +zsh_cv_use_xattr=yes +else +zsh_cv_use_xattr=no +fi]) + +dnl ------------- +dnl CHECK SIGNALS +dnl ------------- +dnl What style of signal do you have (POSIX, BSD, or SYSV)? +AH_TEMPLATE([POSIX_SIGNALS], +[Define to 1 if you use POSIX style signal handling.]) +AH_TEMPLATE([BSD_SIGNALS], +[Define to 1 if you use BSD style signal handling (and can block signals).]) +AH_TEMPLATE([SYSV_SIGNALS], +[Define to 1 if you use SYS style signal handling (and can block signals).]) +AH_TEMPLATE([NO_SIGNAL_BLOCKING], +[Define to 1 if you have no signal blocking at all (bummer).]) +AC_MSG_CHECKING(what style of signals to use) +if test x$ac_cv_func_sigaction = xyes && test x$ac_cv_func_sigprocmask = xyes; then + signals_style=POSIX_SIGNALS + AC_DEFINE(POSIX_SIGNALS) +elif test x$ac_cv_func_sigblock = xyes && test x$ac_cv_func_sigsetmask = xyes; then + signals_style=BSD_SIGNALS + AC_DEFINE(BSD_SIGNALS) +elif test x$ac_cv_func_sighold = xyes && test x$ac_cv_func_sigrelse = xyes; then + signals_style=SYSV_SIGNALS + AC_DEFINE(SYSV_SIGNALS) +else + signals_style=NO_SIGNAL_BLOCKING + AC_DEFINE(NO_SIGNAL_BLOCKING) +fi +AC_DEFINE_UNQUOTED($signals_style) +AC_MSG_RESULT($signals_style) + +dnl Where is <signal.h> located? Needed as input for signals.awk +AC_CACHE_CHECK(where signal.h is located, zsh_cv_path_signal_h, +[dnl Look at the output from the preprocessor. +dnl We should get lines of the form `# 1 "/usr/include/signal.h"' +dnl The following assumes the real definitions are in a file which +dnl contains the name `sig'; we could relax this if necessary, +dnl but then you can get a rather long list of files to test. +dnl The backslash substitution is to persuade cygwin to cough up +dnl slashes rather than doubled backslashes in the path. +echo "#include <signal.h>" > nametmp.c +sigfile_list="`$CPP $CPPFLAGS nametmp.c | +sed -n -e 's/^#line[ ].*\"\(.*\)\"/\1/p' \ + -e 's/^#[ ].*\"\(.*\)\"/\1/p' | +sed 's/\\\\\\\\/\//g' | +$AWK '{ if ($1 ~ /sig/) files[[$1]] = $1 } + END { for (var in files) print var }'`" +rm -f nametmp.c +if test -z "$sigfile_list"; then + dnl In case we don't get the stuff from the preprocesor, use the old + dnl list of standard places. + sigfile_list="/usr/include/sys/iso/signal_iso.h +/usr/include/bsd/sys/signal.h +/usr/include/signum.h +/usr/include/asm/signum.h +/usr/include/asm/signal.h +/usr/include/linux/signal.h +/usr/include/sys/signal.h +/usr/include/bits/signum.h +/dev/null" +fi +for SIGNAL_TRY_H in $sigfile_list +do + dnl Try to make sure it doesn't get confused by files that don't + dnl have real signal definitions in, but do #define SIG* by counting + dnl the number of signals. Maybe we could even check for e.g. SIGHUP? + nsigs=`test -f $SIGNAL_TRY_H && \ + grep '#[ ]*define[ ][ ]*SIG[0-9A-Z]*[ ]*[0-9][0-9]*' $SIGNAL_TRY_H | \ + wc -l | sed 's/[ ]//g'` + if test "x$nsigs" != x && test "$nsigs" -ge 7 + then + SIGNAL_H="$SIGNAL_H $SIGNAL_TRY_H" + fi +done +if test "x$SIGNAL_H" = x; then + AC_MSG_ERROR(SIGNAL MACROS NOT FOUND: please report to developers) +fi +zsh_cv_path_signal_h="$SIGNAL_H" +]) +SIGNAL_H="$zsh_cv_path_signal_h" +AC_SUBST(SIGNAL_H)dnl + +dnl Where are error names located? Needed as input for errnames1.awk +AC_CACHE_CHECK(where error names are located, zsh_cv_path_errno_h, +[dnl Look at the output from the preprocessor. +dnl We should get lines of the form `# 1 "/usr/include/errno.h"' +dnl The following assumes the real definitions are in a file which +dnl contains the name `err'; we could relax this if necessary, +dnl but then you can get a rather long list of files to test. +dnl The backslash substitution is to persuade cygwin to cough up +dnl slashes rather than doubled backslashes in the path. +echo "#include <errno.h>" > nametmp.c +errfile_list="`$CPP $CPPFLAGS nametmp.c | +sed -n -e 's/^#line[ ].*\"\(.*\)\"/\1/p' \ + -e 's/^#[ 0-9].*\"\(.*\)\"/\1/p' | +sed 's/\\\\\\\\/\//g' | +$AWK '{ if ($1 ~ /err/) files[[$1]] = $1 } + END { for (var in files) print var }'`" +rm -f nametmp.c +for ERRNO_TRY_H in $errfile_list /dev/null +do + dnl Try to make sure it doesn't get confused by files that don't + dnl have real error definitions in. Count definitions to make sure. + dnl Definitions of error numbers have become more and more general, so + dnl make a list of files containing any definitions in and keep them all. + dnl Careful with cut and paste in the pattern: the square brackets + dnl must contain a space and a tab. + nerrs=`test -f $ERRNO_TRY_H && \ + $EGREP '#[ ]*define[ ][ ]*E[0-9A-Z]*[ ]*(_HURD_ERRNO )?\(?[_A-Z0-9]' $ERRNO_TRY_H | \ + wc -l | sed 's/[ ]//g'` + if test "x$nerrs" != x && test "$nerrs" -ge 1 + then + ERRNO_H="$ERRNO_H $ERRNO_TRY_H" + fi +done +if test x"$ERRNO_H" = x; then + AC_MSG_ERROR(ERROR MACROS NOT FOUND: please report to developers) +fi +zsh_cv_path_errno_h="$ERRNO_H" +]) +ERRNO_H="$zsh_cv_path_errno_h" +AC_SUBST(ERRNO_H)dnl + +AC_CACHE_CHECK(location of curses header, zsh_cv_path_curses_header, +[if test x$zsh_cv_ignore_ncurses = xyes; then + if test x$ac_cv_header_curses_h = xyes; then + zsh_cv_path_curses_header=curses.h + else + zsh_cv_path_curses_header=none + fi +elif test x$ac_cv_header_ncursesw_ncurses_h = xyes; then + zsh_cv_path_curses_header=ncursesw/ncurses.h +elif test x$ac_cv_header_ncurses_ncurses_h = xyes; then + zsh_cv_path_curses_header=ncurses/ncurses.h +elif test x$ac_cv_header_ncurses_h = xyes; then + zsh_cv_path_curses_header=ncurses.h +elif test x$ac_cv_header_curses_h = xyes; then + zsh_cv_path_curses_header=curses.h +else + zsh_cv_path_curses_header=none +fi]) +AH_TEMPLATE([ZSH_HAVE_CURSES_H], +[Define to 1 if some variant of a curses header can be included]) +if test x$zsh_cv_path_curses_header != xnone; then + AC_DEFINE(ZSH_HAVE_CURSES_H) + ZSH_CURSES_H=$zsh_cv_path_curses_header +else + ZSH_CURSES_H= +fi +AC_SUBST(ZSH_CURSES_H) + +dnl Where are curses key definitions located? Need for keypad() mode. +AC_CACHE_CHECK(where curses key definitions are located, zsh_cv_path_curses_keys_h, +[dnl This is an identical trick to errno.h, except we use ncurses.h +dnl if we can. +if test x$zsh_cv_path_curses_header = xnone; then + echo >nametmp.c +else + echo "#include <$zsh_cv_path_curses_header>" >nametmp.c +fi + +curses_list="`$CPP $CPPFLAGS nametmp.c | +sed -n -e 's/^#line[ ].*\"\(.*\)\"/\1/p' \ + -e 's/^#[ 0-9].*\"\(.*\)\"/\1/p' | +sed 's/\\\\\\\\/\//g' | +$AWK '{ if ($1 ~ /\.h/) files[[$1]] = $1 } + END { for (var in files) print var }'`" +rm -f nametmp.c +for CURSES_TRY_H in $curses_list /dev/null +do + nkeys=`test -f $CURSES_TRY_H && \ + $EGREP '#[ ]*define[ ][ ]*KEY_' $CURSES_TRY_H | \ + wc -l | sed 's/[ ]//g'` + if test "x$nkeys" != x && test "$nkeys" -ge 10 + then + CURSES_KEYS_H=$CURSES_TRY_H + break + fi +done +zsh_cv_path_curses_keys_h="$CURSES_KEYS_H" +]) +CURSES_KEYS_H="$zsh_cv_path_curses_keys_h" +AC_SUBST(CURSES_KEYS_H)dnl + +dnl See if there are variants of term.h. For testing each one +dnl we include the most likely variant of the curses header. +AC_CHECK_HEADERS(ncursesw/term.h, +true, true, +[#include <ncursesw/ncurses.h>]) +AC_CHECK_HEADERS(ncurses/term.h, +true, true, +[#include <ncurses/ncurses.h>]) +AC_CHECK_HEADERS(term.h, +true, true, +[#include <curses.h>]) + +dnl See if term.h is bundled along with the curses library we +dnl are using. If this isn't the default system curses, compilation +dnl could barf unless we include from the right subdirectory. +AC_CACHE_CHECK(where term.h is located, zsh_cv_path_term_header, +[case x$zsh_cv_path_curses_header in + xncursesw/*) + if test x$ac_cv_header_ncursesw_term_h = xyes; then + zsh_cv_path_term_header=ncursesw/term.h + fi + ;; + xncurses/*) + if test x$ac_cv_header_ncurses_term_h = xyes; then + zsh_cv_path_term_header=ncurses/term.h + fi + ;; +esac +if test x$zsh_cv_path_term_header = x; then + if test x$ac_cv_header_term_h = xyes; then + zsh_cv_path_term_header=term.h + else + zsh_cv_path_term_header=none + fi +fi]) + +AH_TEMPLATE([ZSH_HAVE_TERM_H], +[Define to 1 if some variant of term.h can be included]) +AH_TEMPLATE([HAVE_BOOLCODES], +[Define if you have the termcap boolcodes symbol.]) +AH_TEMPLATE([HAVE_NUMCODES], +[Define if you have the termcap numcodes symbol.]) +AH_TEMPLATE([HAVE_STRCODES], +[Define if you have the termcap strcodes symbol.]) +AH_TEMPLATE([HAVE_BOOLNAMES], +[Define if you have the terminfo boolnames symbol.]) +AH_TEMPLATE([HAVE_NUMNAMES], +[Define if you have the terminfo numnames symbol.]) +AH_TEMPLATE([HAVE_STRNAMES], +[Define if you have the terminfo strnames symbol.]) +AH_TEMPLATE([TGOTO_PROTO_MISSING], +[Define if there is no prototype for the tgoto() terminal function.]) + +if test x$zsh_cv_path_term_header != xnone; then + AC_DEFINE(ZSH_HAVE_TERM_H) + ZSH_TERM_H=$zsh_cv_path_term_header + if test x$zsh_cv_path_curses_header != xnone; then + term_includes="#include <$zsh_cv_path_curses_header> +#include <$zsh_cv_path_term_header>" + else + term_includes="#include <$zsh_cv_path_term_header>" + fi + + AC_MSG_CHECKING(if boolcodes is available) + AC_LINK_IFELSE([AC_LANG_PROGRAM([[$term_includes]], [[char **test = boolcodes; puts(*test);]])],[AC_DEFINE(HAVE_BOOLCODES) boolcodes=yes],[boolcodes=no]) + AC_MSG_RESULT($boolcodes) + + AC_MSG_CHECKING(if numcodes is available) + AC_LINK_IFELSE([AC_LANG_PROGRAM([[$term_includes]], [[char **test = numcodes; puts(*test);]])],[AC_DEFINE(HAVE_NUMCODES) numcodes=yes],[numcodes=no]) + AC_MSG_RESULT($numcodes) + + AC_MSG_CHECKING(if strcodes is available) + AC_LINK_IFELSE([AC_LANG_PROGRAM([[$term_includes]], [[char **test = strcodes; puts(*test);]])],[AC_DEFINE(HAVE_STRCODES) strcodes=yes],[strcodes=no]) + AC_MSG_RESULT($strcodes) + + AC_MSG_CHECKING(if boolnames is available) + AC_LINK_IFELSE([AC_LANG_PROGRAM([[$term_includes]], [[char **test = boolnames; puts(*test);]])],[AC_DEFINE(HAVE_BOOLNAMES) boolnames=yes],[boolnames=no]) + AC_MSG_RESULT($boolnames) + + AC_MSG_CHECKING(if numnames is available) + AC_LINK_IFELSE([AC_LANG_PROGRAM([[$term_includes]], [[char **test = numnames; puts(*test);]])],[AC_DEFINE(HAVE_NUMNAMES) numnames=yes],[numnames=no]) + AC_MSG_RESULT($numnames) + + AC_MSG_CHECKING(if strnames is available) + AC_LINK_IFELSE([AC_LANG_PROGRAM([[$term_includes]], [[char **test = strnames; puts(*test);]])],[AC_DEFINE(HAVE_STRNAMES) strnames=yes],[strnames=no]) + AC_MSG_RESULT($strnames) + + dnl There are apparently defective terminal library headers on some + dnl versions of Solaris before 11. + AC_MSG_CHECKING(if tgoto prototype is missing) + tgoto_includes="$term_includes +/* guaranteed to clash with any valid tgoto prototype */ +extern void tgoto(int **stuff, float **more_stuff);" + AC_LINK_IFELSE([AC_LANG_PROGRAM([[$tgoto_includes]], [[int *stuff; float *more_stuff; tgoto(&stuff, &more_stuff);]])],[AC_DEFINE(TGOTO_PROTO_MISSING) tgotoprotomissing=yes],[tgotoprotomissing=no]) + AC_MSG_RESULT($tgotoprotomissing) +else + ZSH_TERM_H= +fi +AC_SUBST(ZSH_TERM_H) + + +dnl ----------------------------------------------------- +dnl Look for the file containing the RLIMIT_* definitions +dnl ----------------------------------------------------- +dnl CALL FOR MORE (FEWER?) LOCATIONS: I've just copied the signal checking. +AC_CACHE_CHECK(where the RLIMIT macros are located,zsh_cv_path_rlimit_h, +[dnl Look at the output from the preprocessor. +dnl Copied from the search for the signal names above. +echo "#include <sys/resource.h>" >restmp.c +resourcefile_list="`$CPP $CPPFLAGS restmp.c | +sed -n -e 's/^#line[ ].*\"\(.*\)\"/\1/p' \ + -e 's/^#[ ].*\"\(.*\)\"/\1/p' | +sed 's/\\\\\\\\/\//g' | +$AWK '{ if ($1 ~ /resource/) files[[$1]] = $1 } + END { for (var in files) print var }'`" +rm -f restmp.c +if test -z "$resourcefile_list"; then + dnl No list: look at standard places. + resourcefile_list="/usr/include/bsd/sys/resource.h +/usr/include/asm/resource.h +/usr/include/linux/resource.h +/usr/include/sys/resource.h +/usr/include/bits/resource.h +/usr/include/resourcebits.h" +fi +for RESOURCE_H in $resourcefile_list /dev/null; +do + test -f $RESOURCE_H && \ + grep '#[ ]*define[ ][ ]*RLIMIT_[A-Z]*[ ]*[0-9A-Z][0-9]*' $RESOURCE_H > /dev/null && \ + break +done +zsh_cv_path_rlimit_h=$RESOURCE_H +if test x$RESOURCE_H = x"/dev/null" && test x$ac_cv_func_getrlimit = xyes; then + AC_MSG_WARN(RLIMIT MACROS NOT FOUND: please report to developers) +fi]) +RLIMITS_INC_H=$zsh_cv_path_rlimit_h +if test "$RLIMITS_INC_H" = "/dev/null"; then + RLIMITS_INC_H='' +fi +dnl rlimits.h only appears in dependencies if we are actually using it. +dnl We are using it any time we have getrlimit, though if the macros were +dnl not found we simply awk through /dev/null and fail to find them. +dnl Thus, limit won't work, but at least the shell will compile. +AC_SUBST(RLIMITS_INC_H)dnl + +dnl ------------------ +dnl rlimit type checks +dnl ------------------ +AH_TEMPLATE([RLIM_T_IS_QUAD_T], +[Define to 1 if struct rlimit uses quad_t.]) +AH_TEMPLATE([RLIM_T_IS_LONG_LONG], +[Define to 1 if struct rlimit uses long long]) +AH_TEMPLATE([RLIM_T_IS_UNSIGNED], +[Define to 1 if struct rlimit uses unsigned.]) +AH_TEMPLATE([rlim_t], +[Define to the type used in struct rlimit.]) +DEFAULT_RLIM_T=long +AC_CACHE_CHECK(if rlim_t is longer than a long, +zsh_cv_rlim_t_is_longer, +[AC_RUN_IFELSE([AC_LANG_SOURCE([[ +#ifdef HAVE_SYS_TIME_H +#include <sys/time.h> +#endif +#include <sys/resource.h> +main(){struct rlimit r;exit(sizeof(r.rlim_cur) <= sizeof(long));}]])],[zsh_cv_rlim_t_is_longer=yes],[zsh_cv_rlim_t_is_longer=no],[zsh_cv_rlim_t_is_longer=yes])]) +if test x$zsh_cv_rlim_t_is_longer = xyes; then + AC_CACHE_CHECK(if rlim_t is a quad, + zsh_cv_rlim_t_is_quad_t, + [AC_RUN_IFELSE([AC_LANG_SOURCE([[ +#ifdef HAVE_SYS_TIME_H +#include <sys/time.h> +#endif +#include <stdio.h> +#include <sys/resource.h> +main() { + struct rlimit r; + char buf[20]; + r.rlim_cur = 0; + sprintf(buf, "%qd", r.rlim_cur); + exit(strcmp(buf, "0")); +}]])],[zsh_cv_rlim_t_is_quad_t=yes],[zsh_cv_rlim_t_is_quad_t=no],[zsh_cv_rlim_t_is_quad_t=no])]) + if test x$zsh_cv_rlim_t_is_quad_t = xyes; then + AC_DEFINE(RLIM_T_IS_QUAD_T) + DEFAULT_RLIM_T=quad_t + else + AC_DEFINE(RLIM_T_IS_LONG_LONG) + DEFAULT_RLIM_T='long long' + fi +else + AC_CACHE_CHECK(if the rlim_t is unsigned, + zsh_cv_type_rlim_t_is_unsigned, + [AC_RUN_IFELSE([AC_LANG_SOURCE([[ +#ifdef HAVE_SYS_TIME_H +#include <sys/time.h> +#endif +#include <sys/resource.h> + main(){struct rlimit r;r.rlim_cur=-1;exit(r.rlim_cur<0);}]])],[zsh_cv_type_rlim_t_is_unsigned=yes],[zsh_cv_type_rlim_t_is_unsigned=no],[zsh_cv_type_rlim_t_is_unsigned=no])]) + if test x$zsh_cv_type_rlim_t_is_unsigned = xyes; then + AC_DEFINE(RLIM_T_IS_UNSIGNED) + DEFAULT_RLIM_T="unsigned $DEFAULT_RLIM_T" + fi +fi + +AC_CACHE_CHECK(for rlim_t, zsh_cv_type_rlim_t, +[AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ +#include <sys/types.h> +#ifdef HAVE_SYS_TIME_H +#include <sys/time.h> +#endif +#include <sys/resource.h>]], [[rlim_t l;]])],[zsh_cv_type_rlim_t=yes],[zsh_cv_type_rlim_t=no])]) +if test x$zsh_cv_type_rlim_t = xno; then + AC_DEFINE_UNQUOTED(rlim_t, $DEFAULT_RLIM_T) +fi + + +dnl On some systems the RLIMIT_* don't evaluate to integers at compile time +dnl (they may be enums). In this case we are not able to do preprocessor +dnl comparisons and need our tests to determine what values exist and +dnl if there are clashing definitions. + +zsh_LIMIT_PRESENT(RLIMIT_AIO_MEM) +zsh_LIMIT_PRESENT(RLIMIT_AIO_OPS) +zsh_LIMIT_PRESENT(RLIMIT_AS) +zsh_LIMIT_PRESENT(RLIMIT_LOCKS) +zsh_LIMIT_PRESENT(RLIMIT_MEMLOCK) +zsh_LIMIT_PRESENT(RLIMIT_NPROC) +zsh_LIMIT_PRESENT(RLIMIT_NTHR) +zsh_LIMIT_PRESENT(RLIMIT_NOFILE) +zsh_LIMIT_PRESENT(RLIMIT_PTHREAD) +zsh_LIMIT_PRESENT(RLIMIT_RSS) +zsh_LIMIT_PRESENT(RLIMIT_SBSIZE) +zsh_LIMIT_PRESENT(RLIMIT_TCACHE) +zsh_LIMIT_PRESENT(RLIMIT_VMEM) +zsh_LIMIT_PRESENT(RLIMIT_SIGPENDING) +zsh_LIMIT_PRESENT(RLIMIT_MSGQUEUE) +zsh_LIMIT_PRESENT(RLIMIT_NICE) +zsh_LIMIT_PRESENT(RLIMIT_RTPRIO) +zsh_LIMIT_PRESENT(RLIMIT_POSIXLOCKS) +zsh_LIMIT_PRESENT(RLIMIT_NPTS) +zsh_LIMIT_PRESENT(RLIMIT_SWAP) +zsh_LIMIT_PRESENT(RLIMIT_KQUEUES) + +AH_TEMPLATE([RLIMIT_VMEM_IS_RSS], +[Define to 1 if RLIMIT_VMEM and RLIMIT_RSS both exist and are equal.]) +AC_CACHE_CHECK(if RLIMIT_VMEM and RLIMIT_RSS are the same, +zsh_cv_rlimit_vmem_is_rss, +[AC_RUN_IFELSE([AC_LANG_SOURCE([[ +#include <sys/types.h> +#ifdef HAVE_SYS_TIME_H +#include <sys/time.h> +#endif +#include <sys/resource.h> +int main() +{ +int ret = 1; +#if defined(HAVE_RLIMIT_VMEM) && defined(HAVE_RLIMIT_RSS) +if (RLIMIT_RSS == RLIMIT_VMEM) ret = 0; +#endif +return ret; +}]])],[zsh_cv_rlimit_vmem_is_rss=yes],[zsh_cv_rlimit_vmem_is_rss=no],[zsh_cv_rlimit_vmem_is_rss=no])]) + +if test x$zsh_cv_rlimit_vmem_is_rss = xyes; then + AC_DEFINE(RLIMIT_VMEM_IS_RSS) +fi + + +AH_TEMPLATE([RLIMIT_VMEM_IS_AS], +[Define to 1 if RLIMIT_VMEM and RLIMIT_AS both exist and are equal.]) +AC_CACHE_CHECK(if RLIMIT_VMEM and RLIMIT_AS are the same, +zsh_cv_rlimit_vmem_is_as, +[AC_RUN_IFELSE([AC_LANG_SOURCE([[ +#include <sys/types.h> +#ifdef HAVE_SYS_TIME_H +#include <sys/time.h> +#endif +#include <sys/resource.h> +int main() +{ +int ret = 1; +#if defined(HAVE_RLIMIT_VMEM) && defined(HAVE_RLIMIT_AS) +if (RLIMIT_AS == RLIMIT_VMEM) ret = 0; +#endif +return ret; +}]])],[zsh_cv_rlimit_vmem_is_as=yes],[zsh_cv_rlimit_vmem_is_as=no],[zsh_cv_rlimit_vmem_is_as=no])]) + +if test x$zsh_cv_rlimit_vmem_is_as = xyes; then + AC_DEFINE(RLIMIT_VMEM_IS_AS) +fi + + +AH_TEMPLATE([RLIMIT_RSS_IS_AS], +[Define to 1 if RLIMIT_RSS and RLIMIT_AS both exist and are equal.]) +AC_CACHE_CHECK(if RLIMIT_RSS and RLIMIT_AS are the same, +zsh_cv_rlimit_rss_is_as, +[AC_RUN_IFELSE([AC_LANG_SOURCE([[ +#include <sys/types.h> +#ifdef HAVE_SYS_TIME_H +#include <sys/time.h> +#endif +#include <sys/resource.h> +int main() +{ +int ret = 1; +#if defined(HAVE_RLIMIT_RSS) && defined(HAVE_RLIMIT_AS) +if (RLIMIT_AS == RLIMIT_RSS) ret = 0; +#endif +return ret; +}]])],[zsh_cv_rlimit_rss_is_as=yes],[zsh_cv_rlimit_rss_is_as=no],[zsh_cv_rlimit_rss_is_as=no])]) + +if test x$zsh_cv_rlimit_rss_is_as = xyes; then + AC_DEFINE(RLIMIT_RSS_IS_AS) +fi + + +dnl -------------------------------------------- +dnl Check for members of struct rusage +dnl -------------------------------------------- +if test x$ac_cv_func_getrusage = xyes; then + AC_CHECK_MEMBERS([struct rusage.ru_maxrss, + struct rusage.ru_ixrss, + struct rusage.ru_idrss, + struct rusage.ru_isrss, + struct rusage.ru_minflt, + struct rusage.ru_majflt, + struct rusage.ru_nswap, + struct rusage.ru_inblock, + struct rusage.ru_oublock, + struct rusage.ru_msgsnd, + struct rusage.ru_msgrcv, + struct rusage.ru_nsignals, + struct rusage.ru_nvcsw, + struct rusage.ru_nivcsw],,, +[#include <sys/types.h> +#ifdef HAVE_SYS_TIME_H +#include <sys/time.h> +#endif +#include <sys/resource.h>]) +fi + + +dnl -------------------------------------------- +dnl CHECK FOR DEFAULT PATH (used for command -p) +dnl -------------------------------------------- +AC_CACHE_VAL(zsh_cv_cs_path, +[if getconf _CS_PATH >/dev/null 2>&1; then + zsh_cv_cs_path=`getconf _CS_PATH` +elif getconf CS_PATH >/dev/null 2>&1; then + zsh_cv_cs_path=`getconf CS_PATH` +elif getconf PATH >/dev/null 2>&1; then + zsh_cv_cs_path=`getconf PATH` +else + zsh_cv_cs_path="/bin:/usr/bin" +fi]) +AC_DEFINE_UNQUOTED(DEFAULT_PATH, "$zsh_cv_cs_path", +[The default path; used when running commands with command -p]) + + +dnl ---------------------------- +dnl CHECK FOR /dev/fd FILESYSTEM +dnl ---------------------------- +dnl FreeBSD 5 only supports /dev/fd/0 to /dev/fd/2 without mounting +dnl a special file system. As zsh needs arbitrary /dev/fd (typically +dnl >10) for its own use, we need to make sure higher fd's are available. +dnl Since we're using the shell, we're restricted to 0 to 9 but 3 should +dnl be good enough. +AH_TEMPLATE([PATH_DEV_FD], +[Define to the path of the /dev/fd filesystem.]) +AC_CACHE_CHECK(for /dev/fd filesystem, zsh_cv_sys_path_dev_fd, +[if test "$host_os" = cygwin; then +dnl In current (2008/12/01) versions of Cygwin these are present but don't +dnl seem to work smoothly for process substitution; no great surprise +dnl since getting processes to work at all on Cygwin is a big challenge. +dnl We'll rely on FIFOs, since they do what we need. +zsh_cv_sys_path_dev_fd=no +else +[for zsh_cv_sys_path_dev_fd in /proc/self/fd /dev/fd no; do + test x`echo ok|(exec 3<&0; cat $zsh_cv_sys_path_dev_fd/3 2>/dev/null;)` = xok && break + done] +fi]) +if test x$zsh_cv_sys_path_dev_fd != xno; then + AC_DEFINE_UNQUOTED(PATH_DEV_FD, "$zsh_cv_sys_path_dev_fd") +fi + +dnl --------------------------------- +dnl CHECK FOR RFS SUPERROOT DIRECTORY +dnl --------------------------------- +AC_CACHE_CHECK(for RFS superroot directory, zsh_cv_sys_superroot, +[test -d /../.LOCALROOT && zsh_cv_sys_superroot=yes || zsh_cv_sys_superroot=no]) +AH_TEMPLATE([HAVE_SUPERROOT], +[Define to 1 if you have RFS superroot directory.]) +if test x$zsh_cv_sys_superroot = xyes; then + AC_DEFINE(HAVE_SUPERROOT) +fi + +dnl CHECK FOR SYSTEMS REQUIRING GETCWD +AC_CACHE_CHECK(whether we should use the native getcwd, +zsh_cv_use_getcwd, +[case "${host_cpu}-${host_vendor}-${host_os}" in + *QNX*) zsh_cv_use_getcwd=yes ;; + *) zsh_cv_use_getcwd=no ;; + esac]) +AH_TEMPLATE([USE_GETCWD], +[Define to 1 if you need to use the native getcwd.]) +if test x$zsh_cv_use_getcwd = xyes; then + AC_DEFINE(USE_GETCWD) +fi + +dnl GNU getcwd() can allocate as much space as necessary for a +dnl directory name, preventing guessing games. +AH_TEMPLATE([GETCWD_CALLS_MALLOC], +[Define to 1 if getcwd() calls malloc to allocate memory.]) +if test x$ac_cv_func_getcwd = xyes; then + AC_CACHE_CHECK(whether getcwd calls malloc to allocate memory, + zsh_cv_getcwd_malloc, + [AC_RUN_IFELSE([AC_LANG_SOURCE([[ +#include <unistd.h> +#include <string.h> +int main() { + char buf[1024], *ptr1, *ptr2; + ptr1 = getcwd(buf, 1024); + ptr2 = getcwd(NULL, 0); + if (ptr1 && ptr2 && !strcmp(ptr1, ptr2)) { + return 0; + } + return 1; +} +]])],[zsh_cv_getcwd_malloc=yes],[zsh_cv_getcwd_malloc=no],[zsh_cv_getcwd_malloc=no])]) + if test x$zsh_cv_getcwd_malloc = xyes; then + AC_DEFINE(GETCWD_CALLS_MALLOC) + fi +fi + +dnl CHECK FOR setproctitle() FOR jobs -Z / ARGV0 +AH_TEMPLATE([HAVE_SETPROCTITLE], +[Define to 1 if the system supports `setproctitle' to change process name]) +AC_CHECK_FUNC(setproctitle,AC_DEFINE(HAVE_SETPROCTITLE), +AC_SEARCH_LIBS(setproctitle,util,AC_DEFINE(HAVE_SETPROCTITLE))) + +dnl ------------- +dnl CHECK FOR NIS +dnl ------------- +AH_TEMPLATE([HAVE_NIS], +[Define to 1 if you have NIS.]) +AC_CACHE_CHECK(for NIS, zsh_cv_sys_nis, +[test -f /usr/bin/ypcat && /usr/bin/ypcat passwd.byname > /dev/null 2>&1 && \ +zsh_cv_sys_nis=yes || zsh_cv_sys_nis=no]) +if test x$zsh_cv_sys_nis = xyes; then + AC_DEFINE(HAVE_NIS) +dnl Some systems (Solaris 2.x, Linux Redhat 5.x) require +dnl libnsl (Network Services Library) to find yp_all + AC_SEARCH_LIBS(yp_all, nsl) +fi + +dnl ----------------- +dnl CHECK FOR NISPLUS +dnl ----------------- +AH_TEMPLATE([HAVE_NIS_PLUS], +[Define to 1 if you have NISPLUS.]) +AC_CACHE_CHECK(for NIS+, zsh_cv_sys_nis_plus, +[test x$ac_cv_func_nis_list = xyes && test -f /usr/bin/nisls && \ + /usr/bin/nisls > /dev/null 2>&1 && \ +zsh_cv_sys_nis_plus=yes || zsh_cv_sys_nis_plus=no]) +if test x$zsh_cv_sys_nis_plus = xyes; then + AC_DEFINE(HAVE_NIS_PLUS) +fi + +dnl ---------------------------------------- +dnl CHECK FOR LOCATION OF {U,W}TMP{,X} FILES +dnl ---------------------------------------- +zsh_PATH_UTMP(utmp) +zsh_PATH_UTMP(wtmp) +zsh_PATH_UTMP(utmpx) +zsh_PATH_UTMP(wtmpx) + +dnl ------------------- +dnl brk/sbrk PROTOTYPES +dnl ------------------- +AC_CACHE_CHECK(for brk() prototype in <unistd.h>, +zsh_cv_header_unistd_h_brk_proto, +[AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <unistd.h> +double brk();]], [[int i;]])],[zsh_cv_header_unistd_h_brk_proto=no],[zsh_cv_header_unistd_h_brk_proto=yes])]) +AH_TEMPLATE([HAVE_BRK_PROTO], +[Define to 1 if there is a prototype defined for brk() on your system.]) +if test x$zsh_cv_header_unistd_h_brk_proto = xyes; then + AC_DEFINE(HAVE_BRK_PROTO) +fi + +AC_CACHE_CHECK(for sbrk() prototype in <unistd.h>, +zsh_cv_header_unistd_h_sbrk_proto, +[AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <unistd.h> +double sbrk();]], [[int i;]])],[zsh_cv_header_unistd_h_sbrk_proto=no],[zsh_cv_header_unistd_h_sbrk_proto=yes])]) +AH_TEMPLATE([HAVE_SBRK_PROTO], +[Define to 1 if there is a prototype defined for sbrk() on your system.]) +if test x$zsh_cv_header_unistd_h_sbrk_proto = xyes; then + AC_DEFINE(HAVE_SBRK_PROTO) +fi + +dnl ----------------------- +dnl mknod prototype for OSF +dnl ----------------------- +AH_TEMPLATE([HAVE_MKNOD_PROTO], +[Define to 1 if there is a prototype defined for mknod() on your system.]) +if test "$ac_cv_prog_cc_stdc" != no; then + AC_CACHE_CHECK(for mknod prototype in <sys/stat.h>, + zsh_cv_header_sys_stat_h_mknod_proto, + [AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <sys/stat.h> + int mknod(double x);]], [[int i;]])],[zsh_cv_header_sys_stat_h_mknod_proto=no],[zsh_cv_header_sys_stat_h_mknod_proto=yes])]) + if test x$zsh_cv_header_sys_stat_h_mknod_proto = xyes; then + AC_DEFINE(HAVE_MKNOD_PROTO) + fi +fi + +dnl ---------------------------------------- +dnl presence and location of ioctl prototype +dnl ---------------------------------------- +AC_CACHE_CHECK(for ioctl prototype in <unistd.h> or <termios.h>, +zsh_cv_header_unistd_h_termios_h_ioctl_proto, +[AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ +#ifdef HAVE_UNISTD_H +# include <unistd.h> +#endif +#ifdef HAVE_TERMIOS_H +# include <termios.h> +#endif +double ioctl();]], [[int i;]])],[zsh_cv_header_unistd_h_termios_h_ioctl_proto=no],[zsh_cv_header_unistd_h_termios_h_ioctl_proto=yes])]) + +if test x$zsh_cv_header_unistd_h_termios_h_ioctl_proto = xno; then + AC_CACHE_CHECK(for ioctl prototype in <sys/ioctl.h>, + zsh_cv_header_sys_ioctl_h_ioctl_proto, + [AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <sys/ioctl.h> + double ioctl();]], [[int i;]])],[zsh_cv_header_sys_ioctl_h_ioctl_proto=no],[zsh_cv_header_sys_ioctl_h_ioctl_proto=yes])]) +else + zsh_cv_header_sys_ioctl_h_ioctl_proto=no +fi + +AH_TEMPLATE([HAVE_IOCTL_PROTO], +[Define to 1 if there is a prototype defined for ioctl() on your system.]) +if test x$zsh_cv_header_unistd_h_termios_h_ioctl_proto = xyes || \ + test x$zsh_cv_header_sys_ioctl_h_ioctl_proto = xyes; then + AC_DEFINE(HAVE_IOCTL_PROTO) +fi +AH_TEMPLATE([IOCTL_IN_SYS_IOCTL], +[Define to 1 if we must include <sys/ioctl.h> to get a prototype for ioctl().]) +if test x$zsh_cv_header_sys_ioctl_h_ioctl_proto = xyes; then + AC_DEFINE(IOCTL_IN_SYS_IOCTL) +fi + +dnl ------------------- +dnl select() defined in <sys/socket.h>, ie BeOS R4.51 +dnl ------------------- +AH_TEMPLATE([SELECT_IN_SYS_SOCKET_H], +[Define to 1 if select() is defined in <sys/socket.h>, ie BeOS R4.51]) +if test x$ac_cv_header_sys_select_h != xyes; then + AC_CACHE_CHECK(for select() in <sys/socket.h>, + zsh_cv_header_socket_h_select_proto, + [AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <sys/socket.h>]], [[fd_set fd;]])],[zsh_cv_header_socket_h_select_proto=yes],[zsh_cv_header_socket_h_select_proto=no])]) + if test x$zsh_cv_header_socket_h_select_proto = xyes; then + AC_DEFINE(SELECT_IN_SYS_SOCKET_H) + fi +fi + +dnl ----------- +dnl named FIFOs +dnl ----------- +dnl +dnl Named FIFOs work well enough on recent versions of Cygwin +dnl to provide what we want. Simply enable them. +AC_CACHE_CHECK(if named FIFOs work, +zsh_cv_sys_fifo, +[if test "$host_os" = cygwin; then +zsh_cv_sys_fifo=yes +else +AC_RUN_IFELSE([AC_LANG_SOURCE([[ +#include <fcntl.h> +#include <signal.h> +main() +{ + char c; + int fd; + int pid, ret; + unlink("/tmp/fifo$$"); +#ifdef HAVE_MKFIFO + if(mkfifo("/tmp/fifo$$", 0600) < 0) +#else + if(mknod("/tmp/fifo$$", 0010600, 0) < 0) +#endif + exit(1); + pid = fork(); + if(pid < 0) + exit(1); + if(pid) { + fd = open("/tmp/fifo$$", O_RDONLY); + exit(fd < 0 || read(fd, &c, 1) != 1 || c != 'x'); + } + fd = open("/tmp/fifo$$", O_WRONLY); + ret = (fd < 0 || write(fd, "x", 1) < 1); + unlink("/tmp/fifo$$"); + exit(ret); +} +]])],[zsh_cv_sys_fifo=yes],[zsh_cv_sys_fifo=no],[zsh_cv_sys_fifo=yes]) +fi]) +AH_TEMPLATE([HAVE_FIFOS], +[Define to 1 if system has working FIFOs.]) +if test x$zsh_cv_sys_fifo = xyes; then + AC_DEFINE(HAVE_FIFOS) +fi + +dnl ----------- +dnl test for whether link() works +dnl for instance, BeOS R4.51 doesn't support hard links yet +dnl ----------- +AC_CACHE_CHECK(if link() works, +zsh_cv_sys_link, +[AC_RUN_IFELSE([AC_LANG_SOURCE([[ +#include <unistd.h> +#include <fcntl.h> +main() +{ + int ret; + char *tmpfile, *newfile; + tmpfile="/tmp/zsh.linktest$$"; + newfile="/tmp/zsh.linktest2$$"; + unlink(tmpfile); + unlink(newfile); + if(creat(tmpfile, 0644) < 0) + exit(1); + ret = link(tmpfile, newfile); + unlink(tmpfile); + unlink(newfile); + exit(ret<0); +} +]])],[zsh_cv_sys_link=yes],[zsh_cv_sys_link=no],[zsh_cv_sys_link=yes])]) +AH_TEMPLATE([HAVE_LINK], +[Define to 1 if system has working link().]) +if test x$zsh_cv_sys_link = xyes; then + AC_DEFINE(HAVE_LINK) +fi + +dnl ----------- +dnl test for whether kill(pid, 0) where pid doesn't exit +dnl should set errno to ESRCH, but some like BeOS R4.51 set to EINVAL +dnl ----------- +AC_CACHE_CHECK(if kill(pid, 0) returns ESRCH correctly, +zsh_cv_sys_killesrch, +[AC_RUN_IFELSE([AC_LANG_SOURCE([[ +#include <unistd.h> +#include <signal.h> +#include <errno.h> +main() +{ + int pid = (getpid() + 10000) & 0xffffff; + while (pid && (kill(pid, 0) == 0 || errno != ESRCH)) pid >>= 1; + exit(errno!=ESRCH); +} +]])],[zsh_cv_sys_killesrch=yes],[zsh_cv_sys_killesrch=no],[zsh_cv_sys_killesrch=yes])]) +AH_TEMPLATE([BROKEN_KILL_ESRCH], +[Define to 1 if kill(pid, 0) doesn't return ESRCH, ie BeOS R4.51.]) +if test x$zsh_cv_sys_killesrch = xno; then + AC_DEFINE(BROKEN_KILL_ESRCH) +fi + +dnl ----------- +dnl if POSIX, test for working sigsuspend(). +dnl for instance, BeOS R4.51 is broken. +dnl ----------- +AH_TEMPLATE([BROKEN_POSIX_SIGSUSPEND], +Define to 1 if sigsuspend() is broken, ie BeOS R4.51.]) +if test x$signals_style = xPOSIX_SIGNALS; then + AC_CACHE_CHECK(if POSIX sigsuspend() works, + zsh_cv_sys_sigsuspend, + [AC_RUN_IFELSE([AC_LANG_SOURCE([[ +#include <signal.h> +#include <unistd.h> +int child=0; +void handler(sig) + int sig; +{if(sig==SIGCHLD) child=1;} +main() { + struct sigaction act; + sigset_t set; + int pid, ret; + act.sa_handler = &handler; + sigfillset(&act.sa_mask); + act.sa_flags = 0; + sigaction(SIGCHLD, &act, 0); + sigfillset(&set); + sigprocmask(SIG_SETMASK, &set, 0); + pid=fork(); + if(pid==0) return 0; + if(pid>0) { + sigemptyset(&set); + ret=sigsuspend(&set); + exit(child==0); + } +} +]])],[zsh_cv_sys_sigsuspend=yes],[zsh_cv_sys_sigsuspend=no],[zsh_cv_sys_sigsuspend=yes])]) + if test x$zsh_cv_sys_sigsuspend = xno; then + AC_DEFINE(BROKEN_POSIX_SIGSUSPEND) + fi +fi + +dnl ----------- +dnl if found tcsetpgrp, test to see if it actually works +dnl for instance, BeOS R4.51 does not support it yet +dnl ----------- +AH_TEMPLATE([BROKEN_TCSETPGRP], +[Define to 1 if tcsetpgrp() doesn't work, ie BeOS R4.51.]) +AC_ARG_WITH(tcsetpgrp, +AS_HELP_STRING([--with-tcsetpgrp],[assumes that tcsetpgrp() exists and works correctly]),[ +case "x$withval" in + xyes) zsh_working_tcsetpgrp=yes;; + xno) zsh_working_tcsetpgrp=no;; + *) AC_MSG_ERROR(please use --with-tcsetpgrp=yes or --with-tcsetpgrp=no);; +esac],[zsh_working_tcsetpgrp=check]) +if test "x$ac_cv_func_tcsetpgrp" = xyes; then +case "x$zsh_working_tcsetpgrp" in + xcheck) + trap "" TTOU > /dev/null 2>&1 || : + AC_CACHE_CHECK(if tcsetpgrp() actually works, + zsh_cv_sys_tcsetpgrp, + [AC_RUN_IFELSE([AC_LANG_SOURCE([[ +#include <sys/types.h> +#include <unistd.h> +#include <fcntl.h> +main() { + int fd; + int ret; + fd=open("/dev/tty", O_RDWR); + if (fd < 0) exit(2); + ret=tcsetpgrp(fd, tcgetpgrp(fd)); + if (ret < 0) exit(1); + exit(0); +} +]])],[zsh_cv_sys_tcsetpgrp=yes],[ +case $? in + 1) zsh_cv_sys_tcsetpgrp=no;; + 2) zsh_cv_sys_tcsetpgrp=notty;; + *) zsh_cv_sys_tcsetpgrp=error;; +esac + ],[zsh_cv_sys_tcsetpgrp=yes])]) + case "x$zsh_cv_sys_tcsetpgrp" in + xno) AC_DEFINE(BROKEN_TCSETPGRP);; + xyes) :;; + xnotty) AC_MSG_ERROR([no controlling tty +Try running configure with --with-tcsetpgrp or --without-tcsetpgrp]);; + *) AC_MSG_ERROR([unexpected return status]);; + esac + trap - TTOU > /dev/null 2>&1 || : + ;; + xyes) :;; + xno) AC_DEFINE(BROKEN_TCSETPGRP);; + *) AC_MSG_ERROR([unexpected value zsh_working_tcsetpgrp=$zsh_working_tcsetpgrp]);; +esac +fi + +dnl ----------- +dnl test for faked getpwnam() entry, ie a single entry returned for any username +dnl for instance, BeOS R4.51 is not multiuser yet, and fakes getpwnam() +dnl test by looking up two usernames that shouldn't succeed, and compare entry +dnl ----------- +AH_TEMPLATE([GETPWNAM_FAKED], +[Define to 1 if getpwnam() is faked, ie BeOS R4.51.]) +if test x$ac_cv_func_getpwnam = xyes; then + AC_CACHE_CHECK(if getpwnam() is faked, + zsh_cv_sys_getpwnam_faked, + [AC_RUN_IFELSE([AC_LANG_SOURCE([[ +#include <pwd.h> +main() { + struct passwd *pw1, *pw2; + char buf[1024], name[1024]; + sprintf(buf, "%d:%d", getpid(), rand()); + pw1=getpwnam(buf); + if (pw1) strcpy(name, pw1->pw_name); + sprintf(buf, "%d:%d", rand(), getpid()); + pw2=getpwnam(buf); + exit(pw1!=0 && pw2!=0 && !strcmp(name, pw2->pw_name)); +} +]])],[zsh_cv_sys_getpwnam_faked=no],[zsh_cv_sys_getpwnam_faked=yes],[zsh_cv_sys_getpwnam_faked=no])]) + if test x$zsh_cv_sys_getpwnam_faked = xyes; then + AC_DEFINE(GETPWNAM_FAKED) + fi +fi + + +dnl --------------- +dnl check for the type of third argument of accept +dnl --------------- + +zsh_CHECK_SOCKLEN_T + +dnl --------------- +dnl Check for pty multiplexer for use in pty module. +dnl We need to open it read/write, so make sure it is writeable. +dnl Yet another test which won't work when cross-compiling. +dnl --------------- +AC_CACHE_CHECK(if your system has /dev/ptmx, +ac_cv_have_dev_ptmx, +[if test -w /dev/ptmx; then + ac_cv_have_dev_ptmx=yes +else + ac_cv_have_dev_ptmx=no +fi]) + +dnl -------- +dnl Check if the ptmx functions are usable. +dnl We need to be able to find the prototypes, which may +dnl require non-POSIX source definitions. So test to see +dnl if ptsname is correctly recognised as returning a char *. +dnl We do this by making sure a program where ptsname() is declared +dnl as returning int does *not* compile. +dnl On Linux we need the XOPEN extensions. The easiest way to get +dnl these is by defining _GNU_SOURCE. +dnl ------- +AH_TEMPLATE([USE_DEV_PTMX], +[Define to 1 if all the kit for using /dev/ptmx for ptys is available.]) +if test x$ac_cv_have_dev_ptmx = xyes -o x$ac_cv_func_posix_openpt = xyes && \ + test x$ac_cv_func_grantpt = xyes && \ + test x$ac_cv_func_unlockpt = xyes && \ + test x$ac_cv_func_ptsname = xyes; then + AC_CACHE_CHECK([if /dev/ptmx is usable], + ac_cv_use_dev_ptmx, + [AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#ifdef __linux +#define _GNU_SOURCE 1 +#endif +#include <stdlib.h> +int ptsname();]], [[]])],[ac_cv_use_dev_ptmx=no],[ac_cv_use_dev_ptmx=yes])]) + if test x$ac_cv_use_dev_ptmx = xyes; then + AC_DEFINE(USE_DEV_PTMX) + fi +fi + +dnl ----------------- +dnl multibyte support +dnl ----------------- +AC_ARG_ENABLE(multibyte, +AS_HELP_STRING([--enable-multibyte],[support multibyte characters]), +[zsh_cv_c_unicode_support=$enableval], +[AC_CACHE_VAL(zsh_cv_c_unicode_support, + AC_MSG_NOTICE([checking for functions supporting multibyte characters]) + [zfuncs_absent= +dnl +dnl Note that iswblank is not included and checked separately. +dnl As iswblank() was added to C long after the others, we still +dnl want to enabled unicode support even if iswblank is not available +dnl (we then just do the SPC+TAB approximation) +dnl + for zfunc in iswalnum iswcntrl iswdigit iswgraph iswlower iswprint \ +iswpunct iswspace iswupper iswxdigit mbrlen mbrtowc towupper towlower \ +wcschr wcscpy wcslen wcsncmp wcsncpy wcrtomb wcwidth wmemchr wmemcmp \ +wmemcpy wmemmove wmemset; do + AC_CHECK_FUNC($zfunc, + [:], [zfuncs_absent="$zfuncs_absent $zfunc"]) + done + if test x"$zfuncs_absent" = x; then + AC_MSG_NOTICE([all functions found, multibyte support enabled]) + zsh_cv_c_unicode_support=yes + else + AC_MSG_NOTICE([missing functions, multibyte support disabled]) + zsh_cv_c_unicode_support=no + fi + ]) +]) +AH_TEMPLATE([MULTIBYTE_SUPPORT], +[Define to 1 if you want support for multibyte character sets.]) + +dnl +dnl unicode9 support +dnl +AH_TEMPLATE([ENABLE_UNICODE9], +[Define to 1 if you want use unicode9 character widths.]) +AC_ARG_ENABLE(unicode9, +AS_HELP_STRING([--enable-unicode9],[compile with unicode9 character widths]), +[if test x$enableval = xyes; then + AC_DEFINE(ENABLE_UNICODE9) +fi]) + +AH_TEMPLATE([BROKEN_ISPRINT], +[Define to 1 if the isprint() function is broken under UTF-8 locale.]) + +if test x$zsh_cv_c_unicode_support = xyes; then + AC_DEFINE(MULTIBYTE_SUPPORT) + + dnl Test if wcwidth() and/or iswprint() is broken for + dnl zero-width combining characters, or + dnl some characters in the Latin Extended-B. + dnl If either of the functions is broken, both functions will be replaced + dnl by the ones from wcwidth9.h by defining ENABLE_UNICODE9. We will do + dnl this only if __STDC_ISO_10646__ is defined (or if building on macOS, + dnl where __STDC_ISO_10646__ is not defined but wchar_t is UCS). + dnl For the test we use a combining acute accent (\u0301) or + dnl a LATIN SMALL LETTER L WITH CURL (\u0234). + dnl We input it as UTF-8 since that is the standard we can rely + dnl upon most: we can't rely on a wchar_t being stored as a + dnl Unicode code point on all systems. + dnl The programme returns 0 only if all the conditions for brokenness + dnl are met: + dnl - the programme compiled, linked and ran + dnl - we successfully set a UTF-8 locale + dnl - the locale we set plausibly converted the UTF-8 string + dnl into the correct wide character + dnl - but wcwidth() or iswprint() is broken for the converted wide character. + dnl locale -a is a fallback; on most systems we should find en_US.UTF-8. + [locale_prog='char *my_locales[] = { + "en_US.UTF-8", "en_GB.UTF-8", "en.UTF-8", ' + locale_prog="$locale_prog"`locale -a 2>/dev/null | \ + sed -e 's/utf8/UTF-8/' | grep UTF-8 | \ + while read line; do echo " \"$line\","; done;` + locale_prog="$locale_prog 0 }; + #define _XOPEN_SOURCE + #include <stdlib.h> + #include <locale.h> + #include <wchar.h> + #include <wctype.h> + + int main() { + char **localep; + char comb_acute_mb[] = { (char)0xcc, (char)0x81 }; + char u_0234[] = { (char)0xc8, (char)0xb4 }; + wchar_t wc; + #if !defined(__STDC_ISO_10646__) && !defined(__APPLE__) + return 1; + #endif + + for (localep = my_locales; *localep; localep++) + if (setlocale(LC_ALL, *localep)) + break; + if (!*localep) + return 1; + if (mbtowc(&wc, comb_acute_mb, 2) == 2 && (wcwidth(wc) != 0 || !iswprint(wc))) + return 0; + if (mbtowc(&wc, u_0234, 2) == 2 && (wcwidth(wc) != 1 || !iswprint(wc))) + return 0; + return 1; + } + "] + + AC_CACHE_CHECK(if the wcwidth() and/or iswprint() functions are broken, + zsh_cv_c_broken_wcwidth, + [AC_RUN_IFELSE([AC_LANG_SOURCE([[$locale_prog]])],[zsh_cv_c_broken_wcwidth=yes],[zsh_cv_c_broken_wcwidth=no],[zsh_cv_c_broken_wcwidth=no])]) + if test x$zsh_cv_c_broken_wcwidth = xyes; then + AC_DEFINE(ENABLE_UNICODE9) + fi + + dnl Check if isprint() behaves correctly under UTF-8 locale. + dnl On some platform (maybe only on Mac OS X), isprint() returns + dnl true for all characters in the range from 0xa0 to 0xff if + dnl called under UTF-8 locale. + [locale_prog='char *my_locales[] = { + "en_US.UTF-8", "en_GB.UTF-8", "en.UTF-8", ' + locale_prog="$locale_prog"`locale -a 2>/dev/null | \ + sed -e 's/utf8/UTF-8/' | grep UTF-8 | \ + while read line; do echo " \"$line\","; done;` + locale_prog="$locale_prog 0 }; + #include <locale.h> + #include <ctype.h> + + int main() { + char **localep; + for (localep = my_locales; *localep; localep++) + if (setlocale(LC_ALL, *localep) && isprint(0xa0)) + return 0; + return 1; + } + "] + + AC_CACHE_CHECK(if the isprint() function is broken, + zsh_cv_c_broken_isprint, + [AC_RUN_IFELSE([AC_LANG_SOURCE([[$locale_prog]])],[zsh_cv_c_broken_isprint=yes],[zsh_cv_c_broken_isprint=no],[zsh_cv_c_broken_isprint=no])]) + if test x$zsh_cv_c_broken_isprint = xyes; then + AC_DEFINE(BROKEN_ISPRINT) + fi +fi + +dnl +dnl musl support +dnl +AH_TEMPLATE([LIBC_MUSL], +[Define to 1 if musl is being used as the C library]) +AC_ARG_ENABLE(libc-musl, +AS_HELP_STRING([--enable-libc-musl],[compile with musl as the C library]), +[if test x$enableval = xyes; then + AC_DEFINE(LIBC_MUSL) +fi]) + +dnl +dnl static user lookup +dnl +AC_ARG_ENABLE(dynamic-nss, + AS_HELP_STRING([--disable-dynamic-nss],[do not call + functions that will require dynamic NSS + modules]), +[zsh_cv_c_dynamic_nss=$enableval], +[]) + +AH_TEMPLATE([DISABLE_DYNAMIC_NSS], +[Define to 1 if you want to avoid calling functions that will require + dynamic NSS modules.]) +if test x$zsh_cv_c_dynamic_nss = xno; then + AC_DEFINE(DISABLE_DYNAMIC_NSS) +fi + +dnl --------------- +dnl dynamic loading +dnl --------------- +AH_TEMPLATE([HPUX10DYNAMIC], +[Define to 1 if you want to use dynamically loaded modules on HPUX 10.]) +L=N +INSTLIB="install.bin-\$(L)" +UNINSTLIB="uninstall.bin-\$(L)" +LINKMODS=NOLINKMODS +MOD_EXPORT= +MOD_IMPORT_VARIABLE= +MOD_IMPORT_FUNCTION= +aixdynamic=no +hpuxdynamic=no +if test "$ac_cv_func_load" = yes && + test "$ac_cv_func_unload" = yes && + test "$ac_cv_func_loadbind" = yes && + test "$ac_cv_func_loadquery" = yes; then + dnl Force AIXDYNAMIC even on newer versions that have dl family + if test "x$dynamic" = xyes; then + aixdynamic=yes + fi +elif test "$ac_cv_func_dlopen" != yes || + test "$ac_cv_func_dlsym" != yes || + test "$ac_cv_func_dlerror" != yes; then + if test "$ac_cv_func_shl_load" != yes || + test "$ac_cv_func_shl_unload" != yes || + test "$ac_cv_func_shl_findsym" != yes; then + dynamic=no + elif test "x$dynamic" = xyes; then + hpuxdynamic=yes + DL_EXT="${DL_EXT=sl}" + dnl autoheader won't allow us to define anything which isn't + dnl going into a header, and we can't undefine anything, so + dnl just define this anyway and rely on the later tests to + dnl define DYNAMIC or not. + AC_DEFINE(HPUX10DYNAMIC)dnl + fi +fi + +test -n "$GCC" && LDARG=-Wl, + +AH_TEMPLATE([DLSYM_NEEDS_UNDERSCORE], +[Define to 1 if an underscore has to be prepended to dlsym() argument.]) +AH_TEMPLATE([DYNAMIC_NAME_CLASH_OK], +[Define to 1 if multiple modules defining the same symbol are OK.]) +if test "x$aixdynamic" = xyes; then + DL_EXT="${DL_EXT=so}" + DLLD="${DLLD=$CC}" + zsh_cv_func_dlsym_needs_underscore=no + if test -n "$GCC"; then + DLLDFLAGS=${DLLDFLAGS=-shared} + else + DLLDFLAGS=${DLLDFLAGS=-bM:SRE} + fi + DLLDFLAGS=${DLLDFLAGS=} + EXTRA_LDFLAGS=${EXTRA_LDFLAGS=} + EXPOPT=${LDARG}-bE: + IMPOPT=${LDARG}-bI: + zsh_cv_sys_dynamic_clash_ok="${zsh_cv_sys_dynamic_clash_ok=yes}" + zsh_cv_sys_dynamic_rtld_global="${zsh_cv_sys_dynamic_rtld_global=yes}" + zsh_cv_sys_dynamic_execsyms="${zsh_cv_sys_dynamic_execsyms=yes}" + zsh_cv_sys_dynamic_strip_exe="${zsh_cv_sys_dynamic_strip_exe=yes}" + zsh_cv_sys_dynamic_strip_lib="${zsh_cv_sys_dynamic_strip_lib=yes}" + zsh_cv_shared_environ="${zsh_cv_shared_environ=yes}" +elif test "$host_os" = cygwin; then + DL_EXT="${DL_EXT=dll}" +##DLLD="${DLLD=dllwrap}" + DLLD="${DLLD=$CC}" +##DLLDFLAGS="${DLLDFLAGS=--export-all-symbols}" + DLLDFLAGS=${DLLDFLAGS=-shared -Wl,--export-all-symbols} + zsh_cv_func_dlsym_needs_underscore=no + DLLDFLAGS=${DLLDFLAGS=} + EXTRA_LDFLAGS=${EXTRA_LDFLAGS=} + zsh_cv_sys_dynamic_clash_ok="${zsh_cv_sys_dynamic_clash_ok=no}" + zsh_cv_sys_dynamic_rtld_global="${zsh_cv_sys_dynamic_rtld_global=yes}" + zsh_cv_sys_dynamic_execsyms="${zsh_cv_sys_dynamic_execsyms=no}" + zsh_cv_sys_dynamic_strip_exe="${zsh_cv_sys_dynamic_strip_exe=yes}" + zsh_cv_sys_dynamic_strip_lib="${zsh_cv_sys_dynamic_strip_lib=yes}" + # + # THAT SUCKS! and must be changed + # + zsh_cv_shared_environ="${zsh_cv_shared_environ=yes}" + LINKMODS=LINKMODS + MOD_EXPORT="__attribute__((__dllexport__))" + MOD_IMPORT_VARIABLE="__attribute__((__dllimport__))" + MOD_IMPORT_FUNCTION= +elif test "x$dynamic" = xyes; then + AC_CACHE_CHECK(if your system uses ELF binaries, + zsh_cv_sys_elf, + [AC_RUN_IFELSE([AC_LANG_SOURCE([[/* Test for whether ELF binaries are produced */ +#include <fcntl.h> +#include <stdlib.h> +main(argc, argv) +int argc; +char *argv[]; +{ + char b[4]; + int i = open(argv[0],O_RDONLY); + if(i == -1) + exit(1); /* fail */ + if(read(i,b,4)==4 && b[0]==127 && b[1]=='E' && b[2]=='L' && b[3]=='F') + exit(0); /* succeed (yes, it's ELF) */ + else + exit(1); /* fail */ +}]])],[zsh_cv_sys_elf=yes],[zsh_cv_sys_elf=no],[zsh_cv_sys_elf=yes])]) + + # We use [0-9]* in case statements, so need to change quoting + changequote(, ) + + DL_EXT="${DL_EXT=so}" + if test x$zsh_cv_sys_elf = xyes; then + case "$host" in + mips-sni-sysv4*) + # Forcibly set ld to native compiler to avoid obscure GCC problems + DLLD="${DLLD=/usr/ccs/bin/cc}" + DLLDARG="${LDARG}" + ;; + * ) + DLLD="${DLLD=$CC}" + DLLDARG="${LDARG}" + ;; + esac + else + case "$host" in + *openbsd*) + case "$host_os" in + openbsd[01].* | openbsd2.[0-7] | openbsd2.[0-7].*) + DLLD="${DLLD=ld}" + ;; + *) + DLLD="${DLLD=$CC}" + ;; + esac + DLLDARG="${LDARG}" + ;; + *darwin*) + DLLD="${DLLD=$CC}" + DLLDARG="" + ;; + *interix*) + DLLD="${DLLD=$CC}" + DLLDARG="" + ;; + * ) + DLLD="${DLLD=ld}" + DLLDARG="" + ;; + esac + fi + if test -n "$GCC"; then + case "$host_os" in + hpux*) DLLDFLAGS="${DLLDFLAGS=-shared}" ;; + darwin*) DLCFLAGS="${DLCFLAGS=-fno-common}" ;; + interix*) DLCFLAGS="${DLCFLAGS=}" ;; + *) DLCFLAGS="${DLCFLAGS=-fPIC}" ;; + esac + else + case "$host_os" in + hpux*) + DLCFLAGS="${DLCFLAGS=+z}" + DLLDFLAGS="${DLLDFLAGS=-b}" + ;; + sunos*) DLCFLAGS="${DLCFLAGS=-pic}" ;; + solaris*|sysv4*|esix*) DLCFLAGS="${DLCFLAGS=-KPIC}" ;; + esac + fi + case "$host_os" in + osf*) DLLDFLAGS="${DLLDFLAGS=-shared -expect_unresolved '*'}" ;; + *freebsd*|*netbsd*|linux*|irix*|gnu*|interix*|dragonfly*) DLLDFLAGS="${DLLDFLAGS=-shared}" ;; + sunos*) DLLDFLAGS="${DLLDFLAGS=-assert nodefinitions}" ;; + sysv4*|esix*) DLLDFLAGS="${DLLDFLAGS=-G $ldflags}" ;; + aix*) DLLDFLAGS="${DLLDFLAGS=-G -bexpall -lc}" ;; + solaris*|sysv4*|esix*) DLLDFLAGS="${DLLDFLAGS=-G}" ;; + darwin*) DLLDFLAGS="${DLLDFLAGS=-bundle -flat_namespace -undefined suppress}" ;; + beos*|haiku*) DLLDFLAGS="${DLLDFLAGS=-nostart}" ;; + openbsd*) + if test x$zsh_cv_sys_elf = xyes; then + DLLDFLAGS="${DLLDFLAGS=-shared -fPIC}" + else + case "$host_os" in + openbsd[01].* | openbsd2.[0-7] | openbsd2.[0-7].*) + DLLDFLAGS="${DLLDFLAGS=-Bshareable}" + ;; + *) + DLLDFLAGS="${DLLDFLAGS=-shared -fPIC}" + ;; + esac + fi + ;; + esac + case "$host" in + *-hpux*) EXTRA_LDFLAGS="${EXTRA_LDFLAGS=-Wl,-E}" ;; + *openbsd*) + if test x$zsh_cv_sys_elf = xyes; then + EXTRA_LDFLAGS="${EXTRA_LDFLAGS=-Wl,-E}" + fi + ;; + mips-sni-sysv4) + # + # unfortunately, we have different compilers + # that need different flags + # + if test -n "$GCC"; then + sni_cc_version=GCC + else + sni_cc_version=`$CC -V 2>&1 | head -1` + fi + case "$sni_cc_version" in + *CDS*|GCC ) + EXTRA_LDFLAGS="${EXTRA_LDFLAGS=-Wl,-Blargedynsym}" + ;; + * ) + EXTRA_LDFLAGS="${EXTRA_LDFLAGS=-LD-Blargedynsym}" + ;; + esac + ;; + *-beos*) + # gcc on BeOS doesn't like -rdynamic... + EXTRA_LDFLAGS="${EXTRA_LDFLAGS= }" + # also, dlopen() at least in Zeta respects $LIBRARY_PATH, so needs %A added to it. + export LIBRARY_PATH="$LIBRARY_PATH:%A/" + ;; + *-haiku*) + # + ;; + esac + + # Done with our shell code, so restore autotools quoting + changequote([, ]) + +AC_CACHE_CHECK(if we can use -rdynamic, zsh_cv_rdynamic_available, +old_LDFLAGS="$LDFLAGS" +LDFLAGS="$LDFLAGS -rdynamic" +AC_LINK_IFELSE([AC_LANG_PROGRAM([[]], [[]])],[zsh_cv_rdynamic_available=yes +EXTRA_LDFLAGS="${EXTRA_LDFLAGS=-rdynamic}"],[zsh_cvs_rdynamic_available=no]) +LDFLAGS="$old_LDFLAGS") + AC_CACHE_CHECK(if your dlsym() needs a leading underscore, + zsh_cv_func_dlsym_needs_underscore, + [echo failed >conftestval && cat >conftest.c <<EOM +fred () { } +EOM + AC_TRY_COMMAND($CC -c $CFLAGS $CPPFLAGS $DLCFLAGS conftest.c 1>&AS_MESSAGE_LOG_FD) && + AC_TRY_COMMAND($DLLD $LDFLAGS $DLLDFLAGS -o conftest.$DL_EXT conftest.o 1>&AS_MESSAGE_LOG_FD) && + AC_RUN_IFELSE([AC_LANG_SOURCE([[ +#include <stdio.h> +#ifdef HPUX10DYNAMIC +#include <dl.h> +#define RTLD_LAZY BIND_DEFERRED +#define RTLD_GLOBAL DYNAMIC_PATH + +char *zsh_gl_sym_addr ; + +#define dlopen(file,mode) (void *)shl_load((file), (mode), (long) 0) +#define dlclose(handle) shl_unload((shl_t)(handle)) +#define dlsym(handle,name) (zsh_gl_sym_addr=0,shl_findsym((shl_t *)&(handle),name,TYPE_UNDEFINED,&zsh_gl_sym_addr), (void *)zsh_gl_sym_addr) +#define dlerror() 0 +#else +#ifdef HAVE_DLFCN_H +#include <dlfcn.h> +#else +#include <sys/types.h> +#include <nlist.h> +#include <link.h> +#endif +#endif +#ifndef RTLD_LAZY +#define RTLD_LAZY 1 +#endif + +extern int fred() ; + +main() +{ + void * handle ; + void * symbol ; + FILE *f=fopen("conftestval", "w"); + if (!f) exit(1); + handle = dlopen("./conftest.$DL_EXT", RTLD_LAZY) ; + if (handle == NULL) { + fprintf (f, "dlopen failed") ; + exit(1); + } + symbol = dlsym(handle, "fred") ; + if (symbol == NULL) { + /* try putting a leading underscore */ + symbol = dlsym(handle, "_fred") ; + if (symbol == NULL) { + fprintf (f, "dlsym failed") ; + exit(1); + } + fprintf (f, "yes") ; + } + else + fprintf (f, "no") ; + exit(0); +}]])],[zsh_cv_func_dlsym_needs_underscore=`cat conftestval`],[zsh_cv_func_dlsym_needs_underscore=failed + dynamic=no],[zsh_cv_func_dlsym_needs_underscore=no])]) + if test "x$zsh_cv_func_dlsym_needs_underscore" = xyes; then + AC_DEFINE(DLSYM_NEEDS_UNDERSCORE) + elif test "x$zsh_cv_func_dlsym_needs_underscore" != xno; then + dnl Do not cache failed value + unset zsh_cv_func_dlsym_needs_underscore + fi +fi + +if test "x$dynamic" = xyes; then + zsh_SHARED_VARIABLE([environ], [char **]) + test "$zsh_cv_shared_environ" = yes || dynamic=no + if test "$ac_cv_func_tgetent" = yes; then + zsh_SHARED_FUNCTION([tgetent]) + fi + if test "$ac_cv_func_tigetstr" = yes; then + zsh_SHARED_FUNCTION([tigetstr]) + fi +fi + +if test "x$dynamic" = xyes; then + zsh_SYS_DYNAMIC_CLASH + zsh_SYS_DYNAMIC_GLOBAL + RTLD_GLOBAL_OK=$zsh_cv_sys_dynamic_rtld_global + zsh_SYS_DYNAMIC_EXECSYMS + if test "$zsh_cv_sys_dynamic_execsyms" != yes; then + L=L + fi + zsh_SYS_DYNAMIC_STRIP_EXE + zsh_SYS_DYNAMIC_STRIP_LIB + if $strip_exeldflags && test "$zsh_cv_sys_dynamic_strip_exe" = yes; then + EXELDFLAGS="$EXELDFLAGS -s" + fi + if $strip_libldflags && test "$zsh_cv_sys_dynamic_strip_lib" = yes; then + LIBLDFLAGS="$LIBLDFLAGS -s" + fi + if test "$host_os" = cygwin; then + INSTLIB="install.cygwin-lib" + UNINSTLIB="uninstall.cygwin-lib" + fi +else + $strip_exeldflags && EXELDFLAGS="$EXELDFLAGS -s" + $strip_libldflags && LIBLDFLAGS="$LIBLDFLAGS -s" + RTLD_GLOBAL_OK=no +fi + +AH_TEMPLATE([DYNAMIC], +[Define to 1 if you want to use dynamically loaded modules.]) +if test "x$dynamic" = xyes; then + D=D + AC_DEFINE(DYNAMIC)dnl +else + D=N +fi + +AH_TEMPLATE([AIXDYNAMIC], +[Define to 1 if you want to use dynamically loaded modules on AIX.]) +if test "x$aixdynamic" = xyes; then + E=E + AC_DEFINE(AIXDYNAMIC)dnl +else + E=N +fi + +if test "x$zsh_cv_sys_dynamic_clash_ok" = xyes; then + SHORTBOOTNAMES=yes +else + SHORTBOOTNAMES=no +fi +AC_SUBST(SHORTBOOTNAMES) + +AC_SUBST(INSTLIB)dnl +AC_SUBST(UNINSTLIB)dnl + +if test "$host_os" = cygwin; then + EXTRAZSHOBJS="$EXTRAZSHOBJS zsh.res.o" +fi + +AC_DEFINE_UNQUOTED(DL_EXT, "$DL_EXT", +[The extension used for dynamically loaded modules.])dnl +AC_SUBST(D)dnl +AC_SUBST(DL_EXT)dnl +AC_SUBST(DLLD)dnl +AC_SUBST(DLCFLAGS)dnl +AC_SUBST(DLLDFLAGS)dnl +AC_SUBST(E)dnl +AC_SUBST(EXTRA_LDFLAGS)dnl +AC_SUBST(EXPOPT)dnl +AC_SUBST(IMPOPT)dnl +AC_SUBST(L)dnl +AC_SUBST(LINKMODS)dnl +AC_SUBST(MOD_EXPORT)dnl +AC_SUBST(MOD_IMPORT_VARIABLE)dnl +AC_SUBST(MOD_IMPORT_FUNCTION)dnl +AC_SUBST(EXTRAZSHOBJS)dnl + +# Generate config.modules. We look for *.mdd files in first and second +# level subdirectories. Any existing line not containing 'auto=y' will be +# retained, provided the .mdd file itself was found. +CONFIG_MODULES=./config.modules +cat <<EOM > ${CONFIG_MODULES}.sh +srcdir="$srcdir" +dynamic="$dynamic" +CONFIG_MODULES="${CONFIG_MODULES}" +EOM +cat <<\EOM >> ${CONFIG_MODULES}.sh +echo "creating ${CONFIG_MODULES}" +userlist=" " +if test -f ${CONFIG_MODULES}; then + userlist="`sed -e '/^#/d' -e '/auto=y/d' -e 's/ .*/ /' -e 's/^name=/ /' \ + ${CONFIG_MODULES}`" + mv ${CONFIG_MODULES} ${CONFIG_MODULES}.old +else + # Save testing for existence each time. + echo > ${CONFIG_MODULES}.old +fi +(echo "# Edit this file to change the way modules are loaded." +echo "# The format is strict; do not break lines or add extra spaces." +echo "# Run \`make prep' if you change anything here after compiling" +echo "# (there is no need if you change this just after the first time" +echo "# you run \`configure')." +echo "#" +echo "# Values of \`link' are \`static', \`dynamic' or \`no' to compile the" +echo "# module into the shell, link it in at run time, or not use it at all." +echo "# In the final case, no attempt will be made to compile it." +echo "# Use \`static' or \`no' if you do not have dynamic loading." +echo "#" +echo "# Values of \`load' are \`yes' or \`no'; if yes, any builtins etc." +echo "# provided by the module will be autoloaded by the main shell" +echo "# (so long as \`link' is not set to \`no')." +echo "#" +echo "# Values of \`auto' are \`yes' or \`no'. configure sets the value to" +echo "# \`yes'. If you set it by hand to \`no', the line will be retained" +echo "# when the file is regenerated in future." +echo "#" +echo "# Note that the \`functions' entry extends to the end of the line." +echo "# It should not be quoted; it is used verbatim to find files to install." +echo "#" +echo "# You will need to run \`config.status --recheck' if you add a new" +echo "# module." +echo "#" +echo "# You should not change the values for the pseudo-module zsh/main," +echo "# which is the main shell (apart from the functions entry)." +EOM +dnl The autoconf macros are only available in configure, not +dnl config.status, and only change when configure is rerun. +dnl So we need to run the autoconf tests here and store the results. +dnl We then generate config.modules, preserving any user-generated +dnl information, from config.status. +for modfile in `cd ${srcdir}; echo */*.mdd */*/*.mdd`; do + name= + link= + load= + functions= + result= + . ${srcdir}/$modfile + if test x$name != x && test x"$link" != x; then + case "$link" in + *\ *) eval "link=\`$link\`" + ;; + esac + case "${load}" in + y*) load=" load=yes" + ;; + *) load=" load=no" + ;; + esac + if test "x$functions" != x; then + # N.B. no additional quotes + f=" functions=$functions" + else + f= + fi + case "$link" in + static) result="name=$name modfile=$modfile link=static auto=yes${load}$f" + ;; + dynamic) if test x$dynamic != xno; then + result="name=$name modfile=$modfile link=dynamic\ + auto=yes${load}$f" + else + result="name=$name modfile=$modfile link=no\ + auto=yes load=no$f" + fi + ;; + either) if test x$dynamic != xno; then + result="name=$name modfile=$modfile link=dynamic\ + auto=yes${load}$f" + else + result="name=$name modfile=$modfile link=static\ + auto=yes${load}$f" + fi + ;; + *) result="name=$name modfile=$modfile link=no auto=yes load=no$f" + ;; + esac +dnl $result is the default output for config.modules. We generate +dnl code to check if we should use this. +cat <<EOM >> ${CONFIG_MODULES}.sh +case "\$userlist" in + *" $name "*) grep "^name=$name " \${CONFIG_MODULES}.old;; + *) echo "$result";; +esac +EOM + fi +done +cat <<\EOM >> ${CONFIG_MODULES}.sh +) >${CONFIG_MODULES} +rm -f ${CONFIG_MODULES}.old +EOM + +dnl AH_TOP replaces the code which used to appear at the top +dnl of acconfig.h. +AH_TOP([/***** begin user configuration section *****/ + +/* Define this to be the location of your password file */ +#define PASSWD_FILE "/etc/passwd" + +/* Define this to be the name of your NIS/YP password * + * map (if applicable) */ +#define PASSWD_MAP "passwd.byname" + +/* Define to 1 if you want user names to be cached */ +#define CACHE_USERNAMES 1 + +/* Define to 1 if system supports job control */ +#define JOB_CONTROL 1 + +/* Define this if you use "suspended" instead of "stopped" */ +#define USE_SUSPENDED 1 + +/* The default history buffer size in lines */ +#define DEFAULT_HISTSIZE 30 + +/* The default editor for the fc builtin */ +#define DEFAULT_FCEDIT "vi" + +/* The default prefix for temporary files */ +#define DEFAULT_TMPPREFIX "/tmp/zsh" + +/***** end of user configuration section *****/ +/***** shouldn't have to change anything below here *****/ + +]) + +CLEAN_MK="${srcdir}/Config/clean.mk" +CONFIG_MK="${srcdir}/Config/config.mk" +dnl defs.mk is in the build tree, not the source tree +DEFS_MK="Config/defs.mk" +VERSION_MK="${srcdir}/Config/version.mk" + +AC_SUBST_FILE(CLEAN_MK)dnl +AC_SUBST_FILE(CONFIG_MK)dnl +AC_SUBST_FILE(DEFS_MK)dnl +AC_SUBST_FILE(VERSION_MK)dnl + +AC_CONFIG_FILES(Config/defs.mk Makefile Doc/Makefile Etc/Makefile \ +Src/Makefile Test/Makefile) +AC_CONFIG_COMMANDS([config.modules], [. ./config.modules.sh]) +AC_CONFIG_COMMANDS([stamp-h], [echo >stamp-h]) + +AC_OUTPUT + +eval "zshbin1=${bindir}" +eval "zshbin2=${zshbin1}" +eval "zshman1=${mandir}" +eval "zshman2=${zshman1}" +eval "zshinfo1=${infodir}" +eval "zshinfo2=${zshinfo1}" +eval "zshfndir1=${fndir}" +eval "zshfndir2=${zshfndir1}" + +echo " +zsh configuration +----------------- +zsh version : ${VERSION} +host operating system : ${host_cpu}-${host_vendor}-${host_os} +source code location : ${srcdir} +compiler : ${CC} +preprocessor flags : ${CPPFLAGS} +executable compiler flags : ${CFLAGS}" +if test "x$dynamic" = xyes; then + echo "\ +module compiler flags : ${CFLAGS} ${DLCFLAGS}" +fi +echo "\ +executable linker flags : ${LDFLAGS} ${EXELDFLAGS} ${EXTRA_LDFLAGS}" +if test "x$dynamic" = xyes; then + echo "\ +module linker flags : ${LDFLAGS} ${LIBLDFLAGS} ${DLLDFLAGS}" +fi +echo "\ +library flags : ${LIBS} +installation basename : ${tzsh_name} +binary install path : ${zshbin2} +man page install path : ${zshman2} +info install path : ${zshinfo2}" +if test "$zshfndir2" != no; then + echo "functions install path : ${zshfndir2}" +fi +if test "x$additionalfpath" != x; then + echo "additional fpath entries : ${additionalfpath}" +fi +echo "See config.modules for installed modules and functions. +" + +case x$LIBS in + *-lgdbm*) + echo "WARNING: zsh will be linked against libgdbm. +This means the binary is covered by the GNU General Public License. +This does not affect the source code. +Run configure with --disable-gdbm if required." + ;; +esac + +exit 0 diff --color -Naur zsh-5.6.ori/Src/openssh_bsd_setres_id.c zsh-5.6.new/Src/openssh_bsd_setres_id.c --- zsh-5.6.ori/Src/openssh_bsd_setres_id.c 1970-01-01 01:00:00.000000000 +0100 +++ zsh-5.6.new/Src/openssh_bsd_setres_id.c 2022-03-01 17:09:37.415809676 +0100 @@ -0,0 +1,129 @@ +/* + * Copyright (c) 2012 Darren Tucker (dtucker at zip com au). + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ +/* + * openssh_bsd_setres_id.c - setresuid() and setresgid() wrappers + * + * This file is part of zsh, the Z shell. + * + * It is based on the file openbsd-compat/bsd-setres_id.c in OpenSSH 7.9p1, + * which is subject to the copyright notice above. The zsh modifications are + * licensed as follows: + * + * Copyright (c) 2019 Daniel Shahaf + * All rights reserved. + * + * Permission is hereby granted, without written agreement and without + * license or royalty fees, to use, copy, modify, and distribute this + * software and to distribute modified versions of this software for any + * purpose, provided that the above copyright notice and the following + * two paragraphs appear in all copies of this software. + * + * In no event shall Daniel Shahaf or the Zsh Development Group be liable + * to any party for direct, indirect, special, incidental, or consequential + * damages arising out of the use of this software and its documentation, + * even if Daniel Shahaf and the Zsh Development Group have been advised of + * the possibility of such damage. + * + * Daniel Shahaf and the Zsh Development Group specifically disclaim any + * warranties, including, but not limited to, the implied warranties of + * merchantability and fitness for a particular purpose. The software + * provided hereunder is on an "as is" basis, and Daniel Shahaf and the + * Zsh Development Group have no obligation to provide maintenance, + * support, updates, enhancements, or modifications. + * + */ + + +#include <sys/types.h> + +#include <stdarg.h> +#include <unistd.h> +#include <string.h> + +#include "zsh.mdh" + +#if defined(ZSH_IMPLEMENT_SETRESGID) || defined(BROKEN_SETRESGID) +int +setresgid(gid_t rgid, gid_t egid, gid_t sgid) +{ + int ret = 0, saved_errno; + + if (rgid != sgid) { + errno = ENOSYS; + return -1; + } +#if defined(ZSH_HAVE_NATIVE_SETREGID) && !defined(BROKEN_SETREGID) + if (setregid(rgid, egid) < 0) { + saved_errno = errno; + zwarnnam("setregid", "to gid %L: %e", (long)rgid, errno); + errno = saved_errno; + ret = -1; + } +#else + if (setegid(egid) < 0) { + saved_errno = errno; + zwarnnam("setegid", "to gid %L: %e", (long)(unsigned int)egid, errno); + errno = saved_errno; + ret = -1; + } + if (setgid(rgid) < 0) { + saved_errno = errno; + zwarnnam("setgid", "to gid %L: %e", (long)rgid, errno); + errno = saved_errno; + ret = -1; + } +#endif + return ret; +} +#endif + +#if defined(ZSH_IMPLEMENT_SETRESUID) || defined(BROKEN_SETRESUID) +int +setresuid(uid_t ruid, uid_t euid, uid_t suid) +{ + int ret = 0, saved_errno; + + if (ruid != suid) { + errno = ENOSYS; + return -1; + } +#if defined(ZSH_HAVE_NATIVE_SETREUID) && !defined(BROKEN_SETREUID) + if (setreuid(ruid, euid) < 0) { + saved_errno = errno; + zwarnnam("setreuid", "to uid %L: %e", (long)ruid, errno); + errno = saved_errno; + ret = -1; + } +#else + +# ifndef SETEUID_BREAKS_SETUID + if (seteuid(euid) < 0) { + saved_errno = errno; + zwarnnam("seteuid", "to uid %L: %e", (long)euid, errno); + errno = saved_errno; + ret = -1; + } +# endif + if (setuid(ruid) < 0) { + saved_errno = errno; + zwarnnam("setuid", "to uid %L: %e", (long)ruid, errno); + errno = saved_errno; + ret = -1; + } +#endif + return ret; +} +#endif diff --color -Naur zsh-5.6.ori/Src/options.c zsh-5.6.new/Src/options.c --- zsh-5.6.ori/Src/options.c 2018-08-12 21:21:30.000000000 +0200 +++ zsh-5.6.new/Src/options.c 2022-03-01 17:09:59.507986325 +0100 @@ -576,6 +576,7 @@ bin_setopt(char *nam, char **args, UNUSED(Options ops), int isun) { int action, optno, match = 0; + int retval = 0; /* With no arguments or options, display options. */ if (!*args) { @@ -603,18 +604,24 @@ inittyptab(); return 1; } - if(!(optno = optlookup(*args))) + if(!(optno = optlookup(*args))) { zwarnnam(nam, "no such option: %s", *args); - else if(dosetopt(optno, action, 0, opts)) + retval |= 1; + } else if (dosetopt(optno, action, 0, opts)) { zwarnnam(nam, "can't change option: %s", *args); + retval |= 1; + } break; } else if(**args == 'm') { match = 1; } else { - if (!(optno = optlookupc(**args))) + if (!(optno = optlookupc(**args))) { zwarnnam(nam, "bad option: -%c", **args); - else if(dosetopt(optno, action, 0, opts)) + retval |= 1; + } else if (dosetopt(optno, action, 0, opts)) { zwarnnam(nam, "can't change option: -%c", **args); + retval |= 1; + } } } args++; @@ -624,10 +631,13 @@ if (!match) { /* Not globbing the arguments -- arguments are simply option names. */ while (*args) { - if(!(optno = optlookup(*args++))) + if(!(optno = optlookup(*args++))) { zwarnnam(nam, "no such option: %s", args[-1]); - else if(dosetopt(optno, !isun, 0, opts)) + retval |= 1; + } else if (dosetopt(optno, !isun, 0, opts)) { zwarnnam(nam, "can't change option: %s", args[-1]); + retval |= 1; + } } } else { /* Globbing option (-m) set. */ @@ -650,7 +660,8 @@ tokenize(s); if (!(pprog = patcompile(s, PAT_HEAPDUP, NULL))) { zwarnnam(nam, "bad pattern: %s", *args); - continue; + retval |= 1; + break; } /* Loop over expansions. */ scanmatchtable(optiontab, pprog, 0, 0, OPT_ALIAS, @@ -659,7 +670,7 @@ } } inittyptab(); - return 0; + return retval; } /* Identify an option name */ @@ -768,37 +779,99 @@ return -1; } else if(optno == PRIVILEGED && !value) { /* unsetting PRIVILEGED causes the shell to make itself unprivileged */ -#ifdef HAVE_SETUID - int ignore_err; - errno = 0; + +/* For simplicity's sake, require both setresgid() and setresuid() up-front. */ +#if !defined(HAVE_SETRESGID) + zwarnnam("unsetopt", + "PRIVILEGED: can't drop privileges; setresgid() and friends not available"); + return -1; +#elif !defined(HAVE_SETRESUID) + zwarnnam("unsetopt", + "PRIVILEGED: can't drop privileges; setresuid() and friends not available"); + return -1; +#else + /* If set, return -1 so lastval will be non-zero. */ + int failed = 0; + const int orig_euid = geteuid(); + const int orig_egid = getegid(); + /* * Set the GID first as if we set the UID to non-privileged it * might be impossible to restore the GID. - * - * Some OSes (possibly no longer around) have been known to - * fail silently the first time, so we attempt the change twice. - * If it fails we are guaranteed to pick this up the second - * time, so ignore the first time. - * - * Some versions of gcc make it hard to ignore the results the - * first time, hence the following. (These are probably not - * systems that require the doubled calls.) */ - ignore_err = setgid(getgid()); - (void)ignore_err; - ignore_err = setuid(getuid()); - (void)ignore_err; - if (setgid(getgid())) { - zwarn("failed to change group ID: %e", errno); - return -1; - } else if (setuid(getuid())) { - zwarn("failed to change user ID: %e", errno); - return -1; + if (setresgid(getgid(), getgid(), getgid())) { + zwarnnam("unsetopt", + "PRIVILEGED: can't drop privileges; failed to change group ID: %e", + errno); + return -1; } -#else - zwarn("setuid not available"); - return -1; -#endif /* not HAVE_SETUID */ + +# ifdef HAVE_INITGROUPS + /* Set the supplementary groups list. + * + * Note that on macOS, FreeBSD, and possibly some other platforms, + * initgroups() resets the EGID to its second argument (see setgroups(2) for + * details). This has the potential to leave the EGID in an unexpected + * state. However, it seems common in other projects that do this dance to + * simply re-use the same GID that's going to become the EGID anyway, in + * which case it doesn't matter. That's what we do here. It's therefore + * possible, in some probably uncommon cases, that the shell ends up not + * having the privileges of the RUID user's primary/passwd group. */ + if (geteuid() == 0) { + struct passwd *pw = getpwuid(getuid()); + if (pw == NULL) { + zwarnnam("unsetopt", + "can't drop privileges; failed to get user information for uid %L: %e", + (long)getuid(), errno); + failed = 1; + /* This may behave strangely in the unlikely event that the same user + * name appears with multiple UIDs in the passwd database */ + } else if (initgroups(pw->pw_name, getgid())) { + zwarnnam("unsetopt", + "can't drop privileges; failed to set supplementary group list: %e", + errno); + return -1; + } + } else if (getuid() != 0 && + (geteuid() != getuid() || orig_egid != getegid())) { + zwarnnam("unsetopt", + "PRIVILEGED: supplementary group list not changed due to lack of permissions: EUID=%L", + (long)geteuid()); + failed = 1; + } +# else + /* initgroups() isn't in POSIX. If it's not available on the system, + * we silently skip it. */ +# endif + + /* Set the UID second. */ + if (setresuid(getuid(), getuid(), getuid())) { + zwarnnam("unsetopt", + "PRIVILEGED: can't drop privileges; failed to change user ID: %e", + errno); + return -1; + } + + if (getuid() != 0 && orig_egid != getegid() && + (setgid(orig_egid) != -1 || setegid(orig_egid) != -1)) { + zwarnnam("unsetopt", + "PRIVILEGED: can't drop privileges; was able to restore the egid"); + return -1; + } + + if (getuid() != 0 && orig_euid != geteuid() && + (setuid(orig_euid) != -1 || seteuid(orig_euid) != -1)) { + zwarnnam("unsetopt", + "PRIVILEGED: can't drop privileges; was able to restore the euid"); + return -1; + } + + if (failed) { + /* A warning message has been printed. */ + return -1; + } +#endif /* HAVE_SETRESGID && HAVE_SETRESUID */ + #ifdef JOB_CONTROL } else if (!force && optno == MONITOR && value) { if (new_opts[optno] == value) diff --color -Naur zsh-5.6.ori/Src/options.c.orig zsh-5.6.new/Src/options.c.orig --- zsh-5.6.ori/Src/options.c.orig 1970-01-01 01:00:00.000000000 +0100 +++ zsh-5.6.new/Src/options.c.orig 2022-03-01 17:09:56.723964064 +0100 @@ -0,0 +1,1016 @@ +/* + * options.c - shell options + * + * This file is part of zsh, the Z shell. + * + * Copyright (c) 1992-1997 Paul Falstad + * All rights reserved. + * + * Permission is hereby granted, without written agreement and without + * license or royalty fees, to use, copy, modify, and distribute this + * software and to distribute modified versions of this software for any + * purpose, provided that the above copyright notice and the following + * two paragraphs appear in all copies of this software. + * + * In no event shall Paul Falstad or the Zsh Development Group be liable + * to any party for direct, indirect, special, incidental, or consequential + * damages arising out of the use of this software and its documentation, + * even if Paul Falstad and the Zsh Development Group have been advised of + * the possibility of such damage. + * + * Paul Falstad and the Zsh Development Group specifically disclaim any + * warranties, including, but not limited to, the implied warranties of + * merchantability and fitness for a particular purpose. The software + * provided hereunder is on an "as is" basis, and Paul Falstad and the + * Zsh Development Group have no obligation to provide maintenance, + * support, updates, enhancements, or modifications. + * + */ + +#include "zsh.mdh" +#include "options.pro" + +/* current emulation (used to decide which set of option letters is used) */ + +/**/ +mod_export int emulation; + +/* current sticky emulation: sticky = NULL means none */ + +/**/ +mod_export Emulation_options sticky; + +/* the options; e.g. if opts[SHGLOB] != 0, SH_GLOB is turned on */ + +/**/ +mod_export char opts[OPT_SIZE]; + +/* Option name hash table */ + +/**/ +mod_export HashTable optiontab; + +/* The canonical option name table */ + +#define OPT_CSH EMULATE_CSH +#define OPT_KSH EMULATE_KSH +#define OPT_SH EMULATE_SH +#define OPT_ZSH EMULATE_ZSH + +#define OPT_ALL (OPT_CSH|OPT_KSH|OPT_SH|OPT_ZSH) +#define OPT_BOURNE (OPT_KSH|OPT_SH) +#define OPT_BSHELL (OPT_KSH|OPT_SH|OPT_ZSH) +#define OPT_NONBOURNE (OPT_ALL & ~OPT_BOURNE) +#define OPT_NONZSH (OPT_ALL & ~OPT_ZSH) + +/* option is relevant to emulation */ +#define OPT_EMULATE (EMULATE_UNUSED) +/* option should never be set by emulate() */ +#define OPT_SPECIAL (EMULATE_UNUSED<<1) +/* option is an alias to an other option */ +#define OPT_ALIAS (EMULATE_UNUSED<<2) + +#define defset(X, my_emulation) (!!((X)->node.flags & my_emulation)) + +/* + * Note that option names should usually be fewer than 20 characters long + * to avoid formatting problems. + */ +static struct optname optns[] = { +{{NULL, "aliases", OPT_EMULATE|OPT_ALL}, ALIASESOPT}, +{{NULL, "aliasfuncdef", OPT_EMULATE|OPT_BOURNE}, ALIASFUNCDEF}, +{{NULL, "allexport", OPT_EMULATE}, ALLEXPORT}, +{{NULL, "alwayslastprompt", OPT_ALL}, ALWAYSLASTPROMPT}, +{{NULL, "alwaystoend", 0}, ALWAYSTOEND}, +{{NULL, "appendcreate", OPT_EMULATE|OPT_BOURNE}, APPENDCREATE}, +{{NULL, "appendhistory", OPT_ALL}, APPENDHISTORY}, +{{NULL, "autocd", OPT_EMULATE}, AUTOCD}, +{{NULL, "autocontinue", 0}, AUTOCONTINUE}, +{{NULL, "autolist", OPT_ALL}, AUTOLIST}, +{{NULL, "automenu", OPT_ALL}, AUTOMENU}, +{{NULL, "autonamedirs", 0}, AUTONAMEDIRS}, +{{NULL, "autoparamkeys", OPT_ALL}, AUTOPARAMKEYS}, +{{NULL, "autoparamslash", OPT_ALL}, AUTOPARAMSLASH}, +{{NULL, "autopushd", 0}, AUTOPUSHD}, +{{NULL, "autoremoveslash", OPT_ALL}, AUTOREMOVESLASH}, +{{NULL, "autoresume", 0}, AUTORESUME}, +{{NULL, "badpattern", OPT_EMULATE|OPT_NONBOURNE},BADPATTERN}, +{{NULL, "banghist", OPT_NONBOURNE}, BANGHIST}, +{{NULL, "bareglobqual", OPT_EMULATE|OPT_ZSH}, BAREGLOBQUAL}, +{{NULL, "bashautolist", 0}, BASHAUTOLIST}, +{{NULL, "bashrematch", 0}, BASHREMATCH}, +{{NULL, "beep", OPT_ALL}, BEEP}, +{{NULL, "bgnice", OPT_EMULATE|OPT_NONBOURNE},BGNICE}, +{{NULL, "braceccl", OPT_EMULATE}, BRACECCL}, +{{NULL, "bsdecho", OPT_EMULATE|OPT_SH}, BSDECHO}, +{{NULL, "caseglob", OPT_ALL}, CASEGLOB}, +{{NULL, "casematch", OPT_ALL}, CASEMATCH}, +{{NULL, "cbases", 0}, CBASES}, +{{NULL, "cprecedences", OPT_EMULATE|OPT_NONZSH}, CPRECEDENCES}, +{{NULL, "cdablevars", OPT_EMULATE}, CDABLEVARS}, +{{NULL, "chasedots", OPT_EMULATE}, CHASEDOTS}, +{{NULL, "chaselinks", OPT_EMULATE}, CHASELINKS}, +{{NULL, "checkjobs", OPT_EMULATE|OPT_ZSH}, CHECKJOBS}, +{{NULL, "checkrunningjobs", OPT_EMULATE|OPT_ZSH}, CHECKRUNNINGJOBS}, +{{NULL, "clobber", OPT_EMULATE|OPT_ALL}, CLOBBER}, +{{NULL, "combiningchars", 0}, COMBININGCHARS}, +{{NULL, "completealiases", 0}, COMPLETEALIASES}, +{{NULL, "completeinword", 0}, COMPLETEINWORD}, +{{NULL, "continueonerror", 0}, CONTINUEONERROR}, +{{NULL, "correct", 0}, CORRECT}, +{{NULL, "correctall", 0}, CORRECTALL}, +{{NULL, "cshjunkiehistory", OPT_EMULATE|OPT_CSH}, CSHJUNKIEHISTORY}, +{{NULL, "cshjunkieloops", OPT_EMULATE|OPT_CSH}, CSHJUNKIELOOPS}, +{{NULL, "cshjunkiequotes", OPT_EMULATE|OPT_CSH}, CSHJUNKIEQUOTES}, +{{NULL, "cshnullcmd", OPT_EMULATE|OPT_CSH}, CSHNULLCMD}, +{{NULL, "cshnullglob", OPT_EMULATE|OPT_CSH}, CSHNULLGLOB}, +{{NULL, "debugbeforecmd", OPT_ALL}, DEBUGBEFORECMD}, +{{NULL, "emacs", 0}, EMACSMODE}, +{{NULL, "equals", OPT_EMULATE|OPT_ZSH}, EQUALS}, +{{NULL, "errexit", OPT_EMULATE}, ERREXIT}, +{{NULL, "errreturn", OPT_EMULATE}, ERRRETURN}, +{{NULL, "exec", OPT_ALL}, EXECOPT}, +{{NULL, "extendedglob", OPT_EMULATE}, EXTENDEDGLOB}, +{{NULL, "extendedhistory", OPT_CSH}, EXTENDEDHISTORY}, +{{NULL, "evallineno", OPT_EMULATE|OPT_ZSH}, EVALLINENO}, +{{NULL, "flowcontrol", OPT_ALL}, FLOWCONTROL}, +{{NULL, "forcefloat", 0}, FORCEFLOAT}, +{{NULL, "functionargzero", OPT_EMULATE|OPT_NONBOURNE},FUNCTIONARGZERO}, +{{NULL, "glob", OPT_EMULATE|OPT_ALL}, GLOBOPT}, +{{NULL, "globalexport", OPT_EMULATE|OPT_ZSH}, GLOBALEXPORT}, +{{NULL, "globalrcs", OPT_ALL}, GLOBALRCS}, +{{NULL, "globassign", OPT_EMULATE|OPT_CSH}, GLOBASSIGN}, +{{NULL, "globcomplete", 0}, GLOBCOMPLETE}, +{{NULL, "globdots", OPT_EMULATE}, GLOBDOTS}, +{{NULL, "globstarshort", OPT_EMULATE}, GLOBSTARSHORT}, +{{NULL, "globsubst", OPT_EMULATE|OPT_NONZSH}, GLOBSUBST}, +{{NULL, "hashcmds", OPT_ALL}, HASHCMDS}, +{{NULL, "hashdirs", OPT_ALL}, HASHDIRS}, +{{NULL, "hashexecutablesonly", 0}, HASHEXECUTABLESONLY}, +{{NULL, "hashlistall", OPT_ALL}, HASHLISTALL}, +{{NULL, "histallowclobber", 0}, HISTALLOWCLOBBER}, +{{NULL, "histbeep", OPT_ALL}, HISTBEEP}, +{{NULL, "histexpiredupsfirst",0}, HISTEXPIREDUPSFIRST}, +{{NULL, "histfcntllock", 0}, HISTFCNTLLOCK}, +{{NULL, "histfindnodups", 0}, HISTFINDNODUPS}, +{{NULL, "histignorealldups", 0}, HISTIGNOREALLDUPS}, +{{NULL, "histignoredups", 0}, HISTIGNOREDUPS}, +{{NULL, "histignorespace", 0}, HISTIGNORESPACE}, +{{NULL, "histlexwords", 0}, HISTLEXWORDS}, +{{NULL, "histnofunctions", 0}, HISTNOFUNCTIONS}, +{{NULL, "histnostore", 0}, HISTNOSTORE}, +{{NULL, "histsubstpattern", OPT_EMULATE}, HISTSUBSTPATTERN}, +{{NULL, "histreduceblanks", 0}, HISTREDUCEBLANKS}, +{{NULL, "histsavebycopy", OPT_ALL}, HISTSAVEBYCOPY}, +{{NULL, "histsavenodups", 0}, HISTSAVENODUPS}, +{{NULL, "histverify", 0}, HISTVERIFY}, +{{NULL, "hup", OPT_EMULATE|OPT_ZSH}, HUP}, +{{NULL, "ignorebraces", OPT_EMULATE|OPT_SH}, IGNOREBRACES}, +{{NULL, "ignoreclosebraces", OPT_EMULATE}, IGNORECLOSEBRACES}, +{{NULL, "ignoreeof", 0}, IGNOREEOF}, +{{NULL, "incappendhistory", 0}, INCAPPENDHISTORY}, +{{NULL, "incappendhistorytime", 0}, INCAPPENDHISTORYTIME}, +{{NULL, "interactive", OPT_SPECIAL}, INTERACTIVE}, +{{NULL, "interactivecomments",OPT_BOURNE}, INTERACTIVECOMMENTS}, +{{NULL, "ksharrays", OPT_EMULATE|OPT_BOURNE}, KSHARRAYS}, +{{NULL, "kshautoload", OPT_EMULATE|OPT_BOURNE}, KSHAUTOLOAD}, +{{NULL, "kshglob", OPT_EMULATE|OPT_KSH}, KSHGLOB}, +{{NULL, "kshoptionprint", OPT_EMULATE|OPT_KSH}, KSHOPTIONPRINT}, +{{NULL, "kshtypeset", 0}, KSHTYPESET}, +{{NULL, "kshzerosubscript", 0}, KSHZEROSUBSCRIPT}, +{{NULL, "listambiguous", OPT_ALL}, LISTAMBIGUOUS}, +{{NULL, "listbeep", OPT_ALL}, LISTBEEP}, +{{NULL, "listpacked", 0}, LISTPACKED}, +{{NULL, "listrowsfirst", 0}, LISTROWSFIRST}, +{{NULL, "listtypes", OPT_ALL}, LISTTYPES}, +{{NULL, "localoptions", OPT_EMULATE|OPT_KSH}, LOCALOPTIONS}, +{{NULL, "localloops", OPT_EMULATE}, LOCALLOOPS}, +{{NULL, "localpatterns", OPT_EMULATE}, LOCALPATTERNS}, +{{NULL, "localtraps", OPT_EMULATE|OPT_KSH}, LOCALTRAPS}, +{{NULL, "login", OPT_SPECIAL}, LOGINSHELL}, +{{NULL, "longlistjobs", 0}, LONGLISTJOBS}, +{{NULL, "magicequalsubst", OPT_EMULATE}, MAGICEQUALSUBST}, +{{NULL, "mailwarning", 0}, MAILWARNING}, +{{NULL, "markdirs", 0}, MARKDIRS}, +{{NULL, "menucomplete", 0}, MENUCOMPLETE}, +{{NULL, "monitor", OPT_SPECIAL}, MONITOR}, +{{NULL, "multibyte", +#ifdef MULTIBYTE_SUPPORT + OPT_ALL +#else + 0 +#endif + }, MULTIBYTE}, +{{NULL, "multifuncdef", OPT_EMULATE|OPT_ZSH}, MULTIFUNCDEF}, +{{NULL, "multios", OPT_EMULATE|OPT_ZSH}, MULTIOS}, +{{NULL, "nomatch", OPT_EMULATE|OPT_NONBOURNE},NOMATCH}, +{{NULL, "notify", OPT_ZSH}, NOTIFY}, +{{NULL, "nullglob", OPT_EMULATE}, NULLGLOB}, +{{NULL, "numericglobsort", OPT_EMULATE}, NUMERICGLOBSORT}, +{{NULL, "octalzeroes", OPT_EMULATE|OPT_SH}, OCTALZEROES}, +{{NULL, "overstrike", 0}, OVERSTRIKE}, +{{NULL, "pathdirs", OPT_EMULATE}, PATHDIRS}, +{{NULL, "pathscript", OPT_EMULATE|OPT_BOURNE}, PATHSCRIPT}, +{{NULL, "pipefail", OPT_EMULATE}, PIPEFAIL}, +{{NULL, "posixaliases", OPT_EMULATE|OPT_BOURNE}, POSIXALIASES}, +{{NULL, "posixargzero", OPT_EMULATE}, POSIXARGZERO}, +{{NULL, "posixbuiltins", OPT_EMULATE|OPT_BOURNE}, POSIXBUILTINS}, +{{NULL, "posixcd", OPT_EMULATE|OPT_BOURNE}, POSIXCD}, +{{NULL, "posixidentifiers", OPT_EMULATE|OPT_BOURNE}, POSIXIDENTIFIERS}, +{{NULL, "posixjobs", OPT_EMULATE|OPT_BOURNE}, POSIXJOBS}, +{{NULL, "posixstrings", OPT_EMULATE|OPT_BOURNE}, POSIXSTRINGS}, +{{NULL, "posixtraps", OPT_EMULATE|OPT_BOURNE}, POSIXTRAPS}, +{{NULL, "printeightbit", 0}, PRINTEIGHTBIT}, +{{NULL, "printexitvalue", 0}, PRINTEXITVALUE}, +{{NULL, "privileged", OPT_SPECIAL}, PRIVILEGED}, +{{NULL, "promptbang", OPT_KSH}, PROMPTBANG}, +{{NULL, "promptcr", OPT_ALL}, PROMPTCR}, +{{NULL, "promptpercent", OPT_NONBOURNE}, PROMPTPERCENT}, +{{NULL, "promptsp", OPT_ALL}, PROMPTSP}, +{{NULL, "promptsubst", OPT_BOURNE}, PROMPTSUBST}, +{{NULL, "pushdignoredups", OPT_EMULATE}, PUSHDIGNOREDUPS}, +{{NULL, "pushdminus", OPT_EMULATE}, PUSHDMINUS}, +{{NULL, "pushdsilent", 0}, PUSHDSILENT}, +{{NULL, "pushdtohome", OPT_EMULATE}, PUSHDTOHOME}, +{{NULL, "rcexpandparam", OPT_EMULATE}, RCEXPANDPARAM}, +{{NULL, "rcquotes", OPT_EMULATE}, RCQUOTES}, +{{NULL, "rcs", OPT_ALL}, RCS}, +{{NULL, "recexact", 0}, RECEXACT}, +{{NULL, "rematchpcre", 0}, REMATCHPCRE}, +{{NULL, "restricted", OPT_SPECIAL}, RESTRICTED}, +{{NULL, "rmstarsilent", OPT_BOURNE}, RMSTARSILENT}, +{{NULL, "rmstarwait", 0}, RMSTARWAIT}, +{{NULL, "sharehistory", OPT_KSH}, SHAREHISTORY}, +{{NULL, "shfileexpansion", OPT_EMULATE|OPT_BOURNE}, SHFILEEXPANSION}, +{{NULL, "shglob", OPT_EMULATE|OPT_BOURNE}, SHGLOB}, +{{NULL, "shinstdin", OPT_SPECIAL}, SHINSTDIN}, +{{NULL, "shnullcmd", OPT_EMULATE|OPT_BOURNE}, SHNULLCMD}, +{{NULL, "shoptionletters", OPT_EMULATE|OPT_BOURNE}, SHOPTIONLETTERS}, +{{NULL, "shortloops", OPT_EMULATE|OPT_NONBOURNE},SHORTLOOPS}, +{{NULL, "shwordsplit", OPT_EMULATE|OPT_BOURNE}, SHWORDSPLIT}, +{{NULL, "singlecommand", OPT_SPECIAL}, SINGLECOMMAND}, +{{NULL, "singlelinezle", OPT_KSH}, SINGLELINEZLE}, +{{NULL, "sourcetrace", 0}, SOURCETRACE}, +{{NULL, "sunkeyboardhack", 0}, SUNKEYBOARDHACK}, +{{NULL, "transientrprompt", 0}, TRANSIENTRPROMPT}, +{{NULL, "trapsasync", 0}, TRAPSASYNC}, +{{NULL, "typesetsilent", OPT_EMULATE|OPT_BOURNE}, TYPESETSILENT}, +{{NULL, "unset", OPT_EMULATE|OPT_BSHELL}, UNSET}, +{{NULL, "verbose", 0}, VERBOSE}, +{{NULL, "vi", 0}, VIMODE}, +{{NULL, "warncreateglobal", OPT_EMULATE}, WARNCREATEGLOBAL}, +{{NULL, "warnnestedvar", OPT_EMULATE}, WARNNESTEDVAR}, +{{NULL, "xtrace", 0}, XTRACE}, +{{NULL, "zle", OPT_SPECIAL}, USEZLE}, +{{NULL, "braceexpand", OPT_ALIAS}, /* ksh/bash */ -IGNOREBRACES}, +{{NULL, "dotglob", OPT_ALIAS}, /* bash */ GLOBDOTS}, +{{NULL, "hashall", OPT_ALIAS}, /* bash */ HASHCMDS}, +{{NULL, "histappend", OPT_ALIAS}, /* bash */ APPENDHISTORY}, +{{NULL, "histexpand", OPT_ALIAS}, /* bash */ BANGHIST}, +{{NULL, "log", OPT_ALIAS}, /* ksh */ -HISTNOFUNCTIONS}, +{{NULL, "mailwarn", OPT_ALIAS}, /* bash */ MAILWARNING}, +{{NULL, "onecmd", OPT_ALIAS}, /* bash */ SINGLECOMMAND}, +{{NULL, "physical", OPT_ALIAS}, /* ksh/bash */ CHASELINKS}, +{{NULL, "promptvars", OPT_ALIAS}, /* bash */ PROMPTSUBST}, +{{NULL, "stdin", OPT_ALIAS}, /* ksh */ SHINSTDIN}, +{{NULL, "trackall", OPT_ALIAS}, /* ksh */ HASHCMDS}, +{{NULL, "dvorak", 0}, DVORAK}, +{{NULL, NULL, 0}, 0} +}; + +/* Option letters */ + +#define optletters (isset(SHOPTIONLETTERS) ? kshletters : zshletters) + +#define FIRST_OPT '0' +#define LAST_OPT 'y' + +static short zshletters[LAST_OPT - FIRST_OPT + 1] = { + /* 0 */ CORRECT, + /* 1 */ PRINTEXITVALUE, + /* 2 */ -BADPATTERN, + /* 3 */ -NOMATCH, + /* 4 */ GLOBDOTS, + /* 5 */ NOTIFY, + /* 6 */ BGNICE, + /* 7 */ IGNOREEOF, + /* 8 */ MARKDIRS, + /* 9 */ AUTOLIST, + /* : */ 0, + /* ; */ 0, + /* < */ 0, + /* = */ 0, + /* > */ 0, + /* ? */ 0, + /* @ */ 0, + /* A */ 0, /* use with set for arrays */ + /* B */ -BEEP, + /* C */ -CLOBBER, + /* D */ PUSHDTOHOME, + /* E */ PUSHDSILENT, + /* F */ -GLOBOPT, + /* G */ NULLGLOB, + /* H */ RMSTARSILENT, + /* I */ IGNOREBRACES, + /* J */ AUTOCD, + /* K */ -BANGHIST, + /* L */ SUNKEYBOARDHACK, + /* M */ SINGLELINEZLE, + /* N */ AUTOPUSHD, + /* O */ CORRECTALL, + /* P */ RCEXPANDPARAM, + /* Q */ PATHDIRS, + /* R */ LONGLISTJOBS, + /* S */ RECEXACT, + /* T */ CDABLEVARS, + /* U */ MAILWARNING, + /* V */ -PROMPTCR, + /* W */ AUTORESUME, + /* X */ LISTTYPES, + /* Y */ MENUCOMPLETE, + /* Z */ USEZLE, + /* [ */ 0, + /* \ */ 0, + /* ] */ 0, + /* ^ */ 0, + /* _ */ 0, + /* ` */ 0, + /* a */ ALLEXPORT, + /* b */ 0, /* in non-Bourne shells, end of options */ + /* c */ 0, /* command follows */ + /* d */ -GLOBALRCS, + /* e */ ERREXIT, + /* f */ -RCS, + /* g */ HISTIGNORESPACE, + /* h */ HISTIGNOREDUPS, + /* i */ INTERACTIVE, + /* j */ 0, + /* k */ INTERACTIVECOMMENTS, + /* l */ LOGINSHELL, + /* m */ MONITOR, + /* n */ -EXECOPT, + /* o */ 0, /* long option name follows */ + /* p */ PRIVILEGED, + /* q */ 0, + /* r */ RESTRICTED, + /* s */ SHINSTDIN, + /* t */ SINGLECOMMAND, + /* u */ -UNSET, + /* v */ VERBOSE, + /* w */ CHASELINKS, + /* x */ XTRACE, + /* y */ SHWORDSPLIT, +}; + +static short kshletters[LAST_OPT - FIRST_OPT + 1] = { + /* 0 */ 0, + /* 1 */ 0, + /* 2 */ 0, + /* 3 */ 0, + /* 4 */ 0, + /* 5 */ 0, + /* 6 */ 0, + /* 7 */ 0, + /* 8 */ 0, + /* 9 */ 0, + /* : */ 0, + /* ; */ 0, + /* < */ 0, + /* = */ 0, + /* > */ 0, + /* ? */ 0, + /* @ */ 0, + /* A */ 0, + /* B */ 0, + /* C */ -CLOBBER, + /* D */ 0, + /* E */ 0, + /* F */ 0, + /* G */ 0, + /* H */ 0, + /* I */ 0, + /* J */ 0, + /* K */ 0, + /* L */ 0, + /* M */ 0, + /* N */ 0, + /* O */ 0, + /* P */ 0, + /* Q */ 0, + /* R */ 0, + /* S */ 0, + /* T */ TRAPSASYNC, + /* U */ 0, + /* V */ 0, + /* W */ 0, + /* X */ MARKDIRS, + /* Y */ 0, + /* Z */ 0, + /* [ */ 0, + /* \ */ 0, + /* ] */ 0, + /* ^ */ 0, + /* _ */ 0, + /* ` */ 0, + /* a */ ALLEXPORT, + /* b */ NOTIFY, + /* c */ 0, + /* d */ 0, + /* e */ ERREXIT, + /* f */ -GLOBOPT, + /* g */ 0, + /* h */ 0, + /* i */ INTERACTIVE, + /* j */ 0, + /* k */ 0, + /* l */ LOGINSHELL, + /* m */ MONITOR, + /* n */ -EXECOPT, + /* o */ 0, + /* p */ PRIVILEGED, + /* q */ 0, + /* r */ RESTRICTED, + /* s */ SHINSTDIN, + /* t */ SINGLECOMMAND, + /* u */ -UNSET, + /* v */ VERBOSE, + /* w */ 0, + /* x */ XTRACE, + /* y */ 0, +}; + +/* Initialisation of the option name hash table */ + +/**/ +static void +printoptionnode(HashNode hn, int set) +{ + Optname on = (Optname) hn; + int optno = on->optno; + + if (optno < 0) + optno = -optno; + if (isset(KSHOPTIONPRINT)) { + if (defset(on, emulation)) + printf("no%-19s %s\n", on->node.nam, isset(optno) ? "off" : "on"); + else + printf("%-21s %s\n", on->node.nam, isset(optno) ? "on" : "off"); + } else if (set == (isset(optno) ^ defset(on, emulation))) { + if (set ^ isset(optno)) + fputs("no", stdout); + puts(on->node.nam); + } +} + +/**/ +void +createoptiontable(void) +{ + Optname on; + + optiontab = newhashtable(101, "optiontab", NULL); + + optiontab->hash = hasher; + optiontab->emptytable = NULL; + optiontab->filltable = NULL; + optiontab->cmpnodes = strcmp; + optiontab->addnode = addhashnode; + optiontab->getnode = gethashnode; + optiontab->getnode2 = gethashnode2; + optiontab->removenode = NULL; + optiontab->disablenode = disablehashnode; + optiontab->enablenode = enablehashnode; + optiontab->freenode = NULL; + optiontab->printnode = printoptionnode; + + for (on = optns; on->node.nam; on++) + optiontab->addnode(optiontab, on->node.nam, on); +} + +/* Emulation appropriate to the setemulate function */ + +static int setemulate_emulation; + +/* Option array manipulated within the setemulate function */ + +/**/ +static char *setemulate_opts; + +/* Setting of default options */ + +/**/ +static void +setemulate(HashNode hn, int fully) +{ + Optname on = (Optname) hn; + + /* Set options: each non-special option is set according to the * + * current emulation mode if either it is considered relevant * + * to emulation or we are doing a full emulation (as indicated * + * by the `fully' parameter). */ + if (!(on->node.flags & OPT_ALIAS) && + ((fully && !(on->node.flags & OPT_SPECIAL)) || + (on->node.flags & OPT_EMULATE))) + setemulate_opts[on->optno] = defset(on, setemulate_emulation); +} + +/**/ +void +installemulation(int new_emulation, char *new_opts) +{ + setemulate_emulation = new_emulation; + setemulate_opts = new_opts; + scanhashtable(optiontab, 0, 0, 0, setemulate, + !!(new_emulation & EMULATE_FULLY)); +} + +/**/ +void +emulate(const char *zsh_name, int fully, int *new_emulation, char *new_opts) +{ + char ch = *zsh_name; + + if (ch == 'r') + ch = zsh_name[1]; + + /* Work out the new emulation mode */ + if (ch == 'c') + *new_emulation = EMULATE_CSH; + else if (ch == 'k') + *new_emulation = EMULATE_KSH; + else if (ch == 's' || ch == 'b') + *new_emulation = EMULATE_SH; + else + *new_emulation = EMULATE_ZSH; + + if (fully) + *new_emulation |= EMULATE_FULLY; + installemulation(*new_emulation, new_opts); + + if (funcstack && funcstack->tp == FS_FUNC) { + /* + * We are inside a function. Decide if it's traced. + * Pedantic note: the function in the function table isn't + * guaranteed to be what we're executing, but it's + * close enough. + */ + Shfunc shf = (Shfunc)shfunctab->getnode(shfunctab, funcstack->name); + if (shf && (shf->node.flags & (PM_TAGGED|PM_TAGGED_LOCAL))) { + /* Tracing is on, so set xtrace */ + new_opts[XTRACE] = 1; + } + } +} + +/* setopt, unsetopt */ + +/**/ +static void +setoption(HashNode hn, int value) +{ + dosetopt(((Optname) hn)->optno, value, 0, opts); +} + +/**/ +int +bin_setopt(char *nam, char **args, UNUSED(Options ops), int isun) +{ + int action, optno, match = 0; + int retval = 0; + + /* With no arguments or options, display options. */ + if (!*args) { + scanhashtable(optiontab, 1, 0, OPT_ALIAS, optiontab->printnode, !isun); + return 0; + } + + /* loop through command line options (begins with "-" or "+") */ + while (*args && (**args == '-' || **args == '+')) { + action = (**args == '-') ^ isun; + if(!args[0][1]) + *args = "--"; + while (*++*args) { + if(**args == Meta) + *++*args ^= 32; + /* The pseudo-option `--' signifies the end of options. */ + if (**args == '-') { + args++; + goto doneoptions; + } else if (**args == 'o') { + if (!*++*args) + args++; + if (!*args) { + zwarnnam(nam, "string expected after -o"); + inittyptab(); + return 1; + } + if(!(optno = optlookup(*args))) { + zwarnnam(nam, "no such option: %s", *args); + retval |= 1; + } else if (dosetopt(optno, action, 0, opts)) { + zwarnnam(nam, "can't change option: %s", *args); + retval |= 1; + } + break; + } else if(**args == 'm') { + match = 1; + } else { + if (!(optno = optlookupc(**args))) { + zwarnnam(nam, "bad option: -%c", **args); + retval |= 1; + } else if (dosetopt(optno, action, 0, opts)) { + zwarnnam(nam, "can't change option: -%c", **args); + retval |= 1; + } + } + } + args++; + } + doneoptions: + + if (!match) { + /* Not globbing the arguments -- arguments are simply option names. */ + while (*args) { + if(!(optno = optlookup(*args++))) { + zwarnnam(nam, "no such option: %s", args[-1]); + retval |= 1; + } else if (dosetopt(optno, !isun, 0, opts)) { + zwarnnam(nam, "can't change option: %s", args[-1]); + retval |= 1; + } + } + } else { + /* Globbing option (-m) set. */ + while (*args) { + Patprog pprog; + char *s, *t; + + t = s = dupstring(*args); + while (*t) + if (*t == '_') + chuck(t); + else { + /* See comment in optlookup() */ + if (*t >= 'A' && *t <= 'Z') + *t = (*t - 'A') + 'a'; + t++; + } + + /* Expand the current arg. */ + tokenize(s); + if (!(pprog = patcompile(s, PAT_HEAPDUP, NULL))) { + zwarnnam(nam, "bad pattern: %s", *args); + retval |= 1; + break; + } + /* Loop over expansions. */ + scanmatchtable(optiontab, pprog, 0, 0, OPT_ALIAS, + setoption, !isun); + args++; + } + } + inittyptab(); + return retval; +} + +/* Identify an option name */ + +/**/ +mod_export int +optlookup(char const *name) +{ + char *s, *t; + Optname n; + + s = t = dupstring(name); + + /* exorcise underscores, and change to lowercase */ + while (*t) + if (*t == '_') + chuck(t); + else { + /* + * Some locales (in particular tr_TR.UTF-8) may + * have non-standard mappings of ASCII characters, + * so be careful. Option names must be ASCII so + * we don't need to be too clever. + */ + if (*t >= 'A' && *t <= 'Z') + *t = (*t - 'A') + 'a'; + t++; + } + + /* look up name in the table */ + if (s[0] == 'n' && s[1] == 'o' && + (n = (Optname) optiontab->getnode(optiontab, s + 2))) { + return -n->optno; + } else if ((n = (Optname) optiontab->getnode(optiontab, s))) + return n->optno; + else + return OPT_INVALID; +} + +/* Identify an option letter */ + +/**/ +int +optlookupc(char c) +{ + if(c < FIRST_OPT || c > LAST_OPT) + return 0; + + return optletters[c - FIRST_OPT]; +} + +/**/ +static void +restrictparam(char *nam) +{ + Param pm = (Param) paramtab->getnode(paramtab, nam); + + if (pm) { + pm->node.flags |= PM_SPECIAL | PM_RESTRICTED; + return; + } + createparam(nam, PM_SCALAR | PM_UNSET | PM_SPECIAL | PM_RESTRICTED); +} + +/* list of restricted parameters which are not otherwise special */ +static char *rparams[] = { + "SHELL", "HISTFILE", "LD_LIBRARY_PATH", "LD_AOUT_LIBRARY_PATH", + "LD_PRELOAD", "LD_AOUT_PRELOAD", NULL +}; + +/* Set or unset an option, as a result of user request. The option * + * number may be negative, indicating that the sense is reversed * + * from the usual meaning of the option. */ + +/**/ +mod_export int +dosetopt(int optno, int value, int force, char *new_opts) +{ + if(!optno) + return -1; + if(optno < 0) { + optno = -optno; + value = !value; + } + if (optno == RESTRICTED) { + if (isset(RESTRICTED)) + return value ? 0 : -1; + if (value) { + char **s; + + for (s = rparams; *s; s++) + restrictparam(*s); + } + } else if(!force && optno == EXECOPT && !value && interact) { + /* cannot set noexec when interactive */ + return -1; + } else if(!force && (optno == INTERACTIVE || optno == SHINSTDIN || + optno == SINGLECOMMAND)) { + if (new_opts[optno] == value) + return 0; + /* it is not permitted to change the value of these options */ + return -1; + } else if(!force && optno == USEZLE && value) { + /* we require a terminal in order to use ZLE */ + if(!interact || SHTTY == -1 || !shout) + return -1; + } else if(optno == PRIVILEGED && !value) { + /* unsetting PRIVILEGED causes the shell to make itself unprivileged */ + +/* For simplicity's sake, require both setresgid() and setresuid() up-front. */ +#if !defined(HAVE_SETRESGID) + zwarnnam("unsetopt", "PRIVILEGED: can't drop privileges; setresgid() and friends not available"); + return -1; +#elif !defined(HAVE_SETRESUID) + zwarnnam("unsetopt", "PRIVILEGED: can't drop privileges; setresuid() and friends not available"); + return -1; +#else + /* If set, return -1 so lastval will be non-zero. */ + int failed = 0; + const int orig_euid = geteuid(); + const int orig_egid = getegid(); + + /* + * Set the GID first as if we set the UID to non-privileged it + * might be impossible to restore the GID. + */ + if (setresgid(getgid(), getgid(), getgid())) { + zwarnnam("unsetopt", "PRIVILEGED: can't drop privileges; failed to change group ID: %e", errno); + return -1; + } + +# ifdef HAVE_INITGROUPS + /* Set the supplementary groups list. + * + * Note that on macOS, FreeBSD, and possibly some other platforms, + * initgroups() resets the EGID to its second argument (see setgroups(2) for + * details). This has the potential to leave the EGID in an unexpected + * state. However, it seems common in other projects that do this dance to + * simply re-use the same GID that's going to become the EGID anyway, in + * which case it doesn't matter. That's what we do here. It's therefore + * possible, in some probably uncommon cases, that the shell ends up not + * having the privileges of the RUID user's primary/passwd group. */ + if (geteuid() == 0) { + struct passwd *pw = getpwuid(getuid()); + if (pw == NULL) { + zwarnnam("unsetopt", "can't drop privileges; failed to get user information for uid %L: %e", + (long)getuid(), errno); + failed = 1; + /* This may behave strangely in the unlikely event that the same user + * name appears with multiple UIDs in the passwd database */ + } else if (initgroups(pw->pw_name, getgid())) { + zwarnnam("unsetopt", "can't drop privileges; failed to set supplementary group list: %e", errno); + return -1; + } + } else if (getuid() != 0 && + (geteuid() != getuid() || orig_egid != getegid())) { + zwarnnam("unsetopt", "PRIVILEGED: supplementary group list not changed due to lack of permissions: EUID=%L", + (long)geteuid()); + failed = 1; + } +# else + /* initgroups() isn't in POSIX. If it's not available on the system, + * we silently skip it. */ +# endif + + /* Set the UID second. */ + if (setresuid(getuid(), getuid(), getuid())) { + zwarnnam("unsetopt", "PRIVILEGED: can't drop privileges; failed to change user ID: %e", errno); + return -1; + } + + if (getuid() != 0 && orig_egid != getegid() && + (setgid(orig_egid) != -1 || setegid(orig_egid) != -1)) { + zwarnnam("unsetopt", "PRIVILEGED: can't drop privileges; was able to restore the egid"); + return -1; + } + + if (getuid() != 0 && orig_euid != geteuid() && + (setuid(orig_euid) != -1 || seteuid(orig_euid) != -1)) { + zwarnnam("unsetopt", "PRIVILEGED: can't drop privileges; was able to restore the euid"); + return -1; + } + + if (failed) { + /* A warning message has been printed. */ + return -1; + } +#endif /* HAVE_SETRESGID && HAVE_SETRESUID */ + +#ifdef JOB_CONTROL + } else if (!force && optno == MONITOR && value) { + if (new_opts[optno] == value) + return 0; + if (SHTTY != -1) { + origpgrp = GETPGRP(); + acquire_pgrp(); + } else + return -1; +#else + } else if(optno == MONITOR && value) { + return -1; +#endif /* not JOB_CONTROL */ +#ifdef GETPWNAM_FAKED + } else if(optno == CDABLEVARS && value) { + return -1; +#endif /* GETPWNAM_FAKED */ + } else if ((optno == EMACSMODE || optno == VIMODE) && value) { + if (sticky && sticky->emulation) + return -1; + zleentry(ZLE_CMD_SET_KEYMAP, optno); + new_opts[(optno == EMACSMODE) ? VIMODE : EMACSMODE] = 0; + } else if (optno == SUNKEYBOARDHACK) { + /* for backward compatibility */ + keyboardhackchar = (value ? '`' : '\0'); + } + new_opts[optno] = value; + if (optno == BANGHIST || optno == SHINSTDIN) + inittyptab(); + return 0; +} + +/* Function to get value for special parameter `-' */ + +/**/ +char * +dashgetfn(UNUSED(Param pm)) +{ + static char buf[LAST_OPT - FIRST_OPT + 2]; + char *val = buf; + int i; + + for(i = 0; i <= LAST_OPT - FIRST_OPT; i++) { + int optno = optletters[i]; + if(optno && ((optno > 0) ? isset(optno) : unset(-optno))) + *val++ = FIRST_OPT + i; + } + *val = '\0'; + return buf; +} + +/* print options for set -o/+o */ + +/**/ +void +printoptionstates(int hadplus) +{ + scanhashtable(optiontab, 1, 0, OPT_ALIAS, printoptionnodestate, hadplus); +} + +/**/ +static void +printoptionnodestate(HashNode hn, int hadplus) +{ + Optname on = (Optname) hn; + int optno = on->optno; + + if (hadplus) { + printf("set %co %s%s\n", + defset(on, emulation) != isset(optno) ? '-' : '+', + defset(on, emulation) ? "no" : "", + on->node.nam); + } else { + if (defset(on, emulation)) + printf("no%-19s %s\n", on->node.nam, isset(optno) ? "off" : "on"); + else + printf("%-21s %s\n", on->node.nam, isset(optno) ? "on" : "off"); + } +} + +/* Print option list for --help */ + +/**/ +void +printoptionlist(void) +{ + short *lp; + char c; + + printf("\nNamed options:\n"); + scanhashtable(optiontab, 1, 0, OPT_ALIAS, printoptionlist_printoption, 0); + printf("\nOption aliases:\n"); + scanhashtable(optiontab, 1, OPT_ALIAS, 0, printoptionlist_printoption, 0); + printf("\nOption letters:\n"); + for(lp = optletters, c = FIRST_OPT; c <= LAST_OPT; lp++, c++) { + if(!*lp) + continue; + printf(" -%c ", c); + printoptionlist_printequiv(*lp); + } +} + +/**/ +static void +printoptionlist_printoption(HashNode hn, UNUSED(int ignored)) +{ + Optname on = (Optname) hn; + + if(on->node.flags & OPT_ALIAS) { + printf(" --%-19s ", on->node.nam); + printoptionlist_printequiv(on->optno); + } else + printf(" --%s\n", on->node.nam); +} + +/**/ +static void +printoptionlist_printequiv(int optno) +{ + int isneg = optno < 0; + + optno *= (isneg ? -1 : 1); + printf(" equivalent to --%s%s\n", isneg ? "no-" : "", optns[optno-1].node.nam); +} + +/**/ +static char *print_emulate_opts; + +/**/ +static void +print_emulate_option(HashNode hn, int fully) +{ + Optname on = (Optname) hn; + + if (!(on->node.flags & OPT_ALIAS) && + ((fully && !(on->node.flags & OPT_SPECIAL)) || + (on->node.flags & OPT_EMULATE))) + { + if (!print_emulate_opts[on->optno]) + fputs("no", stdout); + puts(on->node.nam); + } +} + +/* + * List the settings of options associated with an emulation + */ + +/**/ +void list_emulate_options(char *cmdopts, int fully) +{ + print_emulate_opts = cmdopts; + scanhashtable(optiontab, 1, 0, 0, print_emulate_option, fully); +} diff --color -Naur zsh-5.6.ori/Src/zsh.mdd zsh-5.6.new/Src/zsh.mdd --- zsh-5.6.ori/Src/zsh.mdd 2018-09-03 15:37:10.000000000 +0200 +++ zsh-5.6.new/Src/zsh.mdd 2022-03-01 17:09:37.415809676 +0100 @@ -13,7 +13,8 @@ exec.o glob.o hashtable.o hashnameddir.o \ hist.o init.o input.o jobs.o lex.o linklist.o loop.o math.o \ mem.o module.o options.o params.o parse.o pattern.o prompt.o signals.o \ -signames.o sort.o string.o subst.o text.o utils.o watch.o" +signames.o sort.o string.o subst.o text.o utils.o watch.o \ +openssh_bsd_setres_id.o" headers="../config.h zsh_system.h zsh.h sigcount.h signals.h \ prototypes.h hashtable.h ztype.h" diff --color -Naur zsh-5.6.ori/Test/E01options.ztst zsh-5.6.new/Test/E01options.ztst --- zsh-5.6.ori/Test/E01options.ztst 2018-08-12 21:21:30.000000000 +0200 +++ zsh-5.6.new/Test/E01options.ztst 2022-03-01 17:09:37.419809709 +0100 @@ -74,7 +74,6 @@ # HASH_LIST_ALL ) # PRINT_EXIT_STATUS haven't worked out what this does yet, although # Bart suggested a fix. -# PRIVILEGED (similar to GLOBAL_RCS) # RCS ( " " " " ) # SH_OPTION_LETTERS even I found this too dull to set up a test for # SINGLE_COMMAND kills shell @@ -95,6 +94,15 @@ %test + # setopt should move on to the next operation in the face of an error, but + # preserve the >0 return code + unsetopt aliases + setopt not_a_real_option aliases && return 2 + print -r - $options[aliases] +0:setopt error handling +?(eval):setopt:4: no such option: not_a_real_option +>on + alias echo='print foo' unsetopt aliases # use eval else aliases are all parsed at start diff --color -Naur zsh-5.6.ori/Test/P01privileged.ztst zsh-5.6.new/Test/P01privileged.ztst --- zsh-5.6.ori/Test/P01privileged.ztst 1970-01-01 01:00:00.000000000 +0100 +++ zsh-5.6.new/Test/P01privileged.ztst 2022-03-01 17:09:37.419809709 +0100 @@ -0,0 +1,197 @@ +# This file contains tests related to the PRIVILEGED option. In order to run, +# it requires that the test process itself have super-user privileges (or that +# one of the environment variables described below be set). This can be achieved +# via, e.g., `sudo make check TESTNUM=P`. +# +# Optionally, the environment variables ZSH_TEST_UNPRIVILEGED_UID and/or +# ZSH_TEST_UNPRIVILEGED_GID may be set to UID:EUID or GID:EGID pairs, where the +# two IDs in each pair are different, non-0 IDs valid on the system being used +# to run the tests. (The UIDs must both be non-0 to effectively test downgrading +# of privileges, and they must be non-matching to test auto-enabling of +# PRIVILEGED and to ensure that disabling PRIVILEGED correctly resets the saved +# UID. Technically GID 0 is not special, but for simplicity's sake we apply the +# same requirements here.) +# +# If either of the aforementioned environment variables is not set, the test +# script will try to pick the first two >0 IDs from the passwd/group databases +# on the current system. +# +# If either variable is set, the tests will run, but they will likely fail +# without super-user privileges. + +%prep + + # Mind your empty lines here. The logic in this %prep section is somewhat + # complex compared to most others; to avoid lots of nested/duplicated + # conditions we need to make sure that this all gets executed as a single + # function from which we can return early + [[ $EUID == 0 || -n $ZSH_TEST_UNPRIVILEGED_UID$ZSH_TEST_UNPRIVILEGED_GID ]] || { + ZTST_unimplemented='PRIVILEGED tests require super-user privileges (or env var)' + return 1 + } + (( $+commands[perl] )) || { # @todo Eliminate this dependency with a C wrapper? + ZTST_unimplemented='PRIVILEGED tests require Perl' + return 1 + } + grep -qE '#define HAVE_SETRES?UID' $ZTST_testdir/../config.h || { + ZTST_unimplemented='PRIVILEGED tests require setreuid()/setresuid()' + return 1 + } + # + ruid= euid= rgid= egid= + # + if [[ -n $ZSH_TEST_UNPRIVILEGED_UID ]]; then + ruid=${ZSH_TEST_UNPRIVILEGED_UID%%:*} + euid=${ZSH_TEST_UNPRIVILEGED_UID##*:} + else + print -ru$ZTST_fd 'Selecting unprivileged UID:EUID pair automatically' + local tmp=$( getent passwd 2> /dev/null || < /etc/passwd ) + # Note: Some awks require -v and its argument to be separate + ruid=$( awk -F: '$3 > 0 { print $3; exit; }' <<< $tmp ) + euid=$( awk -F: -v u=$ruid '$3 > u { print $3; exit; }' <<< $tmp ) + fi + # + if [[ -n $ZSH_TEST_UNPRIVILEGED_GID ]]; then + rgid=${ZSH_TEST_UNPRIVILEGED_GID%%:*} + egid=${ZSH_TEST_UNPRIVILEGED_GID##*:} + else + print -ru$ZTST_fd 'Selecting unprivileged GID:EGID pair automatically' + local tmp=$( getent group 2> /dev/null || < /etc/group ) + # Note: Some awks require -v and its argument to be separate + rgid=$( awk -F: '$3 > 0 { print $3; exit; }' <<< $tmp ) + egid=$( awk -F: -v g=$rgid '$3 > g { print $3; exit; }' <<< $tmp ) + fi + # + [[ $ruid/$euid == <1->/<1-> && $ruid != $euid ]] || ruid= euid= + [[ $rgid/$egid == <1->/<1-> && $rgid != $egid ]] || rgid= egid= + # + [[ -n $ruid && -n $euid ]] || { + ZTST_unimplemented='PRIVILEGED tests require unprivileged UID:EUID' + return 1 + } + [[ -n $rgid || -n $egid ]] || { + ZTST_unimplemented='PRIVILEGED tests require unprivileged GID:EGID' + return 1 + } + # + print -ru$ZTST_fd \ + "Using unprivileged UID $ruid, EUID $euid, GID $rgid, EGID $egid" + # + # Execute process with specified UID and EUID + # $1 => Real UID + # $2 => Effective UID + # $3 => Real GID + # $4 => Effective GID + # $5 ... => Command + args to execute (must NOT be a shell command string) + re_exec() { + perl -e ' + die("re_exec: not enough arguments") unless (@ARGV >= 5); + my ($ruid, $euid, $rgid, $egid, @cmd) = @ARGV; + foreach my $id ($ruid, $euid, $rgid, $egid) { + die("re_exec: invalid ID: $id") unless ($id =~ /^(-1|\d+)$/a); + } + $< = 0 + $ruid if ($ruid >= 0); + $> = 0 + $euid if ($euid >= 0); + $( = 0 + $rgid if ($rgid >= 0); + $) = 0 + $egid if ($egid >= 0); + exec(@cmd); + die("re_exec: exec failed: $!"); + ' -- "$@" + } + # + # Convenience wrapper for re_exec to call `zsh -c` + # -* ... => (optional) Command-line options to zsh + # $1 => Real UID + # $2 => Effective UID + # $3 => Real GID + # $4 => Effective GID + # $5 ... => zsh command string; multiple strings are joined by \n + re_zsh() { + local -a opts + while [[ $1 == -[A-Za-z-]* ]]; do + opts+=( $1 ) + shift + done + re_exec "$1" "$2" "$3" "$4" $ZTST_exe $opts -fc \ + "MODULE_PATH=${(q)MODULE_PATH}; ${(F)@[5,-1]}" + } + # + # Return one or more random unused UIDs + # $1 ... => Names of parameters to store UIDs in + get_unused_uid() { + while (( $# )); do + local i_=0 uid_= + until [[ -n $uid_ ]]; do + (( ++i_ > 99 )) && return 1 + uid_=$RANDOM + id $uid_ &> /dev/null || break + uid_= + done + : ${(P)1::=$uid_} + shift + done + } + +%test + + re_zsh $ruid $ruid -1 -1 'echo $UID/$EUID $options[privileged]' + re_zsh $euid $euid -1 -1 'echo $UID/$EUID $options[privileged]' + re_zsh $ruid $euid -1 -1 'echo $UID/$EUID $options[privileged]' +0q:PRIVILEGED automatically enabled when RUID != EUID +>$ruid/$ruid off +>$euid/$euid off +>$ruid/$euid on + + re_zsh -1 -1 $rgid $rgid 'echo $GID/$EGID $options[privileged]' + re_zsh -1 -1 $egid $egid 'echo $GID/$EGID $options[privileged]' + re_zsh -1 -1 $rgid $egid 'echo $GID/$EGID $options[privileged]' +0q:PRIVILEGED automatically enabled when RGID != EGID +>$rgid/$rgid off +>$egid/$egid off +>$rgid/$egid on + + re_zsh $ruid $euid -1 -1 'unsetopt privileged; echo $UID/$EUID' +0q:EUID set to RUID after disabling PRIVILEGED +*?zsh:unsetopt:1: PRIVILEGED: supplementary group list not changed * +*?zsh:unsetopt:1: can't change option: privileged +>$ruid/$ruid + + re_zsh 0 $euid -1 -1 'unsetopt privileged && echo $UID/$EUID' +0:RUID/EUID set to 0/0 when privileged after disabling PRIVILEGED +>0/0 + + re_zsh $ruid $euid -1 -1 "unsetopt privileged; UID=$euid" || + re_zsh $ruid $euid -1 -1 "unsetopt privileged; EUID=$euid" +1:not possible to regain EUID when unprivileged after disabling PRIVILEGED +*?zsh:unsetopt:1: PRIVILEGED: supplementary group list not changed * +*?zsh:unsetopt:1: can't change option: privileged +*?zsh:1: failed to change user ID: * +*?zsh:unsetopt:1: PRIVILEGED: supplementary group list not changed * +*?zsh:unsetopt:1: can't change option: privileged +*?zsh:1: failed to change effective user ID: * + + re_zsh -1 -1 $rgid $egid 'unsetopt privileged && echo $GID/$EGID' +0q:EGID set to RGID after disabling PRIVILEGED +>$rgid/$rgid + +# This test also confirms that we can't revert to the original EUID's primary +# GID, which initgroups() may reset the EGID to on some systems + re_zsh $ruid 0 $rgid 0 'unsetopt privileged; GID=0' || + re_zsh $ruid 0 $rgid 0 'unsetopt privileged; EGID=0' +1:not possible to regain EGID when unprivileged after disabling PRIVILEGED +*?zsh:1: failed to change group ID: * +*?zsh:1: failed to change effective group ID: * + + local rruid + grep -qF '#define HAVE_INITGROUPS' $ZTST_testdir/../config.h || { + ZTST_skip='initgroups() not available' + return 1 + } + get_unused_uid rruid || { + ZTST_skip="Can't get unused UID" + return 1 + } + re_zsh $rruid 0 -1 -1 'unsetopt privileged' +1:getpwuid() fails with non-existent RUID and 0 EUID +*?zsh:unsetopt:1: can't drop privileges; failed to get user information * +*?zsh:unsetopt:1: can't change option: privileged diff --color -Naur zsh-5.6.ori/Test/README zsh-5.6.new/Test/README --- zsh-5.6.ori/Test/README 2017-05-26 19:42:13.000000000 +0200 +++ zsh-5.6.new/Test/README 2022-03-01 17:09:37.419809709 +0100 @@ -6,6 +6,7 @@ C: shell commands with special syntax D: substititution E: options + P: privileged (needs super-user privileges) V: modules W: builtin interactive commands and constructs X: line editing
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor