mirror of
https://salsa.debian.org/debian/dash.git
synced 2026-01-26 07:37:51 +00:00
New upstream version 0.5.12
This commit is contained in:
commit
796d7ad03d
20
Makefile.in
20
Makefile.in
@ -1,7 +1,7 @@
|
||||
# Makefile.in generated by automake 1.16.1 from Makefile.am.
|
||||
# Makefile.in generated by automake 1.16.3 from Makefile.am.
|
||||
# @configure_input@
|
||||
|
||||
# Copyright (C) 1994-2018 Free Software Foundation, Inc.
|
||||
# Copyright (C) 1994-2020 Free Software Foundation, Inc.
|
||||
|
||||
# This Makefile.in is free software; the Free Software Foundation
|
||||
# gives unlimited permission to copy and/or distribute it,
|
||||
@ -133,8 +133,8 @@ am__recursive_targets = \
|
||||
$(am__extra_recursive_targets)
|
||||
AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \
|
||||
cscope distdir distdir-am dist dist-all distcheck
|
||||
am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) \
|
||||
$(LISP)config.h.in
|
||||
am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) \
|
||||
config.h.in
|
||||
# Read a list of newline-separated strings from the standard input,
|
||||
# and print each of them once, without duplicates. Input order is
|
||||
# *not* preserved.
|
||||
@ -195,6 +195,8 @@ am__relativize = \
|
||||
DIST_ARCHIVES = $(distdir).tar.gz
|
||||
GZIP_ENV = --best
|
||||
DIST_TARGETS = dist-gzip
|
||||
# Exists only to be overridden by the user if desired.
|
||||
AM_DISTCHECK_DVI_TARGET = dvi
|
||||
distuninstallcheck_listfiles = find . -type f -print
|
||||
am__distuninstallcheck_listfiles = $(distuninstallcheck_listfiles) \
|
||||
| sed 's|^\./|$(prefix)/|' | grep -v '$(infodir)/dir$$'
|
||||
@ -531,6 +533,10 @@ dist-xz: distdir
|
||||
tardir=$(distdir) && $(am__tar) | XZ_OPT=$${XZ_OPT--e} xz -c >$(distdir).tar.xz
|
||||
$(am__post_remove_distdir)
|
||||
|
||||
dist-zstd: distdir
|
||||
tardir=$(distdir) && $(am__tar) | zstd -c $${ZSTD_CLEVEL-$${ZSTD_OPT--19}} >$(distdir).tar.zst
|
||||
$(am__post_remove_distdir)
|
||||
|
||||
dist-tarZ: distdir
|
||||
@echo WARNING: "Support for distribution archives compressed with" \
|
||||
"legacy program 'compress' is deprecated." >&2
|
||||
@ -573,6 +579,8 @@ distcheck: dist
|
||||
eval GZIP= gzip $(GZIP_ENV) -dc $(distdir).shar.gz | unshar ;;\
|
||||
*.zip*) \
|
||||
unzip $(distdir).zip ;;\
|
||||
*.tar.zst*) \
|
||||
zstd -dc $(distdir).tar.zst | $(am__untar) ;;\
|
||||
esac
|
||||
chmod -R a-w $(distdir)
|
||||
chmod u+w $(distdir)
|
||||
@ -588,7 +596,7 @@ distcheck: dist
|
||||
$(DISTCHECK_CONFIGURE_FLAGS) \
|
||||
--srcdir=../.. --prefix="$$dc_install_base" \
|
||||
&& $(MAKE) $(AM_MAKEFLAGS) \
|
||||
&& $(MAKE) $(AM_MAKEFLAGS) dvi \
|
||||
&& $(MAKE) $(AM_MAKEFLAGS) $(AM_DISTCHECK_DVI_TARGET) \
|
||||
&& $(MAKE) $(AM_MAKEFLAGS) check \
|
||||
&& $(MAKE) $(AM_MAKEFLAGS) install \
|
||||
&& $(MAKE) $(AM_MAKEFLAGS) installcheck \
|
||||
@ -749,7 +757,7 @@ uninstall-am:
|
||||
am--refresh check check-am clean clean-cscope clean-generic \
|
||||
cscope cscopelist-am ctags ctags-am dist dist-all dist-bzip2 \
|
||||
dist-gzip dist-lzip dist-shar dist-tarZ dist-xz dist-zip \
|
||||
distcheck distclean distclean-generic distclean-hdr \
|
||||
dist-zstd distcheck distclean distclean-generic distclean-hdr \
|
||||
distclean-tags distcleancheck distdir distuninstallcheck dvi \
|
||||
dvi-am html html-am info info-am install install-am \
|
||||
install-data install-data-am install-dvi install-dvi-am \
|
||||
|
||||
55
aclocal.m4
vendored
55
aclocal.m4
vendored
@ -1,6 +1,6 @@
|
||||
# generated automatically by aclocal 1.16.1 -*- Autoconf -*-
|
||||
# generated automatically by aclocal 1.16.3 -*- Autoconf -*-
|
||||
|
||||
# Copyright (C) 1996-2018 Free Software Foundation, Inc.
|
||||
# Copyright (C) 1996-2020 Free Software Foundation, Inc.
|
||||
|
||||
# This file is free software; the Free Software Foundation
|
||||
# gives unlimited permission to copy and/or distribute it,
|
||||
@ -20,7 +20,7 @@ You have another version of autoconf. It may work, but is not guaranteed to.
|
||||
If you have problems, you may need to regenerate the build system entirely.
|
||||
To do so, use the procedure documented by the package, typically 'autoreconf'.])])
|
||||
|
||||
# Copyright (C) 2002-2018 Free Software Foundation, Inc.
|
||||
# Copyright (C) 2002-2020 Free Software Foundation, Inc.
|
||||
#
|
||||
# This file is free software; the Free Software Foundation
|
||||
# gives unlimited permission to copy and/or distribute it,
|
||||
@ -35,7 +35,7 @@ AC_DEFUN([AM_AUTOMAKE_VERSION],
|
||||
[am__api_version='1.16'
|
||||
dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to
|
||||
dnl require some minimum version. Point them to the right macro.
|
||||
m4_if([$1], [1.16.1], [],
|
||||
m4_if([$1], [1.16.3], [],
|
||||
[AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl
|
||||
])
|
||||
|
||||
@ -51,14 +51,14 @@ m4_define([_AM_AUTOCONF_VERSION], [])
|
||||
# Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced.
|
||||
# This function is AC_REQUIREd by AM_INIT_AUTOMAKE.
|
||||
AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION],
|
||||
[AM_AUTOMAKE_VERSION([1.16.1])dnl
|
||||
[AM_AUTOMAKE_VERSION([1.16.3])dnl
|
||||
m4_ifndef([AC_AUTOCONF_VERSION],
|
||||
[m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl
|
||||
_AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))])
|
||||
|
||||
# AM_AUX_DIR_EXPAND -*- Autoconf -*-
|
||||
|
||||
# Copyright (C) 2001-2018 Free Software Foundation, Inc.
|
||||
# Copyright (C) 2001-2020 Free Software Foundation, Inc.
|
||||
#
|
||||
# This file is free software; the Free Software Foundation
|
||||
# gives unlimited permission to copy and/or distribute it,
|
||||
@ -110,7 +110,7 @@ am_aux_dir=`cd "$ac_aux_dir" && pwd`
|
||||
|
||||
# AM_CONDITIONAL -*- Autoconf -*-
|
||||
|
||||
# Copyright (C) 1997-2018 Free Software Foundation, Inc.
|
||||
# Copyright (C) 1997-2020 Free Software Foundation, Inc.
|
||||
#
|
||||
# This file is free software; the Free Software Foundation
|
||||
# gives unlimited permission to copy and/or distribute it,
|
||||
@ -141,7 +141,7 @@ AC_CONFIG_COMMANDS_PRE(
|
||||
Usually this means the macro was only invoked conditionally.]])
|
||||
fi])])
|
||||
|
||||
# Copyright (C) 1999-2018 Free Software Foundation, Inc.
|
||||
# Copyright (C) 1999-2020 Free Software Foundation, Inc.
|
||||
#
|
||||
# This file is free software; the Free Software Foundation
|
||||
# gives unlimited permission to copy and/or distribute it,
|
||||
@ -332,7 +332,7 @@ _AM_SUBST_NOTMAKE([am__nodep])dnl
|
||||
|
||||
# Generate code to set up dependency tracking. -*- Autoconf -*-
|
||||
|
||||
# Copyright (C) 1999-2018 Free Software Foundation, Inc.
|
||||
# Copyright (C) 1999-2020 Free Software Foundation, Inc.
|
||||
#
|
||||
# This file is free software; the Free Software Foundation
|
||||
# gives unlimited permission to copy and/or distribute it,
|
||||
@ -371,7 +371,9 @@ AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS],
|
||||
done
|
||||
if test $am_rc -ne 0; then
|
||||
AC_MSG_FAILURE([Something went wrong bootstrapping makefile fragments
|
||||
for automatic dependency tracking. Try re-running configure with the
|
||||
for automatic dependency tracking. If GNU make was not used, consider
|
||||
re-running the configure script with MAKE="gmake" (or whatever is
|
||||
necessary). You can also try re-running configure with the
|
||||
'--disable-dependency-tracking' option to at least be able to build
|
||||
the package (albeit without support for automatic dependency tracking).])
|
||||
fi
|
||||
@ -398,7 +400,7 @@ AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS],
|
||||
|
||||
# Do all the work for Automake. -*- Autoconf -*-
|
||||
|
||||
# Copyright (C) 1996-2018 Free Software Foundation, Inc.
|
||||
# Copyright (C) 1996-2020 Free Software Foundation, Inc.
|
||||
#
|
||||
# This file is free software; the Free Software Foundation
|
||||
# gives unlimited permission to copy and/or distribute it,
|
||||
@ -595,7 +597,7 @@ for _am_header in $config_headers :; do
|
||||
done
|
||||
echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_count])
|
||||
|
||||
# Copyright (C) 2001-2018 Free Software Foundation, Inc.
|
||||
# Copyright (C) 2001-2020 Free Software Foundation, Inc.
|
||||
#
|
||||
# This file is free software; the Free Software Foundation
|
||||
# gives unlimited permission to copy and/or distribute it,
|
||||
@ -616,7 +618,7 @@ if test x"${install_sh+set}" != xset; then
|
||||
fi
|
||||
AC_SUBST([install_sh])])
|
||||
|
||||
# Copyright (C) 2003-2018 Free Software Foundation, Inc.
|
||||
# Copyright (C) 2003-2020 Free Software Foundation, Inc.
|
||||
#
|
||||
# This file is free software; the Free Software Foundation
|
||||
# gives unlimited permission to copy and/or distribute it,
|
||||
@ -637,7 +639,7 @@ AC_SUBST([am__leading_dot])])
|
||||
|
||||
# Check to see how 'make' treats includes. -*- Autoconf -*-
|
||||
|
||||
# Copyright (C) 2001-2018 Free Software Foundation, Inc.
|
||||
# Copyright (C) 2001-2020 Free Software Foundation, Inc.
|
||||
#
|
||||
# This file is free software; the Free Software Foundation
|
||||
# gives unlimited permission to copy and/or distribute it,
|
||||
@ -680,7 +682,7 @@ AC_SUBST([am__quote])])
|
||||
|
||||
# Fake the existence of programs that GNU maintainers use. -*- Autoconf -*-
|
||||
|
||||
# Copyright (C) 1997-2018 Free Software Foundation, Inc.
|
||||
# Copyright (C) 1997-2020 Free Software Foundation, Inc.
|
||||
#
|
||||
# This file is free software; the Free Software Foundation
|
||||
# gives unlimited permission to copy and/or distribute it,
|
||||
@ -701,12 +703,7 @@ AC_DEFUN([AM_MISSING_HAS_RUN],
|
||||
[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl
|
||||
AC_REQUIRE_AUX_FILE([missing])dnl
|
||||
if test x"${MISSING+set}" != xset; then
|
||||
case $am_aux_dir in
|
||||
*\ * | *\ *)
|
||||
MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;;
|
||||
*)
|
||||
MISSING="\${SHELL} $am_aux_dir/missing" ;;
|
||||
esac
|
||||
MISSING="\${SHELL} '$am_aux_dir/missing'"
|
||||
fi
|
||||
# Use eval to expand $SHELL
|
||||
if eval "$MISSING --is-lightweight"; then
|
||||
@ -719,7 +716,7 @@ fi
|
||||
|
||||
# Helper functions for option handling. -*- Autoconf -*-
|
||||
|
||||
# Copyright (C) 2001-2018 Free Software Foundation, Inc.
|
||||
# Copyright (C) 2001-2020 Free Software Foundation, Inc.
|
||||
#
|
||||
# This file is free software; the Free Software Foundation
|
||||
# gives unlimited permission to copy and/or distribute it,
|
||||
@ -748,7 +745,7 @@ AC_DEFUN([_AM_SET_OPTIONS],
|
||||
AC_DEFUN([_AM_IF_OPTION],
|
||||
[m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])])
|
||||
|
||||
# Copyright (C) 1999-2018 Free Software Foundation, Inc.
|
||||
# Copyright (C) 1999-2020 Free Software Foundation, Inc.
|
||||
#
|
||||
# This file is free software; the Free Software Foundation
|
||||
# gives unlimited permission to copy and/or distribute it,
|
||||
@ -795,7 +792,7 @@ AC_LANG_POP([C])])
|
||||
# For backward compatibility.
|
||||
AC_DEFUN_ONCE([AM_PROG_CC_C_O], [AC_REQUIRE([AC_PROG_CC])])
|
||||
|
||||
# Copyright (C) 2001-2018 Free Software Foundation, Inc.
|
||||
# Copyright (C) 2001-2020 Free Software Foundation, Inc.
|
||||
#
|
||||
# This file is free software; the Free Software Foundation
|
||||
# gives unlimited permission to copy and/or distribute it,
|
||||
@ -814,7 +811,7 @@ AC_DEFUN([AM_RUN_LOG],
|
||||
|
||||
# Check to make sure that the build environment is sane. -*- Autoconf -*-
|
||||
|
||||
# Copyright (C) 1996-2018 Free Software Foundation, Inc.
|
||||
# Copyright (C) 1996-2020 Free Software Foundation, Inc.
|
||||
#
|
||||
# This file is free software; the Free Software Foundation
|
||||
# gives unlimited permission to copy and/or distribute it,
|
||||
@ -895,7 +892,7 @@ AC_CONFIG_COMMANDS_PRE(
|
||||
rm -f conftest.file
|
||||
])
|
||||
|
||||
# Copyright (C) 2009-2018 Free Software Foundation, Inc.
|
||||
# Copyright (C) 2009-2020 Free Software Foundation, Inc.
|
||||
#
|
||||
# This file is free software; the Free Software Foundation
|
||||
# gives unlimited permission to copy and/or distribute it,
|
||||
@ -955,7 +952,7 @@ AC_SUBST([AM_BACKSLASH])dnl
|
||||
_AM_SUBST_NOTMAKE([AM_BACKSLASH])dnl
|
||||
])
|
||||
|
||||
# Copyright (C) 2001-2018 Free Software Foundation, Inc.
|
||||
# Copyright (C) 2001-2020 Free Software Foundation, Inc.
|
||||
#
|
||||
# This file is free software; the Free Software Foundation
|
||||
# gives unlimited permission to copy and/or distribute it,
|
||||
@ -983,7 +980,7 @@ fi
|
||||
INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s"
|
||||
AC_SUBST([INSTALL_STRIP_PROGRAM])])
|
||||
|
||||
# Copyright (C) 2006-2018 Free Software Foundation, Inc.
|
||||
# Copyright (C) 2006-2020 Free Software Foundation, Inc.
|
||||
#
|
||||
# This file is free software; the Free Software Foundation
|
||||
# gives unlimited permission to copy and/or distribute it,
|
||||
@ -1002,7 +999,7 @@ AC_DEFUN([AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE($@)])
|
||||
|
||||
# Check how to create a tarball. -*- Autoconf -*-
|
||||
|
||||
# Copyright (C) 2004-2018 Free Software Foundation, Inc.
|
||||
# Copyright (C) 2004-2020 Free Software Foundation, Inc.
|
||||
#
|
||||
# This file is free software; the Free Software Foundation
|
||||
# gives unlimited permission to copy and/or distribute it,
|
||||
|
||||
6
compile
6
compile
@ -3,7 +3,7 @@
|
||||
|
||||
scriptversion=2018-03-07.03; # UTC
|
||||
|
||||
# Copyright (C) 1999-2018 Free Software Foundation, Inc.
|
||||
# Copyright (C) 1999-2020 Free Software Foundation, Inc.
|
||||
# Written by Tom Tromey <tromey@cygnus.com>.
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
@ -53,7 +53,7 @@ func_file_conv ()
|
||||
MINGW*)
|
||||
file_conv=mingw
|
||||
;;
|
||||
CYGWIN*)
|
||||
CYGWIN* | MSYS*)
|
||||
file_conv=cygwin
|
||||
;;
|
||||
*)
|
||||
@ -67,7 +67,7 @@ func_file_conv ()
|
||||
mingw/*)
|
||||
file=`cmd //C echo "$file " | sed -e 's/"\(.*\) " *$/\1/'`
|
||||
;;
|
||||
cygwin/*)
|
||||
cygwin/* | msys/*)
|
||||
file=`cygpath -m "$file" || echo "$file"`
|
||||
;;
|
||||
wine/*)
|
||||
|
||||
@ -186,6 +186,15 @@
|
||||
/* 64-bit operations are the same as 32-bit */
|
||||
#undef fstat64
|
||||
|
||||
/* 64-bit operations are the same as 32-bit */
|
||||
#undef glob64
|
||||
|
||||
/* 64-bit operations are the same as 32-bit */
|
||||
#undef glob64_t
|
||||
|
||||
/* 64-bit operations are the same as 32-bit */
|
||||
#undef globfree64
|
||||
|
||||
/* 64-bit operations are the same as 32-bit */
|
||||
#undef lstat64
|
||||
|
||||
|
||||
63
configure
vendored
63
configure
vendored
@ -1,6 +1,6 @@
|
||||
#! /bin/sh
|
||||
# Guess values for system-dependent variables and create Makefiles.
|
||||
# Generated by GNU Autoconf 2.69 for dash 0.5.11.2.
|
||||
# Generated by GNU Autoconf 2.69 for dash 0.5.12.
|
||||
#
|
||||
#
|
||||
# Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc.
|
||||
@ -577,8 +577,8 @@ MAKEFLAGS=
|
||||
# Identity of this package.
|
||||
PACKAGE_NAME='dash'
|
||||
PACKAGE_TARNAME='dash'
|
||||
PACKAGE_VERSION='0.5.11.2'
|
||||
PACKAGE_STRING='dash 0.5.11.2'
|
||||
PACKAGE_VERSION='0.5.12'
|
||||
PACKAGE_STRING='dash 0.5.12'
|
||||
PACKAGE_BUGREPORT=''
|
||||
PACKAGE_URL=''
|
||||
|
||||
@ -1281,7 +1281,7 @@ if test "$ac_init_help" = "long"; then
|
||||
# Omit some internal or obsolete options to make the list less imposing.
|
||||
# This message is too long to be a string in the A/UX 3.1 sh.
|
||||
cat <<_ACEOF
|
||||
\`configure' configures dash 0.5.11.2 to adapt to many kinds of systems.
|
||||
\`configure' configures dash 0.5.12 to adapt to many kinds of systems.
|
||||
|
||||
Usage: $0 [OPTION]... [VAR=VALUE]...
|
||||
|
||||
@ -1348,7 +1348,7 @@ fi
|
||||
|
||||
if test -n "$ac_init_help"; then
|
||||
case $ac_init_help in
|
||||
short | recursive ) echo "Configuration of dash 0.5.11.2:";;
|
||||
short | recursive ) echo "Configuration of dash 0.5.12:";;
|
||||
esac
|
||||
cat <<\_ACEOF
|
||||
|
||||
@ -1363,7 +1363,7 @@ Optional Features:
|
||||
--disable-dependency-tracking
|
||||
speeds up one-time build
|
||||
--enable-static Build statical linked program
|
||||
--enable-fnmatch Use fnmatch(3) from libc
|
||||
--disable-fnmatch Do not use fnmatch(3) from libc
|
||||
--enable-glob Use glob(3) from libc
|
||||
--enable-test-workaround
|
||||
Guard against faccessat(2) that tells root all files
|
||||
@ -1451,7 +1451,7 @@ fi
|
||||
test -n "$ac_init_help" && exit $ac_status
|
||||
if $ac_init_version; then
|
||||
cat <<\_ACEOF
|
||||
dash configure 0.5.11.2
|
||||
dash configure 0.5.12
|
||||
generated by GNU Autoconf 2.69
|
||||
|
||||
Copyright (C) 2012 Free Software Foundation, Inc.
|
||||
@ -2045,7 +2045,7 @@ cat >config.log <<_ACEOF
|
||||
This file contains any messages produced by compilers while
|
||||
running configure, to aid debugging if configure makes a mistake.
|
||||
|
||||
It was created by dash $as_me 0.5.11.2, which was
|
||||
It was created by dash $as_me 0.5.12, which was
|
||||
generated by GNU Autoconf 2.69. Invocation command line was
|
||||
|
||||
$ $0 $@
|
||||
@ -2598,12 +2598,7 @@ program_transform_name=`$as_echo "$program_transform_name" | sed "$ac_script"`
|
||||
am_aux_dir=`cd "$ac_aux_dir" && pwd`
|
||||
|
||||
if test x"${MISSING+set}" != xset; then
|
||||
case $am_aux_dir in
|
||||
*\ * | *\ *)
|
||||
MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;;
|
||||
*)
|
||||
MISSING="\${SHELL} $am_aux_dir/missing" ;;
|
||||
esac
|
||||
MISSING="\${SHELL} '$am_aux_dir/missing'"
|
||||
fi
|
||||
# Use eval to expand $SHELL
|
||||
if eval "$MISSING --is-lightweight"; then
|
||||
@ -2908,7 +2903,7 @@ fi
|
||||
|
||||
# Define the identity of the package.
|
||||
PACKAGE='dash'
|
||||
VERSION='0.5.11.2'
|
||||
VERSION='0.5.12'
|
||||
|
||||
|
||||
cat >>confdefs.h <<_ACEOF
|
||||
@ -4808,7 +4803,7 @@ $as_echo "#define HAVE_TRADITIONAL_FACCESSAT 1" >>confdefs.h
|
||||
|
||||
fi
|
||||
|
||||
if test "$enable_fnmatch" = yes; then
|
||||
if test "$enable_fnmatch" != no; then
|
||||
use_fnmatch=
|
||||
for ac_func in fnmatch
|
||||
do :
|
||||
@ -4852,11 +4847,16 @@ fi
|
||||
|
||||
fi
|
||||
|
||||
ac_fn_c_check_func "$LINENO" "stat64" "ac_cv_func_stat64"
|
||||
ac_fn_c_check_decl "$LINENO" "stat64" "ac_cv_have_decl_stat64" "$ac_includes_default"
|
||||
if test "x$ac_cv_have_decl_stat64" = xyes; then :
|
||||
ac_fn_c_check_func "$LINENO" "stat64" "ac_cv_func_stat64"
|
||||
if test "x$ac_cv_func_stat64" = xyes; then :
|
||||
|
||||
else
|
||||
fi
|
||||
|
||||
fi
|
||||
|
||||
if test "$ac_cv_func_stat64" != yes; then
|
||||
|
||||
$as_echo "#define fstat64 fstat" >>confdefs.h
|
||||
|
||||
@ -4866,6 +4866,22 @@ $as_echo "#define lstat64 lstat" >>confdefs.h
|
||||
|
||||
$as_echo "#define stat64 stat" >>confdefs.h
|
||||
|
||||
fi
|
||||
|
||||
ac_fn_c_check_func "$LINENO" "glob64" "ac_cv_func_glob64"
|
||||
if test "x$ac_cv_func_glob64" = xyes; then :
|
||||
|
||||
else
|
||||
|
||||
|
||||
$as_echo "#define glob64_t glob_t" >>confdefs.h
|
||||
|
||||
|
||||
$as_echo "#define glob64 glob" >>confdefs.h
|
||||
|
||||
|
||||
$as_echo "#define globfree64 globfree" >>confdefs.h
|
||||
|
||||
|
||||
fi
|
||||
|
||||
@ -4971,6 +4987,9 @@ else
|
||||
fi
|
||||
|
||||
|
||||
else
|
||||
|
||||
as_fn_error $? "Can't find libedit." "$LINENO" 5
|
||||
fi
|
||||
|
||||
fi
|
||||
@ -5523,7 +5542,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
|
||||
# report actual input values of CONFIG_FILES etc. instead of their
|
||||
# values after options handling.
|
||||
ac_log="
|
||||
This file was extended by dash $as_me 0.5.11.2, which was
|
||||
This file was extended by dash $as_me 0.5.12, which was
|
||||
generated by GNU Autoconf 2.69. Invocation command line was
|
||||
|
||||
CONFIG_FILES = $CONFIG_FILES
|
||||
@ -5589,7 +5608,7 @@ _ACEOF
|
||||
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
|
||||
ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
|
||||
ac_cs_version="\\
|
||||
dash config.status 0.5.11.2
|
||||
dash config.status 0.5.12
|
||||
configured by $0, generated by GNU Autoconf 2.69,
|
||||
with options \\"\$ac_cs_config\\"
|
||||
|
||||
@ -6399,7 +6418,9 @@ $as_echo X/"$am_mf" |
|
||||
{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
|
||||
$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
|
||||
as_fn_error $? "Something went wrong bootstrapping makefile fragments
|
||||
for automatic dependency tracking. Try re-running configure with the
|
||||
for automatic dependency tracking. If GNU make was not used, consider
|
||||
re-running the configure script with MAKE=\"gmake\" (or whatever is
|
||||
necessary). You can also try re-running configure with the
|
||||
'--disable-dependency-tracking' option to at least be able to build
|
||||
the package (albeit without support for automatic dependency tracking).
|
||||
See \`config.log' for more details" "$LINENO" 5; }
|
||||
|
||||
21
configure.ac
21
configure.ac
@ -1,4 +1,4 @@
|
||||
AC_INIT([dash],[0.5.11.2])
|
||||
AC_INIT([dash],[0.5.12])
|
||||
AM_INIT_AUTOMAKE([foreign subdir-objects])
|
||||
AC_CONFIG_SRCDIR([src/main.c])
|
||||
|
||||
@ -37,8 +37,8 @@ if test "$enable_static" = "yes"; then
|
||||
export LDFLAGS="-static -Wl,--fatal-warnings"
|
||||
fi
|
||||
|
||||
AC_ARG_ENABLE(fnmatch, AS_HELP_STRING(--enable-fnmatch, \
|
||||
[Use fnmatch(3) from libc]))
|
||||
AC_ARG_ENABLE(fnmatch, AS_HELP_STRING(--disable-fnmatch, \
|
||||
[Do not use fnmatch(3) from libc]))
|
||||
AC_ARG_ENABLE(glob, AS_HELP_STRING(--enable-glob, [Use glob(3) from libc]))
|
||||
|
||||
dnl Checks for libraries.
|
||||
@ -122,7 +122,7 @@ if test "$enable_test_workaround" = "yes"; then
|
||||
[Define if your faccessat tells root all files are executable])
|
||||
fi
|
||||
|
||||
if test "$enable_fnmatch" = yes; then
|
||||
if test "$enable_fnmatch" != no; then
|
||||
use_fnmatch=
|
||||
AC_CHECK_FUNCS(fnmatch, use_fnmatch=yes)
|
||||
fi
|
||||
@ -140,10 +140,18 @@ if test "$ac_cv_func_signal" != yes; then
|
||||
fi
|
||||
|
||||
dnl Check for stat64 (dietlibc/klibc).
|
||||
AC_CHECK_FUNC(stat64,, [
|
||||
AC_CHECK_DECL(stat64, AC_CHECK_FUNC(stat64))
|
||||
if test "$ac_cv_func_stat64" != yes; then
|
||||
AC_DEFINE(fstat64, fstat, [64-bit operations are the same as 32-bit])
|
||||
AC_DEFINE(lstat64, lstat, [64-bit operations are the same as 32-bit])
|
||||
AC_DEFINE(stat64, stat, [64-bit operations are the same as 32-bit])
|
||||
fi
|
||||
|
||||
AC_CHECK_FUNC(glob64,, [
|
||||
AC_DEFINE(glob64_t, glob_t, [64-bit operations are the same as 32-bit])
|
||||
AC_DEFINE(glob64, glob, [64-bit operations are the same as 32-bit])
|
||||
AC_DEFINE(globfree64, globfree,
|
||||
[64-bit operations are the same as 32-bit])
|
||||
])
|
||||
|
||||
dnl OS X apparently has stat64 but not open64.
|
||||
@ -175,7 +183,8 @@ if test "$with_libedit" = "yes"; then
|
||||
AC_CHECK_LIB(edit, history_init, [
|
||||
AC_CHECK_HEADER([histedit.h], [use_libedit="yes"],
|
||||
AC_MSG_ERROR(
|
||||
[Can't find required header files.]))])
|
||||
[Can't find required header files.]))], [
|
||||
AC_MSG_ERROR([Can't find libedit.])])
|
||||
fi
|
||||
if test "$use_libedit" != "yes"; then
|
||||
AC_DEFINE([SMALL], 1, [Define if you build with -DSMALL])
|
||||
|
||||
2
depcomp
2
depcomp
@ -3,7 +3,7 @@
|
||||
|
||||
scriptversion=2018-03-07.03; # UTC
|
||||
|
||||
# Copyright (C) 1999-2018 Free Software Foundation, Inc.
|
||||
# Copyright (C) 1999-2020 Free Software Foundation, Inc.
|
||||
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
|
||||
157
install-sh
157
install-sh
@ -1,7 +1,7 @@
|
||||
#!/bin/sh
|
||||
# install - install a program, script, or datafile
|
||||
|
||||
scriptversion=2018-03-11.20; # UTC
|
||||
scriptversion=2020-11-14.01; # UTC
|
||||
|
||||
# This originates from X11R5 (mit/util/scripts/install.sh), which was
|
||||
# later released in X11R6 (xc/config/util/install.sh) with the
|
||||
@ -69,6 +69,11 @@ posix_mkdir=
|
||||
# Desired mode of installed file.
|
||||
mode=0755
|
||||
|
||||
# Create dirs (including intermediate dirs) using mode 755.
|
||||
# This is like GNU 'install' as of coreutils 8.32 (2020).
|
||||
mkdir_umask=22
|
||||
|
||||
backupsuffix=
|
||||
chgrpcmd=
|
||||
chmodcmd=$chmodprog
|
||||
chowncmd=
|
||||
@ -99,18 +104,28 @@ Options:
|
||||
--version display version info and exit.
|
||||
|
||||
-c (ignored)
|
||||
-C install only if different (preserve the last data modification time)
|
||||
-C install only if different (preserve data modification time)
|
||||
-d create directories instead of installing files.
|
||||
-g GROUP $chgrpprog installed files to GROUP.
|
||||
-m MODE $chmodprog installed files to MODE.
|
||||
-o USER $chownprog installed files to USER.
|
||||
-p pass -p to $cpprog.
|
||||
-s $stripprog installed files.
|
||||
-S SUFFIX attempt to back up existing files, with suffix SUFFIX.
|
||||
-t DIRECTORY install into DIRECTORY.
|
||||
-T report an error if DSTFILE is a directory.
|
||||
|
||||
Environment variables override the default commands:
|
||||
CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG
|
||||
RMPROG STRIPPROG
|
||||
|
||||
By default, rm is invoked with -f; when overridden with RMPROG,
|
||||
it's up to you to specify -f if you want it.
|
||||
|
||||
If -S is not specified, no backups are attempted.
|
||||
|
||||
Email bug reports to bug-automake@gnu.org.
|
||||
Automake home page: https://www.gnu.org/software/automake/
|
||||
"
|
||||
|
||||
while test $# -ne 0; do
|
||||
@ -137,8 +152,13 @@ while test $# -ne 0; do
|
||||
-o) chowncmd="$chownprog $2"
|
||||
shift;;
|
||||
|
||||
-p) cpprog="$cpprog -p";;
|
||||
|
||||
-s) stripcmd=$stripprog;;
|
||||
|
||||
-S) backupsuffix="$2"
|
||||
shift;;
|
||||
|
||||
-t)
|
||||
is_target_a_directory=always
|
||||
dst_arg=$2
|
||||
@ -255,6 +275,10 @@ do
|
||||
dstdir=$dst
|
||||
test -d "$dstdir"
|
||||
dstdir_status=$?
|
||||
# Don't chown directories that already exist.
|
||||
if test $dstdir_status = 0; then
|
||||
chowncmd=""
|
||||
fi
|
||||
else
|
||||
|
||||
# Waiting for this to be detected by the "$cpprog $src $dsttmp" command
|
||||
@ -301,22 +325,6 @@ do
|
||||
if test $dstdir_status != 0; then
|
||||
case $posix_mkdir in
|
||||
'')
|
||||
# Create intermediate dirs using mode 755 as modified by the umask.
|
||||
# This is like FreeBSD 'install' as of 1997-10-28.
|
||||
umask=`umask`
|
||||
case $stripcmd.$umask in
|
||||
# Optimize common cases.
|
||||
*[2367][2367]) mkdir_umask=$umask;;
|
||||
.*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;;
|
||||
|
||||
*[0-7])
|
||||
mkdir_umask=`expr $umask + 22 \
|
||||
- $umask % 100 % 40 + $umask % 20 \
|
||||
- $umask % 10 % 4 + $umask % 2
|
||||
`;;
|
||||
*) mkdir_umask=$umask,go-w;;
|
||||
esac
|
||||
|
||||
# With -d, create the new directory with the user-specified mode.
|
||||
# Otherwise, rely on $mkdir_umask.
|
||||
if test -n "$dir_arg"; then
|
||||
@ -326,52 +334,49 @@ do
|
||||
fi
|
||||
|
||||
posix_mkdir=false
|
||||
case $umask in
|
||||
*[123567][0-7][0-7])
|
||||
# POSIX mkdir -p sets u+wx bits regardless of umask, which
|
||||
# is incompatible with FreeBSD 'install' when (umask & 300) != 0.
|
||||
;;
|
||||
*)
|
||||
# Note that $RANDOM variable is not portable (e.g. dash); Use it
|
||||
# here however when possible just to lower collision chance.
|
||||
tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$
|
||||
# The $RANDOM variable is not portable (e.g., dash). Use it
|
||||
# here however when possible just to lower collision chance.
|
||||
tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$
|
||||
|
||||
trap 'ret=$?; rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir" 2>/dev/null; exit $ret' 0
|
||||
trap '
|
||||
ret=$?
|
||||
rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir" 2>/dev/null
|
||||
exit $ret
|
||||
' 0
|
||||
|
||||
# Because "mkdir -p" follows existing symlinks and we likely work
|
||||
# directly in world-writeable /tmp, make sure that the '$tmpdir'
|
||||
# directory is successfully created first before we actually test
|
||||
# 'mkdir -p' feature.
|
||||
if (umask $mkdir_umask &&
|
||||
$mkdirprog $mkdir_mode "$tmpdir" &&
|
||||
exec $mkdirprog $mkdir_mode -p -- "$tmpdir/a/b") >/dev/null 2>&1
|
||||
then
|
||||
if test -z "$dir_arg" || {
|
||||
# Check for POSIX incompatibilities with -m.
|
||||
# HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or
|
||||
# other-writable bit of parent directory when it shouldn't.
|
||||
# FreeBSD 6.1 mkdir -m -p sets mode of existing directory.
|
||||
test_tmpdir="$tmpdir/a"
|
||||
ls_ld_tmpdir=`ls -ld "$test_tmpdir"`
|
||||
case $ls_ld_tmpdir in
|
||||
d????-?r-*) different_mode=700;;
|
||||
d????-?--*) different_mode=755;;
|
||||
*) false;;
|
||||
esac &&
|
||||
$mkdirprog -m$different_mode -p -- "$test_tmpdir" && {
|
||||
ls_ld_tmpdir_1=`ls -ld "$test_tmpdir"`
|
||||
test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1"
|
||||
}
|
||||
}
|
||||
then posix_mkdir=:
|
||||
fi
|
||||
rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir"
|
||||
else
|
||||
# Remove any dirs left behind by ancient mkdir implementations.
|
||||
rmdir ./$mkdir_mode ./-p ./-- "$tmpdir" 2>/dev/null
|
||||
fi
|
||||
trap '' 0;;
|
||||
esac;;
|
||||
# Because "mkdir -p" follows existing symlinks and we likely work
|
||||
# directly in world-writeable /tmp, make sure that the '$tmpdir'
|
||||
# directory is successfully created first before we actually test
|
||||
# 'mkdir -p'.
|
||||
if (umask $mkdir_umask &&
|
||||
$mkdirprog $mkdir_mode "$tmpdir" &&
|
||||
exec $mkdirprog $mkdir_mode -p -- "$tmpdir/a/b") >/dev/null 2>&1
|
||||
then
|
||||
if test -z "$dir_arg" || {
|
||||
# Check for POSIX incompatibilities with -m.
|
||||
# HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or
|
||||
# other-writable bit of parent directory when it shouldn't.
|
||||
# FreeBSD 6.1 mkdir -m -p sets mode of existing directory.
|
||||
test_tmpdir="$tmpdir/a"
|
||||
ls_ld_tmpdir=`ls -ld "$test_tmpdir"`
|
||||
case $ls_ld_tmpdir in
|
||||
d????-?r-*) different_mode=700;;
|
||||
d????-?--*) different_mode=755;;
|
||||
*) false;;
|
||||
esac &&
|
||||
$mkdirprog -m$different_mode -p -- "$test_tmpdir" && {
|
||||
ls_ld_tmpdir_1=`ls -ld "$test_tmpdir"`
|
||||
test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1"
|
||||
}
|
||||
}
|
||||
then posix_mkdir=:
|
||||
fi
|
||||
rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir"
|
||||
else
|
||||
# Remove any dirs left behind by ancient mkdir implementations.
|
||||
rmdir ./$mkdir_mode ./-p ./-- "$tmpdir" 2>/dev/null
|
||||
fi
|
||||
trap '' 0;;
|
||||
esac
|
||||
|
||||
if
|
||||
@ -382,7 +387,7 @@ do
|
||||
then :
|
||||
else
|
||||
|
||||
# The umask is ridiculous, or mkdir does not conform to POSIX,
|
||||
# mkdir does not conform to POSIX,
|
||||
# or it failed possibly due to a race condition. Create the
|
||||
# directory the slow way, step by step, checking for races as we go.
|
||||
|
||||
@ -411,7 +416,7 @@ do
|
||||
prefixes=
|
||||
else
|
||||
if $posix_mkdir; then
|
||||
(umask=$mkdir_umask &&
|
||||
(umask $mkdir_umask &&
|
||||
$doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break
|
||||
# Don't fail if two instances are running concurrently.
|
||||
test -d "$prefix" || exit 1
|
||||
@ -451,7 +456,18 @@ do
|
||||
trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0
|
||||
|
||||
# Copy the file name to the temp name.
|
||||
(umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") &&
|
||||
(umask $cp_umask &&
|
||||
{ test -z "$stripcmd" || {
|
||||
# Create $dsttmp read-write so that cp doesn't create it read-only,
|
||||
# which would cause strip to fail.
|
||||
if test -z "$doit"; then
|
||||
: >"$dsttmp" # No need to fork-exec 'touch'.
|
||||
else
|
||||
$doit touch "$dsttmp"
|
||||
fi
|
||||
}
|
||||
} &&
|
||||
$doit_exec $cpprog "$src" "$dsttmp") &&
|
||||
|
||||
# and set any options; do chmod last to preserve setuid bits.
|
||||
#
|
||||
@ -477,6 +493,13 @@ do
|
||||
then
|
||||
rm -f "$dsttmp"
|
||||
else
|
||||
# If $backupsuffix is set, and the file being installed
|
||||
# already exists, attempt a backup. Don't worry if it fails,
|
||||
# e.g., if mv doesn't support -f.
|
||||
if test -n "$backupsuffix" && test -f "$dst"; then
|
||||
$doit $mvcmd -f "$dst" "$dst$backupsuffix" 2>/dev/null
|
||||
fi
|
||||
|
||||
# Rename the file to the real destination.
|
||||
$doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null ||
|
||||
|
||||
@ -491,9 +514,9 @@ do
|
||||
# file should still install successfully.
|
||||
{
|
||||
test ! -f "$dst" ||
|
||||
$doit $rmcmd -f "$dst" 2>/dev/null ||
|
||||
$doit $rmcmd "$dst" 2>/dev/null ||
|
||||
{ $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null &&
|
||||
{ $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; }
|
||||
{ $doit $rmcmd "$rmtmp" 2>/dev/null; :; }
|
||||
} ||
|
||||
{ echo "$0: cannot unlink or rename $dst" >&2
|
||||
(exit 1); exit 1
|
||||
|
||||
2
missing
2
missing
@ -3,7 +3,7 @@
|
||||
|
||||
scriptversion=2018-03-07.03; # UTC
|
||||
|
||||
# Copyright (C) 1996-2018 Free Software Foundation, Inc.
|
||||
# Copyright (C) 1996-2020 Free Software Foundation, Inc.
|
||||
# Originally written by Fran,cois Pinard <pinard@iro.umontreal.ca>, 1996.
|
||||
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
# Makefile.in generated by automake 1.16.1 from Makefile.am.
|
||||
# Makefile.in generated by automake 1.16.3 from Makefile.am.
|
||||
# @configure_input@
|
||||
|
||||
# Copyright (C) 1994-2018 Free Software Foundation, Inc.
|
||||
# Copyright (C) 1994-2020 Free Software Foundation, Inc.
|
||||
|
||||
# This Makefile.in is free software; the Free Software Foundation
|
||||
# gives unlimited permission to copy and/or distribute it,
|
||||
@ -628,7 +628,8 @@ installdirs:
|
||||
done
|
||||
install: $(BUILT_SOURCES)
|
||||
$(MAKE) $(AM_MAKEFLAGS) install-am
|
||||
install-exec: install-exec-am
|
||||
install-exec: $(BUILT_SOURCES)
|
||||
$(MAKE) $(AM_MAKEFLAGS) install-exec-am
|
||||
install-data: install-data-am
|
||||
uninstall: uninstall-am
|
||||
|
||||
@ -784,7 +785,7 @@ uninstall-am: uninstall-binPROGRAMS uninstall-man
|
||||
|
||||
uninstall-man: uninstall-man1
|
||||
|
||||
.MAKE: all check install install-am install-strip
|
||||
.MAKE: all check install install-am install-exec install-strip
|
||||
|
||||
.PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \
|
||||
clean-binPROGRAMS clean-generic cscopelist-am ctags ctags-am \
|
||||
|
||||
57
src/dash.1
57
src/dash.1
@ -33,8 +33,8 @@
|
||||
.\" @(#)sh.1 8.6 (Berkeley) 5/4/95
|
||||
.\"
|
||||
.Dd January 19, 2003
|
||||
.Os
|
||||
.Dt DASH 1
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm dash
|
||||
.Nd command interpreter (shell)
|
||||
@ -439,7 +439,7 @@ instead of
|
||||
then leading tabs in the here-doc-text are stripped.
|
||||
.Ss Search and Execution
|
||||
There are three types of commands: shell functions, builtin commands, and
|
||||
normal programs -- and the command is searched for (by name) in that order.
|
||||
normal programs \(en and the command is searched for (by name) in that order.
|
||||
They each are executed in a different way.
|
||||
.Pp
|
||||
When a shell function is executed, all of the shell positional parameters
|
||||
@ -578,11 +578,11 @@ the preceding AND-OR-list.
|
||||
.Pp
|
||||
Note that unlike some other shells, each process in the pipeline is a
|
||||
child of the invoking shell (unless it is a shell builtin, in which case
|
||||
it executes in the current shell -- but any effect it has on the
|
||||
it executes in the current shell \(en but any effect it has on the
|
||||
environment is wiped).
|
||||
.Ss Background Commands -- &
|
||||
.Ss Background Commands \(en &
|
||||
If a command is terminated by the control operator ampersand (&), the
|
||||
shell executes the command asynchronously -- that is, the shell does not
|
||||
shell executes the command asynchronously \(en that is, the shell does not
|
||||
wait for the command to finish before executing the next command.
|
||||
.Pp
|
||||
The format for running a command in background is:
|
||||
@ -592,7 +592,7 @@ The format for running a command in background is:
|
||||
If the shell is not interactive, the standard input of an asynchronous
|
||||
command is set to
|
||||
.Pa /dev/null .
|
||||
.Ss Lists -- Generally Speaking
|
||||
.Ss Lists \(en Generally Speaking
|
||||
A list is a sequence of zero or more commands separated by newlines,
|
||||
semicolons, or ampersands, and optionally terminated by one of these three
|
||||
characters.
|
||||
@ -615,7 +615,7 @@ of the first command is nonzero.
|
||||
and
|
||||
.Dq ||
|
||||
both have the same priority.
|
||||
.Ss Flow-Control Constructs -- if, while, for, case
|
||||
.Ss Flow-Control Constructs \(en if, while, for, case
|
||||
The syntax of the if command is
|
||||
.Bd -literal -offset indent
|
||||
if list
|
||||
@ -694,7 +694,7 @@ Builtin commands grouped into a (list) will not affect the current shell.
|
||||
The second form does not fork another shell so is slightly more efficient.
|
||||
Grouping commands together this way allows you to redirect
|
||||
their output as though they were one program:
|
||||
.Pp
|
||||
.\".Pp
|
||||
.Bd -literal -offset indent
|
||||
{ printf \*q hello \*q ; printf \*q world\\n" ; } \*[Gt] greeting
|
||||
.Ed
|
||||
@ -1177,13 +1177,14 @@ mechanism was used or because the argument is a single dash.
|
||||
The
|
||||
.Fl P
|
||||
option causes the physical directory structure to be used, that is, all
|
||||
symbolic links are resolved to their respective values. The
|
||||
symbolic links are resolved to their respective values.
|
||||
The
|
||||
.Fl L
|
||||
option turns off the effect of any preceding
|
||||
.Fl P
|
||||
options.
|
||||
.It Xo echo Op Fl n
|
||||
.Ar args...
|
||||
.Ar args...
|
||||
.Xc
|
||||
Print the arguments on the standard output, separated by spaces.
|
||||
Unless the
|
||||
@ -1191,13 +1192,15 @@ Unless the
|
||||
option is present, a newline is output following the arguments.
|
||||
.Pp
|
||||
If any of the following sequences of characters is encountered during
|
||||
output, the sequence is not output. Instead, the specified action is
|
||||
output, the sequence is not output.
|
||||
Instead, the specified action is
|
||||
performed:
|
||||
.Bl -tag -width indent
|
||||
.It Li \eb
|
||||
A backspace character is output.
|
||||
.It Li \ec
|
||||
Subsequent output is suppressed. This is normally used at the end of the
|
||||
Subsequent output is suppressed.
|
||||
This is normally used at the end of the
|
||||
last argument to suppress the trailing newline that
|
||||
.Ic echo
|
||||
would otherwise output.
|
||||
@ -1417,7 +1420,7 @@ and
|
||||
and the option
|
||||
.Op c ,
|
||||
which requires an argument.
|
||||
.Pp
|
||||
.\".Pp
|
||||
.Bd -literal -offset indent
|
||||
while getopts abc: f
|
||||
do
|
||||
@ -1431,7 +1434,7 @@ shift `expr $OPTIND - 1`
|
||||
.Ed
|
||||
.Pp
|
||||
This code will accept any of the following as equivalent:
|
||||
.Pp
|
||||
.\".Pp
|
||||
.Bd -literal -offset indent
|
||||
cmd \-acarg file file
|
||||
cmd \-a \-c arg file file
|
||||
@ -1471,7 +1474,8 @@ will continue to print the old name for the directory.
|
||||
The
|
||||
.Fl P
|
||||
option causes the physical value of the current working directory to be shown,
|
||||
that is, all symbolic links are resolved to their respective values. The
|
||||
that is, all symbolic links are resolved to their respective values.
|
||||
The
|
||||
.Fl L
|
||||
option turns off the effect of any preceding
|
||||
.Fl P
|
||||
@ -1522,7 +1526,7 @@ variables.
|
||||
With the
|
||||
.Fl p
|
||||
option specified the output will be formatted suitably for non-interactive use.
|
||||
.Pp
|
||||
.\".Pp
|
||||
.It Xo printf Ar format
|
||||
.Op Ar arguments ...
|
||||
.Xc
|
||||
@ -1780,9 +1784,11 @@ If options are given, it sets the specified option
|
||||
flags, or clears them as described in the section called
|
||||
.Sx Argument List Processing .
|
||||
As a special case, if the option is -o or +o and no argument is
|
||||
supplied, the shell prints the settings of all its options. If the
|
||||
option is -o, the settings are printed in a human-readable format; if
|
||||
the option is +o, the settings are printed in a format suitable for
|
||||
supplied, the shell prints the settings of all its options.
|
||||
If the option is -o,
|
||||
the settings are printed in a human-readable format;
|
||||
if the option is +o,
|
||||
the settings are printed in a format suitable for
|
||||
reinput to the shell to affect the same option settings.
|
||||
.Pp
|
||||
The third use of the set command is to set the values of the shell's
|
||||
@ -2058,7 +2064,8 @@ operator has higher precedence than the
|
||||
operator.
|
||||
.It times
|
||||
Print the accumulated user and system times for the shell and for processes
|
||||
run from the shell. The return status is 0.
|
||||
run from the shell.
|
||||
The return status is 0.
|
||||
.It Xo trap
|
||||
.Op Ar action Ar signal ...
|
||||
.Xc
|
||||
@ -2179,7 +2186,7 @@ the current limit is displayed.
|
||||
Limits of an arbitrary process can be displayed or set using the
|
||||
.Xr sysctl 8
|
||||
utility.
|
||||
.Pp
|
||||
.\".Pp
|
||||
.It umask Op Ar mask
|
||||
Set the value of umask (see
|
||||
.Xr umask 2 )
|
||||
@ -2308,11 +2315,13 @@ children of the shell, and is used in the history editing modes.
|
||||
.It Ev HISTSIZE
|
||||
The number of lines in the history buffer for the shell.
|
||||
.It Ev PWD
|
||||
The logical value of the current working directory. This is set by the
|
||||
The logical value of the current working directory.
|
||||
This is set by the
|
||||
.Ic cd
|
||||
command.
|
||||
.It Ev OLDPWD
|
||||
The previous logical value of the current working directory. This is set by
|
||||
The previous logical value of the current working directory.
|
||||
This is set by
|
||||
the
|
||||
.Ic cd
|
||||
command.
|
||||
@ -2320,7 +2329,7 @@ command.
|
||||
The process ID of the parent process of the shell.
|
||||
.El
|
||||
.Sh FILES
|
||||
.Bl -item -width HOMEprofilexxxx
|
||||
.Bl -item
|
||||
.It
|
||||
.Pa $HOME/.profile
|
||||
.It
|
||||
|
||||
@ -116,11 +116,7 @@ void __inton(void);
|
||||
#define int_pending() intpending
|
||||
|
||||
void exraise(int) __attribute__((__noreturn__));
|
||||
#ifdef USE_NORETURN
|
||||
void onint(void) __attribute__((__noreturn__));
|
||||
#else
|
||||
void onint(void);
|
||||
#endif
|
||||
extern int errlinno;
|
||||
void sh_error(const char *, ...) __attribute__((__noreturn__));
|
||||
void exerror(int, const char *, ...) __attribute__((__noreturn__));
|
||||
|
||||
47
src/eval.c
47
src/eval.c
@ -78,6 +78,9 @@ int exitstatus; /* exit status of last command */
|
||||
int back_exitstatus; /* exit status of backquoted command */
|
||||
int savestatus = -1; /* exit status of last command outside traps */
|
||||
|
||||
/* Prevent PS4 nesting. */
|
||||
MKINIT int inps4;
|
||||
|
||||
|
||||
#if !defined(__alpha__) || (defined(__GNUC__) && __GNUC__ >= 3)
|
||||
STATIC
|
||||
@ -123,6 +126,7 @@ EXITRESET {
|
||||
}
|
||||
evalskip = 0;
|
||||
loopnest = 0;
|
||||
inps4 = 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -209,6 +213,9 @@ evaltree(union node *n, int flags)
|
||||
|
||||
setstackmark(&smark);
|
||||
|
||||
if (nflag)
|
||||
goto out;
|
||||
|
||||
if (n == NULL) {
|
||||
TRACE(("evaltree(NULL) called\n"));
|
||||
goto out;
|
||||
@ -231,32 +238,29 @@ evaltree(union node *n, int flags)
|
||||
break;
|
||||
#endif
|
||||
case NNOT:
|
||||
status = !evaltree(n->nnot.com, EV_TESTED);
|
||||
goto setstatus;
|
||||
status = evaltree(n->nnot.com, EV_TESTED);
|
||||
if (!evalskip)
|
||||
status = !status;
|
||||
break;
|
||||
case NREDIR:
|
||||
errlinno = lineno = n->nredir.linno;
|
||||
if (funcline)
|
||||
lineno -= funcline - 1;
|
||||
expredir(n->nredir.redirect);
|
||||
pushredir(n->nredir.redirect);
|
||||
status = redirectsafe(n->nredir.redirect, REDIR_PUSH) ?:
|
||||
evaltree(n->nredir.n, flags & EV_TESTED);
|
||||
status = redirectsafe(n->nredir.redirect, REDIR_PUSH);
|
||||
if (status)
|
||||
checkexit = EV_TESTED;
|
||||
else
|
||||
status = evaltree(n->nredir.n, flags & EV_TESTED);
|
||||
if (n->nredir.redirect)
|
||||
popredir(0);
|
||||
goto setstatus;
|
||||
break;
|
||||
case NCMD:
|
||||
#ifdef notyet
|
||||
if (eflag && !(flags & EV_TESTED))
|
||||
checkexit = ~0;
|
||||
status = evalcommand(n, flags, (struct backcmd *)NULL);
|
||||
goto setstatus;
|
||||
#else
|
||||
evalfn = evalcommand;
|
||||
checkexit:
|
||||
if (eflag && !(flags & EV_TESTED))
|
||||
checkexit = ~0;
|
||||
checkexit = EV_TESTED;
|
||||
goto calleval;
|
||||
#endif
|
||||
case NFOR:
|
||||
evalfn = evalfor;
|
||||
goto calleval;
|
||||
@ -293,7 +297,7 @@ evaln:
|
||||
evalfn = evaltree;
|
||||
calleval:
|
||||
status = evalfn(n, flags);
|
||||
goto setstatus;
|
||||
break;
|
||||
case NIF:
|
||||
status = evaltree(n->nif.test, EV_TESTED);
|
||||
if (evalskip)
|
||||
@ -306,17 +310,18 @@ calleval:
|
||||
goto evaln;
|
||||
}
|
||||
status = 0;
|
||||
goto setstatus;
|
||||
break;
|
||||
case NDEFUN:
|
||||
defun(n);
|
||||
setstatus:
|
||||
exitstatus = status;
|
||||
break;
|
||||
}
|
||||
|
||||
exitstatus = status;
|
||||
|
||||
out:
|
||||
dotrap();
|
||||
|
||||
if (checkexit & status)
|
||||
if (eflag && (~flags & checkexit) && status)
|
||||
goto exexit;
|
||||
|
||||
if (flags & EV_EXIT) {
|
||||
@ -855,12 +860,14 @@ bail:
|
||||
}
|
||||
|
||||
/* Print the command if xflag is set. */
|
||||
if (xflag) {
|
||||
if (xflag && !inps4) {
|
||||
struct output *out;
|
||||
int sep;
|
||||
|
||||
out = &preverrout;
|
||||
inps4 = 1;
|
||||
outstr(expandstr(ps4val()), out);
|
||||
inps4 = 0;
|
||||
sep = 0;
|
||||
sep = eprintlist(out, varlist.list, sep);
|
||||
eprintlist(out, osp, sep);
|
||||
|
||||
115
src/expand.c
115
src/expand.c
@ -120,7 +120,7 @@ static size_t memtodest(const char *p, size_t len, int flags);
|
||||
STATIC ssize_t varvalue(char *, int, int, int);
|
||||
STATIC void expandmeta(struct strlist *);
|
||||
#ifdef HAVE_GLOB
|
||||
STATIC void addglob(const glob_t *);
|
||||
static void addglob(const glob64_t *);
|
||||
#else
|
||||
STATIC void expmeta(char *, unsigned, unsigned);
|
||||
STATIC struct strlist *expsort(struct strlist *);
|
||||
@ -135,8 +135,6 @@ STATIC int pmatch(const char *, const char *);
|
||||
#endif
|
||||
static size_t cvtnum(intmax_t num, int flags);
|
||||
STATIC size_t esclen(const char *, const char *);
|
||||
STATIC char *scanleft(char *, char *, char *, char *, int, int);
|
||||
STATIC char *scanright(char *, char *, char *, char *, int, int);
|
||||
STATIC void varunset(const char *, const char *, const char *, int)
|
||||
__attribute__((__noreturn__));
|
||||
|
||||
@ -541,10 +539,8 @@ out:
|
||||
}
|
||||
|
||||
|
||||
STATIC char *
|
||||
scanleft(
|
||||
char *startp, char *rmesc, char *rmescend, char *str, int quotes,
|
||||
int zero
|
||||
static char *scanleft(char *startp, char *endp, char *rmesc, char *rmescend,
|
||||
char *str, int quotes, int zero
|
||||
) {
|
||||
char *loc;
|
||||
char *loc2;
|
||||
@ -573,16 +569,14 @@ scanleft(
|
||||
}
|
||||
|
||||
|
||||
STATIC char *
|
||||
scanright(
|
||||
char *startp, char *rmesc, char *rmescend, char *str, int quotes,
|
||||
int zero
|
||||
static char *scanright(char *startp, char *endp, char *rmesc, char *rmescend,
|
||||
char *str, int quotes, int zero
|
||||
) {
|
||||
int esc = 0;
|
||||
char *loc;
|
||||
char *loc2;
|
||||
|
||||
for (loc = str - 1, loc2 = rmescend; loc >= startp; loc2--) {
|
||||
for (loc = endp, loc2 = rmescend; loc >= startp; loc2--) {
|
||||
int match;
|
||||
char c = *loc2;
|
||||
const char *s = loc2;
|
||||
@ -618,7 +612,9 @@ static char *subevalvar(char *start, char *str, int strloc, int startloc,
|
||||
long amount;
|
||||
char *rmesc, *rmescend;
|
||||
int zero;
|
||||
char *(*scan)(char *, char *, char *, char *, int , int);
|
||||
char *(*scan)(char *, char *, char *, char *, char *, int , int);
|
||||
int nstrloc = strloc;
|
||||
char *endp;
|
||||
char *p;
|
||||
|
||||
p = argstr(start, (flag & EXP_DISCARD) | EXP_TILDE |
|
||||
@ -646,33 +642,40 @@ static char *subevalvar(char *start, char *str, int strloc, int startloc,
|
||||
abort();
|
||||
#endif
|
||||
|
||||
rmesc = startp;
|
||||
rmescend = stackblock() + strloc;
|
||||
str = preglob(rmescend, FNMATCH_IS_ENABLED ?
|
||||
RMESCAPE_ALLOC | RMESCAPE_GROW : 0);
|
||||
if (FNMATCH_IS_ENABLED) {
|
||||
startp = stackblock() + startloc;
|
||||
rmescend = stackblock() + strloc;
|
||||
nstrloc = str - (char *)stackblock();
|
||||
}
|
||||
|
||||
rmesc = startp;
|
||||
if (quotes) {
|
||||
rmesc = _rmescapes(startp, RMESCAPE_ALLOC | RMESCAPE_GROW);
|
||||
if (rmesc != startp) {
|
||||
if (rmesc != startp)
|
||||
rmescend = expdest;
|
||||
startp = stackblock() + startloc;
|
||||
}
|
||||
startp = stackblock() + startloc;
|
||||
str = stackblock() + nstrloc;
|
||||
}
|
||||
rmescend--;
|
||||
str = stackblock() + strloc;
|
||||
preglob(str, 0);
|
||||
|
||||
/* zero = subtype == VSTRIMLEFT || subtype == VSTRIMLEFTMAX */
|
||||
zero = subtype >> 1;
|
||||
/* VSTRIMLEFT/VSTRIMRIGHTMAX -> scanleft */
|
||||
scan = (subtype & 1) ^ zero ? scanleft : scanright;
|
||||
|
||||
loc = scan(startp, rmesc, rmescend, str, quotes, zero);
|
||||
endp = stackblock() + strloc - 1;
|
||||
loc = scan(startp, endp, rmesc, rmescend, str, quotes, zero);
|
||||
if (loc) {
|
||||
if (zero) {
|
||||
memmove(startp, loc, str - loc);
|
||||
loc = startp + (str - loc) - 1;
|
||||
memmove(startp, loc, endp - loc);
|
||||
loc = startp + (endp - loc);
|
||||
}
|
||||
*loc = '\0';
|
||||
} else
|
||||
loc = str - 1;
|
||||
loc = endp;
|
||||
|
||||
out:
|
||||
amount = loc - expdest;
|
||||
@ -701,7 +704,7 @@ evalvar(char *p, int flag)
|
||||
int discard;
|
||||
int quoted;
|
||||
|
||||
varflags = *p++;
|
||||
varflags = *p++ & ~VSBIT;
|
||||
subtype = varflags & VSTYPE;
|
||||
|
||||
quoted = flag & EXP_QUOTED;
|
||||
@ -1154,6 +1157,20 @@ out:
|
||||
*/
|
||||
|
||||
#ifdef HAVE_GLOB
|
||||
#ifdef __GLIBC__
|
||||
void *opendir_interruptible(const char *pathname)
|
||||
{
|
||||
if (int_pending()) {
|
||||
suppressint = 0;
|
||||
onint();
|
||||
}
|
||||
|
||||
return opendir(pathname);
|
||||
}
|
||||
#else
|
||||
#define GLOB_ALTDIRFUNC 0
|
||||
#endif
|
||||
|
||||
STATIC void
|
||||
expandmeta(struct strlist *str)
|
||||
{
|
||||
@ -1161,14 +1178,23 @@ expandmeta(struct strlist *str)
|
||||
|
||||
while (str) {
|
||||
const char *p;
|
||||
glob_t pglob;
|
||||
glob64_t pglob;
|
||||
int i;
|
||||
|
||||
if (fflag)
|
||||
goto nometa;
|
||||
|
||||
#ifdef __GLIBC__
|
||||
pglob.gl_closedir = (void *)closedir;
|
||||
pglob.gl_readdir = (void *)readdir64;
|
||||
pglob.gl_opendir = opendir_interruptible;
|
||||
pglob.gl_lstat = lstat64;
|
||||
pglob.gl_stat = stat64;
|
||||
#endif
|
||||
|
||||
INTOFF;
|
||||
p = preglob(str->text, RMESCAPE_ALLOC | RMESCAPE_HEAP);
|
||||
i = glob(p, GLOB_NOMAGIC, 0, &pglob);
|
||||
i = glob64(p, GLOB_ALTDIRFUNC | GLOB_NOMAGIC, 0, &pglob);
|
||||
if (p != str->text)
|
||||
ckfree(p);
|
||||
switch (i) {
|
||||
@ -1177,12 +1203,12 @@ expandmeta(struct strlist *str)
|
||||
(GLOB_NOMAGIC | GLOB_NOCHECK))
|
||||
goto nometa2;
|
||||
addglob(&pglob);
|
||||
globfree(&pglob);
|
||||
globfree64(&pglob);
|
||||
INTON;
|
||||
break;
|
||||
case GLOB_NOMATCH:
|
||||
nometa2:
|
||||
globfree(&pglob);
|
||||
globfree64(&pglob);
|
||||
INTON;
|
||||
nometa:
|
||||
*exparg.lastp = str;
|
||||
@ -1201,9 +1227,7 @@ nometa:
|
||||
* Add the result of glob(3) to the list.
|
||||
*/
|
||||
|
||||
STATIC void
|
||||
addglob(pglob)
|
||||
const glob_t *pglob;
|
||||
static void addglob(const glob64_t *pglob)
|
||||
{
|
||||
char **p = pglob->gl_pathv;
|
||||
|
||||
@ -1480,7 +1504,9 @@ msort(struct strlist *list, int len)
|
||||
STATIC inline int
|
||||
patmatch(char *pattern, const char *string)
|
||||
{
|
||||
return pmatch(preglob(pattern, 0), string);
|
||||
return pmatch(preglob(pattern, FNMATCH_IS_ENABLED ?
|
||||
RMESCAPE_ALLOC | RMESCAPE_GROW : 0),
|
||||
string);
|
||||
}
|
||||
|
||||
|
||||
@ -1633,15 +1659,22 @@ _rmescapes(char *str, int flag)
|
||||
int notescaped;
|
||||
int globbing;
|
||||
|
||||
p = strpbrk(str, qchars);
|
||||
p = strpbrk(str, cqchars);
|
||||
if (!p) {
|
||||
return str;
|
||||
}
|
||||
q = p;
|
||||
r = str;
|
||||
globbing = flag & RMESCAPE_GLOB;
|
||||
|
||||
if (flag & RMESCAPE_ALLOC) {
|
||||
size_t len = p - str;
|
||||
size_t fulllen = len + strlen(p) + 1;
|
||||
size_t fulllen = strlen(p);
|
||||
|
||||
if (FNMATCH_IS_ENABLED && globbing)
|
||||
fulllen *= 2;
|
||||
|
||||
fulllen += len + 1;
|
||||
|
||||
if (flag & RMESCAPE_GROW) {
|
||||
int strloc = str - (char *)stackblock();
|
||||
@ -1659,7 +1692,6 @@ _rmescapes(char *str, int flag)
|
||||
q = mempcpy(q, str, len);
|
||||
}
|
||||
}
|
||||
globbing = flag & RMESCAPE_GLOB;
|
||||
notescaped = globbing;
|
||||
while (*p) {
|
||||
if (*p == (char)CTLQUOTEMARK) {
|
||||
@ -1672,8 +1704,11 @@ _rmescapes(char *str, int flag)
|
||||
notescaped = 0;
|
||||
goto copy;
|
||||
}
|
||||
if (FNMATCH_IS_ENABLED && *p == '^')
|
||||
goto add_escape;
|
||||
if (*p == (char)CTLESC) {
|
||||
p++;
|
||||
add_escape:
|
||||
if (notescaped)
|
||||
*q++ = '\\';
|
||||
}
|
||||
@ -1742,6 +1777,16 @@ varunset(const char *end, const char *var, const char *umsg, int varflags)
|
||||
sh_error("%.*s: %s%s", end - var - 1, var, msg, tail);
|
||||
}
|
||||
|
||||
void restore_handler_expandarg(struct jmploc *savehandler, int err)
|
||||
{
|
||||
handler = savehandler;
|
||||
if (err) {
|
||||
if (exception != EXERROR)
|
||||
longjmp(handler->loc, 1);
|
||||
ifsfree();
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef mkinit
|
||||
|
||||
INCLUDE "expand.h"
|
||||
|
||||
@ -62,7 +62,9 @@ struct arglist {
|
||||
#define EXP_DISCARD 0x400 /* discard result of expansion */
|
||||
|
||||
|
||||
struct jmploc;
|
||||
union node;
|
||||
|
||||
void expandarg(union node *, struct arglist *, int);
|
||||
#define rmescapes(p) _rmescapes((p), 0)
|
||||
char *_rmescapes(char *, int);
|
||||
@ -71,6 +73,7 @@ void recordregion(int, int, int);
|
||||
void removerecordregions(int);
|
||||
void ifsbreakup(char *, int, struct arglist *);
|
||||
void ifsfree(void);
|
||||
void restore_handler_expandarg(struct jmploc *savehandler, int err);
|
||||
|
||||
/* From arith.y */
|
||||
intmax_t arith(const char *);
|
||||
|
||||
102
src/input.c
102
src/input.c
@ -58,7 +58,6 @@
|
||||
#include "myhistedit.h"
|
||||
#endif
|
||||
|
||||
#define EOF_NLEFT -99 /* value of parsenleft when EOF pushed back */
|
||||
#define IBUFSIZ (BUFSIZ + 1)
|
||||
|
||||
|
||||
@ -68,6 +67,7 @@ struct parsefile *parsefile = &basepf; /* current input file */
|
||||
int whichprompt; /* 1 == PS1, 2 == PS2 */
|
||||
|
||||
STATIC void pushfile(void);
|
||||
static void popstring(void);
|
||||
static int preadfd(void);
|
||||
static void setinputfd(int fd, int push);
|
||||
static int preadbuffer(void);
|
||||
@ -86,6 +86,7 @@ INIT {
|
||||
RESET {
|
||||
/* clear input buffer */
|
||||
basepf.lleft = basepf.nleft = 0;
|
||||
basepf.unget = 0;
|
||||
popallfiles();
|
||||
}
|
||||
|
||||
@ -99,13 +100,32 @@ FORKRESET {
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* Read a character from the script, returning PEOF on end of file.
|
||||
* Nul characters in the input are silently discarded.
|
||||
*/
|
||||
static void freestrings(struct strpush *sp)
|
||||
{
|
||||
INTOFF;
|
||||
do {
|
||||
struct strpush *psp;
|
||||
|
||||
int
|
||||
pgetc(void)
|
||||
if (sp->ap) {
|
||||
sp->ap->flag &= ~ALIASINUSE;
|
||||
if (sp->ap->flag & ALIASDEAD) {
|
||||
unalias(sp->ap->name);
|
||||
}
|
||||
}
|
||||
|
||||
psp = sp;
|
||||
sp = sp->spfree;
|
||||
|
||||
if (psp != &(parsefile->basestrpush))
|
||||
ckfree(psp);
|
||||
} while (sp);
|
||||
|
||||
parsefile->spfree = NULL;
|
||||
INTON;
|
||||
}
|
||||
|
||||
|
||||
static int __pgetc(void)
|
||||
{
|
||||
int c;
|
||||
|
||||
@ -125,17 +145,18 @@ pgetc(void)
|
||||
|
||||
|
||||
/*
|
||||
* Same as pgetc(), but ignores PEOA.
|
||||
* Read a character from the script, returning PEOF on end of file.
|
||||
* Nul characters in the input are silently discarded.
|
||||
*/
|
||||
|
||||
int
|
||||
pgetc2()
|
||||
int pgetc(void)
|
||||
{
|
||||
int c;
|
||||
do {
|
||||
c = pgetc();
|
||||
} while (c == PEOA);
|
||||
return c;
|
||||
struct strpush *sp = parsefile->spfree;
|
||||
|
||||
if (unlikely(sp))
|
||||
freestrings(sp);
|
||||
|
||||
return __pgetc();
|
||||
}
|
||||
|
||||
|
||||
@ -198,9 +219,8 @@ retry:
|
||||
* Refill the input buffer and return the next input character:
|
||||
*
|
||||
* 1) If a string was pushed back on the input, pop it;
|
||||
* 2) If an EOF was pushed back (parsenleft == EOF_NLEFT) or we are reading
|
||||
* from a string so we can't refill the buffer, return EOF.
|
||||
* 3) If the is more stuff in this buffer, use it else call read to fill it.
|
||||
* 2) If we are reading from a string we can't refill the buffer, return EOF.
|
||||
* 3) If there is more stuff in this buffer, use it else call read to fill it.
|
||||
* 4) Process input up to the next newline, deleting nul characters.
|
||||
*/
|
||||
|
||||
@ -214,19 +234,10 @@ static int preadbuffer(void)
|
||||
char savec;
|
||||
|
||||
if (unlikely(parsefile->strpush)) {
|
||||
if (
|
||||
parsefile->nleft == -1 &&
|
||||
parsefile->strpush->ap &&
|
||||
parsefile->nextc[-1] != ' ' &&
|
||||
parsefile->nextc[-1] != '\t'
|
||||
) {
|
||||
return PEOA;
|
||||
}
|
||||
popstring();
|
||||
return pgetc();
|
||||
return __pgetc();
|
||||
}
|
||||
if (unlikely(parsefile->nleft == EOF_NLEFT ||
|
||||
parsefile->buf == NULL))
|
||||
if (parsefile->buf == NULL)
|
||||
return PEOF;
|
||||
flushall();
|
||||
|
||||
@ -234,7 +245,7 @@ static int preadbuffer(void)
|
||||
if (more <= 0) {
|
||||
again:
|
||||
if ((more = preadfd()) <= 0) {
|
||||
parsefile->lleft = parsefile->nleft = EOF_NLEFT;
|
||||
parsefile->lleft = parsefile->nleft = 0;
|
||||
return PEOF;
|
||||
}
|
||||
}
|
||||
@ -331,7 +342,8 @@ pushstring(char *s, void *ap)
|
||||
len = strlen(s);
|
||||
INTOFF;
|
||||
/*dprintf("*** calling pushstring: %s, %d\n", s, len);*/
|
||||
if (parsefile->strpush) {
|
||||
if ((unsigned long)parsefile->strpush |
|
||||
(unsigned long)parsefile->spfree) {
|
||||
sp = ckmalloc(sizeof (struct strpush));
|
||||
sp->prev = parsefile->strpush;
|
||||
parsefile->strpush = sp;
|
||||
@ -340,6 +352,7 @@ pushstring(char *s, void *ap)
|
||||
sp->prevstring = parsefile->nextc;
|
||||
sp->prevnleft = parsefile->nleft;
|
||||
sp->unget = parsefile->unget;
|
||||
sp->spfree = parsefile->spfree;
|
||||
memcpy(sp->lastc, parsefile->lastc, sizeof(sp->lastc));
|
||||
sp->ap = (struct alias *)ap;
|
||||
if (ap) {
|
||||
@ -349,11 +362,11 @@ pushstring(char *s, void *ap)
|
||||
parsefile->nextc = s;
|
||||
parsefile->nleft = len;
|
||||
parsefile->unget = 0;
|
||||
parsefile->spfree = NULL;
|
||||
INTON;
|
||||
}
|
||||
|
||||
void
|
||||
popstring(void)
|
||||
static void popstring(void)
|
||||
{
|
||||
struct strpush *sp = parsefile->strpush;
|
||||
|
||||
@ -366,10 +379,6 @@ popstring(void)
|
||||
if (sp->string != sp->ap->val) {
|
||||
ckfree(sp->string);
|
||||
}
|
||||
sp->ap->flag &= ~ALIASINUSE;
|
||||
if (sp->ap->flag & ALIASDEAD) {
|
||||
unalias(sp->ap->name);
|
||||
}
|
||||
}
|
||||
parsefile->nextc = sp->prevstring;
|
||||
parsefile->nleft = sp->prevnleft;
|
||||
@ -377,8 +386,7 @@ popstring(void)
|
||||
memcpy(parsefile->lastc, sp->lastc, sizeof(sp->lastc));
|
||||
/*dprintf("*** calling popstring: restoring to '%s'\n", parsenextc);*/
|
||||
parsefile->strpush = sp->prev;
|
||||
if (sp != &(parsefile->basestrpush))
|
||||
ckfree(sp);
|
||||
parsefile->spfree = sp;
|
||||
INTON;
|
||||
}
|
||||
|
||||
@ -393,12 +401,9 @@ setinputfile(const char *fname, int flags)
|
||||
int fd;
|
||||
|
||||
INTOFF;
|
||||
if ((fd = open64(fname, O_RDONLY)) < 0) {
|
||||
if (flags & INPUT_NOFILE_OK)
|
||||
goto out;
|
||||
exitstatus = 127;
|
||||
exerror(EXERROR, "Can't open %s", fname);
|
||||
}
|
||||
fd = sh_open(fname, O_RDONLY, flags & INPUT_NOFILE_OK);
|
||||
if (fd < 0)
|
||||
goto out;
|
||||
if (fd < 10)
|
||||
fd = savefd(fd, fd);
|
||||
setinputfd(fd, flags & INPUT_PUSH_FILE);
|
||||
@ -460,6 +465,7 @@ pushfile(void)
|
||||
pf->prev = parsefile;
|
||||
pf->fd = -1;
|
||||
pf->strpush = NULL;
|
||||
pf->spfree = NULL;
|
||||
pf->basestrpush.prev = NULL;
|
||||
pf->unget = 0;
|
||||
parsefile = pf;
|
||||
@ -476,8 +482,12 @@ popfile(void)
|
||||
close(pf->fd);
|
||||
if (pf->buf)
|
||||
ckfree(pf->buf);
|
||||
while (pf->strpush)
|
||||
if (parsefile->spfree)
|
||||
freestrings(parsefile->spfree);
|
||||
while (pf->strpush) {
|
||||
popstring();
|
||||
freestrings(parsefile->spfree);
|
||||
}
|
||||
parsefile = pf->prev;
|
||||
ckfree(pf);
|
||||
INTON;
|
||||
|
||||
@ -50,6 +50,9 @@ struct strpush {
|
||||
struct alias *ap; /* if push was associated with an alias */
|
||||
char *string; /* remember the string since it may change */
|
||||
|
||||
/* Delay freeing so we can stop nested aliases. */
|
||||
struct strpush *spfree;
|
||||
|
||||
/* Remember last two characters for pungetc. */
|
||||
int lastc[2];
|
||||
|
||||
@ -73,6 +76,9 @@ struct parsefile {
|
||||
struct strpush *strpush; /* for pushing strings at this level */
|
||||
struct strpush basestrpush; /* so pushing one is fast */
|
||||
|
||||
/* Delay freeing so we can stop nested aliases. */
|
||||
struct strpush *spfree;
|
||||
|
||||
/* Remember last two characters for pungetc. */
|
||||
int lastc[2];
|
||||
|
||||
@ -93,7 +99,6 @@ int pgetc(void);
|
||||
int pgetc2(void);
|
||||
void pungetc(void);
|
||||
void pushstring(char *, void *);
|
||||
void popstring(void);
|
||||
int setinputfile(const char *, int);
|
||||
void setinputstring(char *);
|
||||
void popfile(void);
|
||||
|
||||
23
src/jobs.c
23
src/jobs.c
@ -81,6 +81,7 @@
|
||||
#define DOWAIT_NONBLOCK 0
|
||||
#define DOWAIT_BLOCK 1
|
||||
#define DOWAIT_WAITCMD 2
|
||||
#define DOWAIT_WAITCMD_ALL 4
|
||||
|
||||
/* array of jobs */
|
||||
static struct job *jobtab;
|
||||
@ -196,7 +197,7 @@ setjobctl(int on)
|
||||
return;
|
||||
if (on) {
|
||||
int ofd;
|
||||
ofd = fd = open64(_PATH_TTY, O_RDWR);
|
||||
ofd = fd = sh_open(_PATH_TTY, O_RDWR, 1);
|
||||
if (fd < 0) {
|
||||
fd += 3;
|
||||
while (!isatty(fd))
|
||||
@ -615,7 +616,7 @@ waitcmd(int argc, char **argv)
|
||||
jp->waited = 1;
|
||||
jp = jp->prev_job;
|
||||
}
|
||||
if (!dowait(DOWAIT_WAITCMD, 0))
|
||||
if (!dowait(DOWAIT_WAITCMD_ALL, 0))
|
||||
goto sigout;
|
||||
}
|
||||
}
|
||||
@ -887,15 +888,12 @@ static void forkchild(struct job *jp, union node *n, int mode)
|
||||
ignoresig(SIGQUIT);
|
||||
if (jp->nprocs == 0) {
|
||||
close(0);
|
||||
if (open64(_PATH_DEVNULL, O_RDONLY) != 0)
|
||||
sh_error("Can't open %s", _PATH_DEVNULL);
|
||||
sh_open(_PATH_DEVNULL, O_RDONLY, 0);
|
||||
}
|
||||
}
|
||||
if (!oldlvl && iflag) {
|
||||
if (mode != FORK_BG) {
|
||||
setsignal(SIGINT);
|
||||
setsignal(SIGQUIT);
|
||||
}
|
||||
setsignal(SIGINT);
|
||||
setsignal(SIGQUIT);
|
||||
setsignal(SIGTERM);
|
||||
}
|
||||
|
||||
@ -1139,6 +1137,7 @@ static int dowait(int block, struct job *jp)
|
||||
pid = waitone(block, jp);
|
||||
rpid &= !!pid;
|
||||
|
||||
block &= ~DOWAIT_WAITCMD_ALL;
|
||||
if (!pid || (jp && jp->state != JOBRUNNING))
|
||||
block = DOWAIT_NONBLOCK;
|
||||
} while (pid >= 0);
|
||||
@ -1511,7 +1510,13 @@ showpipe(struct job *jp, struct output *out)
|
||||
STATIC void
|
||||
xtcsetpgrp(int fd, pid_t pgrp)
|
||||
{
|
||||
if (tcsetpgrp(fd, pgrp))
|
||||
int err;
|
||||
|
||||
sigblockall(NULL);
|
||||
err = tcsetpgrp(fd, pgrp);
|
||||
sigclearmask();
|
||||
|
||||
if (err)
|
||||
sh_error("Cannot set tty process group (%s)", strerror(errno));
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -233,7 +233,7 @@ cmdloop(int top)
|
||||
out2str("\nUse \"exit\" to leave shell.\n");
|
||||
}
|
||||
numeof++;
|
||||
} else if (nflag == 0) {
|
||||
} else {
|
||||
int i;
|
||||
|
||||
job_warning = (job_warning == 2) ? 1 : 0;
|
||||
|
||||
@ -64,7 +64,6 @@ struct synclass synclass[] = {
|
||||
{ "CEOF", "end of file" },
|
||||
{ "CCTL", "like CWORD, except it must be escaped" },
|
||||
{ "CSPCL", "these terminate a word" },
|
||||
{ "CIGN", "character should be ignored" },
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
||||
@ -145,9 +144,8 @@ main(int argc, char **argv)
|
||||
fprintf(hfile, "/* %s */\n", is_entry[i].comment);
|
||||
}
|
||||
putc('\n', hfile);
|
||||
fprintf(hfile, "#define SYNBASE %d\n", 130);
|
||||
fprintf(hfile, "#define PEOF %d\n\n", -130);
|
||||
fprintf(hfile, "#define PEOA %d\n\n", -129);
|
||||
fprintf(hfile, "#define SYNBASE %d\n", 129);
|
||||
fprintf(hfile, "#define PEOF %d\n\n", -129);
|
||||
putc('\n', hfile);
|
||||
fputs("#define BASESYNTAX (basesyntax + SYNBASE)\n", hfile);
|
||||
fputs("#define DQSYNTAX (dqsyntax + SYNBASE)\n", hfile);
|
||||
@ -170,7 +168,6 @@ main(int argc, char **argv)
|
||||
add("$", "CVAR");
|
||||
add("}", "CENDVAR");
|
||||
add("<>();&| \t", "CSPCL");
|
||||
syntax[1] = "CSPCL";
|
||||
print("basesyntax");
|
||||
init();
|
||||
fputs("\n/* syntax table used when in double quotes */\n", cfile);
|
||||
@ -223,7 +220,7 @@ filltable(char *dftval)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0 ; i < 258; i++)
|
||||
for (i = 0 ; i < 257; i++)
|
||||
syntax[i] = dftval;
|
||||
}
|
||||
|
||||
@ -239,9 +236,8 @@ init(void)
|
||||
|
||||
filltable("CWORD");
|
||||
syntax[0] = "CEOF";
|
||||
syntax[1] = "CIGN";
|
||||
for (ctl = CTL_FIRST; ctl <= CTL_LAST; ctl++ )
|
||||
syntax[130 + ctl] = "CCTL";
|
||||
syntax[129 + ctl] = "CCTL";
|
||||
}
|
||||
|
||||
|
||||
@ -253,7 +249,7 @@ static void
|
||||
add(char *p, char *type)
|
||||
{
|
||||
while (*p)
|
||||
syntax[(signed char)*p++ + 130] = type;
|
||||
syntax[(signed char)*p++ + 129] = type;
|
||||
}
|
||||
|
||||
|
||||
@ -271,7 +267,7 @@ print(char *name)
|
||||
fprintf(hfile, "extern const char %s[];\n", name);
|
||||
fprintf(cfile, "const char %s[] = {\n", name);
|
||||
col = 0;
|
||||
for (i = 0 ; i < 258; i++) {
|
||||
for (i = 0 ; i < 257; i++) {
|
||||
if (i == 0) {
|
||||
fputs(" ", cfile);
|
||||
} else if ((i & 03) == 0) {
|
||||
|
||||
@ -60,9 +60,14 @@
|
||||
char nullstr[1]; /* zero length string */
|
||||
const char spcstr[] = " ";
|
||||
const char snlfmt[] = "%s\n";
|
||||
const char dolatstr[] = { CTLQUOTEMARK, CTLVAR, VSNORMAL, '@', '=',
|
||||
const char dolatstr[] = { CTLQUOTEMARK, CTLVAR, VSNORMAL | VSBIT, '@', '=',
|
||||
CTLQUOTEMARK, '\0' };
|
||||
const char qchars[] = { CTLESC, CTLQUOTEMARK, 0 };
|
||||
const char cqchars[] = {
|
||||
#ifdef HAVE_FNMATCH
|
||||
'^',
|
||||
#endif
|
||||
CTLESC, CTLQUOTEMARK, 0
|
||||
};
|
||||
const char illnum[] = "Illegal number: %s";
|
||||
const char homestr[] = "HOME";
|
||||
|
||||
|
||||
@ -37,11 +37,18 @@
|
||||
#include <inttypes.h>
|
||||
#include <string.h>
|
||||
|
||||
#ifdef HAVE_FNMATCH
|
||||
#define FNMATCH_IS_ENABLED 1
|
||||
#else
|
||||
#define FNMATCH_IS_ENABLED 0
|
||||
#endif
|
||||
|
||||
extern const char snlfmt[];
|
||||
extern const char spcstr[];
|
||||
extern const char dolatstr[];
|
||||
#define DOLATSTRLEN 6
|
||||
extern const char qchars[];
|
||||
extern const char cqchars[];
|
||||
#define qchars (cqchars + FNMATCH_IS_ENABLED)
|
||||
extern const char illnum[];
|
||||
extern const char homestr[];
|
||||
|
||||
|
||||
39
src/parser.c
39
src/parser.c
@ -796,7 +796,6 @@ xxreadtoken(void)
|
||||
c = pgetc_eatbnl();
|
||||
switch (c) {
|
||||
case ' ': case '\t':
|
||||
case PEOA:
|
||||
continue;
|
||||
case '#':
|
||||
while ((c = pgetc()) != '\n' && c != PEOF);
|
||||
@ -838,7 +837,7 @@ static int pgetc_eatbnl(void)
|
||||
int c;
|
||||
|
||||
while ((c = pgetc()) == '\\') {
|
||||
if (pgetc2() != '\n') {
|
||||
if (pgetc() != '\n') {
|
||||
pungetc();
|
||||
break;
|
||||
}
|
||||
@ -943,7 +942,7 @@ readtoken1(int firstc, char const *syntax, char *eofmark, int striptabs)
|
||||
break;
|
||||
/* backslash */
|
||||
case CBACK:
|
||||
c = pgetc2();
|
||||
c = pgetc();
|
||||
if (c == PEOF) {
|
||||
USTPUTC(CTLESC, out);
|
||||
USTPUTC('\\', out);
|
||||
@ -1048,14 +1047,10 @@ toggledq:
|
||||
break;
|
||||
case CEOF:
|
||||
goto endword; /* exit outer loop */
|
||||
case CIGN:
|
||||
break;
|
||||
default:
|
||||
if (synstack->varnest == 0)
|
||||
goto endword; /* exit outer loop */
|
||||
if (c != PEOA) {
|
||||
USTPUTC(c, out);
|
||||
}
|
||||
USTPUTC(c, out);
|
||||
}
|
||||
c = pgetc_top(synstack);
|
||||
}
|
||||
@ -1103,13 +1098,9 @@ checkend: {
|
||||
int markloc;
|
||||
char *p;
|
||||
|
||||
if (c == PEOA) {
|
||||
c = pgetc2();
|
||||
}
|
||||
if (striptabs) {
|
||||
while (c == '\t') {
|
||||
c = pgetc2();
|
||||
}
|
||||
while (c == '\t')
|
||||
c = pgetc();
|
||||
}
|
||||
|
||||
markloc = out - (char *)stackblock();
|
||||
@ -1117,7 +1108,7 @@ checkend: {
|
||||
if (c != *p)
|
||||
goto more_heredoc;
|
||||
|
||||
c = pgetc2();
|
||||
c = pgetc();
|
||||
}
|
||||
|
||||
if (c == '\n' || c == PEOF) {
|
||||
@ -1229,7 +1220,6 @@ parsesub: {
|
||||
c = pgetc_eatbnl();
|
||||
if (
|
||||
(checkkwd & CHKEOFMARK) ||
|
||||
c <= PEOA ||
|
||||
(c != '(' && c != '{' && !is_name(c) && !is_special(c))
|
||||
) {
|
||||
USTPUTC('$', out);
|
||||
@ -1262,7 +1252,8 @@ varname:
|
||||
do {
|
||||
STPUTC(c, out);
|
||||
c = pgetc_eatbnl();
|
||||
} while (!subtype && is_digit(c));
|
||||
} while ((subtype <= 0 || subtype >= VSLENGTH) &&
|
||||
is_digit(c));
|
||||
} else if (c != '}') {
|
||||
int cc = c;
|
||||
|
||||
@ -1322,6 +1313,8 @@ varname:
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
if (subtype == VSLENGTH && c != '}')
|
||||
subtype = 0;
|
||||
badsub:
|
||||
pungetc();
|
||||
}
|
||||
@ -1340,7 +1333,7 @@ badsub:
|
||||
synstack->dblquote = newsyn != BASESYNTAX;
|
||||
}
|
||||
|
||||
*((char *)stackblock() + typeloc) = subtype;
|
||||
*((char *)stackblock() + typeloc) = subtype | VSBIT;
|
||||
if (subtype != VSNORMAL) {
|
||||
synstack->varnest++;
|
||||
if (synstack->dblquote)
|
||||
@ -1397,13 +1390,9 @@ parsebackq: {
|
||||
if (pc != '\\' && pc != '`' && pc != '$'
|
||||
&& (!synstack->dblquote || pc != '"'))
|
||||
STPUTC('\\', pout);
|
||||
if (pc > PEOA) {
|
||||
break;
|
||||
}
|
||||
/* fall through */
|
||||
break;
|
||||
|
||||
case PEOF:
|
||||
case PEOA:
|
||||
synerror("EOF in backquote substitution");
|
||||
|
||||
case '\n':
|
||||
@ -1600,9 +1589,7 @@ expandstr(const char *ps)
|
||||
result = stackblock();
|
||||
|
||||
out:
|
||||
handler = savehandler;
|
||||
if (err && exception != EXERROR)
|
||||
longjmp(handler->loc, 1);
|
||||
restore_handler_expandarg(savehandler, err);
|
||||
|
||||
doprompt = saveprompt;
|
||||
unwindfiles(file_stop);
|
||||
|
||||
@ -50,6 +50,7 @@
|
||||
/* variable substitution byte (follows CTLVAR) */
|
||||
#define VSTYPE 0x0f /* type of variable substitution */
|
||||
#define VSNUL 0x10 /* colon--treat the empty string as unset */
|
||||
#define VSBIT 0x20 /* Ensure subtype is not zero */
|
||||
|
||||
/* values of VSTYPE field */
|
||||
#define VSNORMAL 0x1 /* normal variable: $var or ${var} */
|
||||
@ -62,6 +63,7 @@
|
||||
#define VSTRIMLEFT 0x8 /* ${var#pattern} */
|
||||
#define VSTRIMLEFTMAX 0x9 /* ${var##pattern} */
|
||||
#define VSLENGTH 0xa /* ${#var} */
|
||||
/* VSLENGTH must come last. */
|
||||
|
||||
/* values of checkkwd variable */
|
||||
#define CHKALIAS 0x1
|
||||
|
||||
90
src/redir.c
90
src/redir.c
@ -55,6 +55,7 @@
|
||||
#include "output.h"
|
||||
#include "memalloc.h"
|
||||
#include "error.h"
|
||||
#include "trap.h"
|
||||
|
||||
|
||||
#define EMPTY -2 /* marks an unused slot in redirtab */
|
||||
@ -180,56 +181,83 @@ redirect(union node *redir, int flags)
|
||||
}
|
||||
|
||||
|
||||
static int sh_open_fail(const char *, int, int) __attribute__((__noreturn__));
|
||||
static int sh_open_fail(const char *pathname, int flags, int e)
|
||||
{
|
||||
const char *word;
|
||||
int action;
|
||||
|
||||
word = "open";
|
||||
action = E_OPEN;
|
||||
if (flags & O_CREAT) {
|
||||
word = "create";
|
||||
action = E_CREAT;
|
||||
}
|
||||
|
||||
sh_error("cannot %s %s: %s", word, pathname, errmsg(e, action));
|
||||
}
|
||||
|
||||
|
||||
int sh_open(const char *pathname, int flags, int mayfail)
|
||||
{
|
||||
int fd;
|
||||
int e;
|
||||
|
||||
do {
|
||||
fd = open64(pathname, flags, 0666);
|
||||
e = errno;
|
||||
} while (fd < 0 && e == EINTR && !pending_sig);
|
||||
|
||||
if (mayfail || fd >= 0)
|
||||
return fd;
|
||||
|
||||
sh_open_fail(pathname, flags, e);
|
||||
}
|
||||
|
||||
|
||||
STATIC int
|
||||
openredirect(union node *redir)
|
||||
{
|
||||
struct stat64 sb;
|
||||
char *fname;
|
||||
int flags;
|
||||
int f;
|
||||
|
||||
switch (redir->nfile.type) {
|
||||
case NFROM:
|
||||
fname = redir->nfile.expfname;
|
||||
if ((f = open64(fname, O_RDONLY)) < 0)
|
||||
goto eopen;
|
||||
flags = O_RDONLY;
|
||||
do_open:
|
||||
f = sh_open(redir->nfile.expfname, flags, 0);
|
||||
break;
|
||||
case NFROMTO:
|
||||
fname = redir->nfile.expfname;
|
||||
if ((f = open64(fname, O_RDWR|O_CREAT, 0666)) < 0)
|
||||
goto ecreate;
|
||||
break;
|
||||
flags = O_RDWR|O_CREAT;
|
||||
goto do_open;
|
||||
case NTO:
|
||||
/* Take care of noclobber mode. */
|
||||
if (Cflag) {
|
||||
fname = redir->nfile.expfname;
|
||||
if (stat64(fname, &sb) < 0) {
|
||||
if ((f = open64(fname, O_WRONLY|O_CREAT|O_EXCL, 0666)) < 0)
|
||||
goto ecreate;
|
||||
} else if (!S_ISREG(sb.st_mode)) {
|
||||
if ((f = open64(fname, O_WRONLY, 0666)) < 0)
|
||||
goto ecreate;
|
||||
if (!fstat64(f, &sb) && S_ISREG(sb.st_mode)) {
|
||||
close(f);
|
||||
errno = EEXIST;
|
||||
goto ecreate;
|
||||
}
|
||||
} else {
|
||||
errno = EEXIST;
|
||||
flags = O_WRONLY|O_CREAT|O_EXCL;
|
||||
goto do_open;
|
||||
}
|
||||
|
||||
if (S_ISREG(sb.st_mode))
|
||||
goto ecreate;
|
||||
|
||||
f = sh_open(fname, O_WRONLY, 0);
|
||||
if (!fstat64(f, &sb) && S_ISREG(sb.st_mode)) {
|
||||
close(f);
|
||||
goto ecreate;
|
||||
}
|
||||
break;
|
||||
}
|
||||
/* FALLTHROUGH */
|
||||
case NCLOBBER:
|
||||
fname = redir->nfile.expfname;
|
||||
if ((f = open64(fname, O_WRONLY|O_CREAT|O_TRUNC, 0666)) < 0)
|
||||
goto ecreate;
|
||||
break;
|
||||
flags = O_WRONLY|O_CREAT|O_TRUNC;
|
||||
goto do_open;
|
||||
case NAPPEND:
|
||||
fname = redir->nfile.expfname;
|
||||
if ((f = open64(fname, O_WRONLY|O_CREAT|O_APPEND, 0666)) < 0)
|
||||
goto ecreate;
|
||||
break;
|
||||
flags = O_WRONLY|O_CREAT|O_APPEND;
|
||||
goto do_open;
|
||||
case NTOFD:
|
||||
case NFROMFD:
|
||||
f = redir->ndup.dupfd;
|
||||
@ -249,9 +277,7 @@ openredirect(union node *redir)
|
||||
|
||||
return f;
|
||||
ecreate:
|
||||
sh_error("cannot create %s: %s", fname, errmsg(errno, E_CREAT));
|
||||
eopen:
|
||||
sh_error("cannot open %s: %s", fname, errmsg(errno, E_OPEN));
|
||||
sh_open_fail(fname, O_CREAT, EEXIST);
|
||||
}
|
||||
|
||||
|
||||
@ -447,9 +473,7 @@ redirectsafe(union node *redir, int flags)
|
||||
handler = &jmploc;
|
||||
redirect(redir, flags);
|
||||
}
|
||||
handler = savehandler;
|
||||
if (err && exception != EXERROR)
|
||||
longjmp(handler->loc, 1);
|
||||
restore_handler_expandarg(savehandler, err);
|
||||
RESTOREINT(saveint);
|
||||
return err;
|
||||
}
|
||||
|
||||
@ -49,4 +49,5 @@ int savefd(int, int);
|
||||
int redirectsafe(union node *, int);
|
||||
void unwindredir(struct redirtab *stop);
|
||||
struct redirtab *pushredir(union node *redir);
|
||||
int sh_open(const char *pathname, int flags, int mayfail);
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user