mirror of
https://https.git.savannah.gnu.org/git/bash.git
synced 2026-08-12 21:20:47 +02:00
bash-4.2 remove leftover and stray files
This commit is contained in:
@@ -1,633 +0,0 @@
|
||||
# This Makefile for building libbuiltins.a is in -*- text -*- for Emacs.
|
||||
#
|
||||
# Copyright (C) 1996-2005 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
|
||||
# the Free Software Foundation; either version 2, or (at your option)
|
||||
# any later version.
|
||||
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111 USA.
|
||||
|
||||
PACKAGE = @PACKAGE_NAME@
|
||||
PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
|
||||
PACKAGE_NAME = @PACKAGE_NAME@
|
||||
PACKAGE_STRING = @PACKAGE_STRING@
|
||||
PACKAGE_VERSION = @PACKAGE_VERSION@
|
||||
|
||||
#
|
||||
SHELL = @MAKE_SHELL@
|
||||
RANLIB = @RANLIB@
|
||||
CC = @CC@
|
||||
CC_FOR_BUILD = @CC_FOR_BUILD@
|
||||
AR = @AR@
|
||||
ARFLAGS = @ARFLAGS@
|
||||
RM = rm -f
|
||||
CP = cp
|
||||
|
||||
EXEEXT = @EXEEXT@
|
||||
|
||||
prefix = @prefix@
|
||||
|
||||
srcdir = @srcdir@
|
||||
VPATH = .:@srcdir@
|
||||
topdir = @top_srcdir@
|
||||
includedir = @includedir@
|
||||
datadir = @datadir@
|
||||
localedir = $(datadir)/locale
|
||||
|
||||
# Support an alternate destination root directory for package building
|
||||
DESTDIR =
|
||||
|
||||
INSTALL = @INSTALL@
|
||||
INSTALL_DATA = @INSTALL_DATA@
|
||||
BUILD_DIR = @BUILD_DIR@
|
||||
|
||||
LIBBUILD = ${BUILD_DIR}/lib
|
||||
|
||||
PROFILE_FLAGS = @PROFILE_FLAGS@
|
||||
CFLAGS = @CFLAGS@
|
||||
CFLAGS_FOR_BUILD = @CFLAGS_FOR_BUILD@ @CROSS_COMPILE@
|
||||
CPPFLAGS = @CPPFLAGS@
|
||||
CPPFLAGS_FOR_BUILD = @CPPFLAGS_FOR_BUILD@
|
||||
LOCAL_CFLAGS = @LOCAL_CFLAGS@ ${DEBUG}
|
||||
DEFS = @DEFS@
|
||||
LOCAL_DEFS = @LOCAL_DEFS@
|
||||
|
||||
LIBS = @LIBS@
|
||||
LDFLAGS = @LDFLAGS@ $(LOCAL_LDFLAGS) $(CFLAGS)
|
||||
LDFLAGS_FOR_BUILD = $(LDFLAGS)
|
||||
LOCAL_LDFLAGS = @LOCAL_LDFLAGS@
|
||||
#LIBS_FOR_BUILD = @LIBS_FOR_BUILD@
|
||||
LIBS_FOR_BUILD = $(LIBS)
|
||||
|
||||
BASHINCDIR = ${topdir}/include
|
||||
|
||||
RL_INCLUDEDIR = @RL_INCLUDEDIR@
|
||||
|
||||
INTL_LIBSRC = ${topdir}/lib/intl
|
||||
INTL_BUILDDIR = ${LIBBUILD}/intl
|
||||
INTL_LIBDIR = ${INTL_BUILDDIR}
|
||||
INTL_INC = @INTL_INC@
|
||||
INTL_DEP = @INTL_DEP@
|
||||
LIBINTL_H = @LIBINTL_H@
|
||||
|
||||
HELPDIR = @HELPDIR@
|
||||
MKDIRS = ${topdir}/support/mkdirs
|
||||
|
||||
INCLUDES = -I. -I.. @RL_INCLUDE@ -I$(topdir) -I$(BASHINCDIR) -I$(topdir)/lib -I$(srcdir) ${INTL_INC}
|
||||
|
||||
BASE_CCFLAGS = ${PROFILE_FLAGS} $(DEFS) $(LOCAL_DEFS) $(SYSTEM_FLAGS) \
|
||||
${INCLUDES} $(LOCAL_CFLAGS)
|
||||
|
||||
CCFLAGS = $(BASE_CCFLAGS) $(CPPFLAGS) $(CFLAGS)
|
||||
|
||||
CCFLAGS_FOR_BUILD = $(BASE_CCFLAGS) $(CPPFLAGS_FOR_BUILD) $(CFLAGS_FOR_BUILD)
|
||||
|
||||
GCC_LINT_FLAGS = -Wall -Wshadow -Wpointer-arith -Wcast-qual \
|
||||
-Wcast-align -Wstrict-prototypes -Wconversion \
|
||||
-Wmissing-prototypes -Wtraditional -Wredundant-decls -pedantic
|
||||
|
||||
MKBUILTINS = mkbuiltins$(EXEEXT)
|
||||
DIRECTDEFINE = -D $(srcdir)
|
||||
HELPDIRDEFINE = @HELPDIRDEFINE@
|
||||
HELPSTRINGS = @HELPSTRINGS@
|
||||
|
||||
# xxx this is bad style
|
||||
RL_LIBSRC = $(topdir)/lib/readline
|
||||
|
||||
.SUFFIXES:
|
||||
.SUFFIXES: .def .c .o
|
||||
# How to make a .o file from a .def file.
|
||||
.def.o:
|
||||
$(RM) $@
|
||||
./$(MKBUILTINS) $(DIRECTDEFINE) $<
|
||||
$(CC) -c $(CCFLAGS) $*.c || ( $(RM) $*.c ; exit 1 )
|
||||
$(RM) $*.c
|
||||
|
||||
# How to make a .c file from a .def file.
|
||||
.def.c:
|
||||
$(RM) $@
|
||||
./$(MKBUILTINS) $(DIRECTDEFINE) $<
|
||||
|
||||
# default rule for making a .o file from a .c file
|
||||
.c.o:
|
||||
$(RM) $@
|
||||
$(CC) -c $(CCFLAGS) $<
|
||||
|
||||
DEFSRC = $(srcdir)/alias.def $(srcdir)/bind.def $(srcdir)/break.def \
|
||||
$(srcdir)/builtin.def $(srcdir)/caller.def \
|
||||
$(srcdir)/cd.def $(srcdir)/colon.def \
|
||||
$(srcdir)/command.def $(srcdir)/declare.def $(srcdir)/echo.def \
|
||||
$(srcdir)/enable.def $(srcdir)/eval.def $(srcdir)/getopts.def \
|
||||
$(srcdir)/exec.def $(srcdir)/exit.def $(srcdir)/fc.def \
|
||||
$(srcdir)/fg_bg.def $(srcdir)/hash.def $(srcdir)/help.def \
|
||||
$(srcdir)/history.def $(srcdir)/jobs.def $(srcdir)/kill.def \
|
||||
$(srcdir)/let.def $(srcdir)/read.def $(srcdir)/return.def \
|
||||
$(srcdir)/set.def $(srcdir)/setattr.def $(srcdir)/shift.def \
|
||||
$(srcdir)/source.def $(srcdir)/suspend.def $(srcdir)/test.def \
|
||||
$(srcdir)/times.def $(srcdir)/trap.def $(srcdir)/type.def \
|
||||
$(srcdir)/ulimit.def $(srcdir)/umask.def $(srcdir)/wait.def \
|
||||
$(srcdir)/reserved.def $(srcdir)/pushd.def $(srcdir)/shopt.def \
|
||||
$(srcdir)/printf.def $(srcdir)/complete.def
|
||||
|
||||
STATIC_SOURCE = common.c evalstring.c evalfile.c getopt.c bashgetopt.c \
|
||||
getopt.h
|
||||
|
||||
OFILES = builtins.o \
|
||||
alias.o bind.o break.o builtin.o caller.o cd.o colon.o command.o \
|
||||
common.o declare.o echo.o enable.o eval.o evalfile.o \
|
||||
evalstring.o exec.o \
|
||||
exit.o fc.o fg_bg.o hash.o help.o history.o jobs.o kill.o let.o \
|
||||
pushd.o read.o return.o set.o setattr.o shift.o source.o \
|
||||
suspend.o test.o times.o trap.o type.o ulimit.o umask.o \
|
||||
wait.o getopts.o shopt.o printf.o getopt.o bashgetopt.o complete.o
|
||||
|
||||
CREATED_FILES = builtext.h builtins.c psize.aux pipesize.h
|
||||
|
||||
all: $(MKBUILTINS) libbuiltins.a
|
||||
|
||||
libbuiltins.a: $(MKBUILTINS) $(OFILES) builtins.o
|
||||
$(RM) $@
|
||||
$(AR) $(ARFLAGS) $@ $(OFILES)
|
||||
-$(RANLIB) $@
|
||||
|
||||
builtext.h builtins.c: $(MKBUILTINS) $(DEFSRC)
|
||||
@-if test -f builtins.c; then mv -f builtins.c old-builtins.c; fi
|
||||
@-if test -f builtext.h; then mv -f builtext.h old-builtext.h; fi
|
||||
./$(MKBUILTINS) -externfile builtext.h -structfile builtins.c \
|
||||
-noproduction $(DIRECTDEFINE) $(HELPDIRDEFINE) $(HELPSTRINGS) $(DEFSRC)
|
||||
@-if cmp -s old-builtext.h builtext.h 2>/dev/null; then \
|
||||
mv old-builtext.h builtext.h; \
|
||||
else \
|
||||
$(RM) old-builtext.h; \
|
||||
fi
|
||||
@-if cmp -s old-builtins.c builtins.c 2>/dev/null; then \
|
||||
mv old-builtins.c builtins.c; \
|
||||
else \
|
||||
$(RM) old-builtins.c; \
|
||||
fi
|
||||
|
||||
helpdoc: $(MKBUILTINS) $(DEFSRC)
|
||||
./$(MKBUILTINS) ${HELPDIRDEFINE} -noproduction $(DIRECTDEFINE) $(DEFSRC)
|
||||
|
||||
install-help:
|
||||
@-if test -n "${HELPDIR}" && test -d helpfiles ; then \
|
||||
test -d $(DESTDIR)${HELPDIR} || ${SHELL} ${MKDIRS} $(DESTDIR)$(HELPDIR) ;\
|
||||
( for f in helpfiles/*; do \
|
||||
echo installing $$f; \
|
||||
${INSTALL_DATA} $$f $(DESTDIR)$(HELPDIR); \
|
||||
done; ) ; \
|
||||
fi
|
||||
|
||||
install: @HELPINSTALL@
|
||||
|
||||
mkbuiltins.o: ../config.h
|
||||
mkbuiltins.o: mkbuiltins.c
|
||||
$(RM) $@
|
||||
$(CC_FOR_BUILD) -c $(CCFLAGS_FOR_BUILD) $<
|
||||
|
||||
mkbuiltins$(EXEEXT): mkbuiltins.o
|
||||
$(CC_FOR_BUILD) $(LDFLAGS_FOR_BUILD) -o $(MKBUILTINS) mkbuiltins.o $(LIBS_FOR_BUILD)
|
||||
|
||||
# rules for deficient makes, like SunOS
|
||||
mkbuiltins.o: mkbuiltins.c
|
||||
builtins.o: builtins.c
|
||||
common.o: common.c
|
||||
bashgetopt.o: bashgetopt.c
|
||||
getopt.o: getopt.c
|
||||
evalstring.o: evalstring.c
|
||||
evalfile.o: evalfile.c
|
||||
|
||||
ulimit.o: pipesize.h
|
||||
|
||||
pipesize.h: psize.aux
|
||||
$(SHELL) $(srcdir)/psize.sh > $@
|
||||
|
||||
psize.aux: psize.c
|
||||
$(CC_FOR_BUILD) $(CCFLAGS_FOR_BUILD) -o $@ $(srcdir)/psize.c
|
||||
|
||||
documentation: builtins.texi
|
||||
|
||||
builtins.texi: $(MKBUILTINS)
|
||||
./$(MKBUILTINS) -documentonly $(DEFSRC)
|
||||
|
||||
clean:
|
||||
$(RM) $(OFILES) $(CREATED_FILES) $(MKBUILTINS) mkbuiltins.o libbuiltins.a
|
||||
-test -d helpfiles && $(RM) -r helpfiles
|
||||
|
||||
mostlyclean:
|
||||
$(RM) $(OFILES) libbuiltins.a
|
||||
|
||||
distclean maintainer-clean: clean
|
||||
$(RM) Makefile
|
||||
|
||||
$(OFILES): $(MKBUILTINS) ../config.h
|
||||
|
||||
../version.h: ../config.h ../Makefile Makefile
|
||||
-( cd ${BUILD_DIR} && ${MAKE} ${MFLAGS} version.h )
|
||||
|
||||
# maintainer special - for now
|
||||
po: builtins.c
|
||||
xgettext -L C -o $(topdir)/po/builtins.pot --keyword='N_' builtins.c 2>/dev/null
|
||||
|
||||
${LIBINTL_H}: ${INTL_DEP}
|
||||
|
||||
${INTL_LIBRARY}: ../config.h ${INTL_BUILDDIR}/Makefile
|
||||
@echo making $@ in ${INTL_LIBDIR}
|
||||
@(cd ${INTL_LIBDIR} && \
|
||||
$(MAKE) $(MFLAGS) all) || ex
|
||||
# dependencies
|
||||
|
||||
alias.o: alias.def
|
||||
bind.o: bind.def
|
||||
break.o: break.def
|
||||
builtin.o: builtin.def
|
||||
caller.o: caller.def
|
||||
cd.o: cd.def
|
||||
colon.o: colon.def
|
||||
command.o: command.def
|
||||
declare.o: declare.def
|
||||
echo.o: echo.def
|
||||
enable.o: enable.def
|
||||
eval.o: eval.def
|
||||
exec.o: exec.def
|
||||
exit.o: exit.def
|
||||
fc.o: fc.def
|
||||
fg_bg.o: fg_bg.def
|
||||
hash.o: hash.def
|
||||
help.o: help.def
|
||||
history.o: history.def
|
||||
jobs.o: jobs.def
|
||||
kill.o: kill.def
|
||||
let.o: let.def
|
||||
printf.o: printf.def
|
||||
pushd.o: pushd.def
|
||||
read.o: read.def
|
||||
return.o: return.def
|
||||
set.o: set.def
|
||||
setattr.o: setattr.def
|
||||
shift.o: shift.def
|
||||
shopt.o: shopt.def
|
||||
source.o: source.def
|
||||
suspend.o: suspend.def
|
||||
test.o: test.def
|
||||
times.o: times.def
|
||||
trap.o: trap.def
|
||||
type.o: type.def
|
||||
ulimit.o: ulimit.def
|
||||
umask.o: umask.def
|
||||
wait.o: wait.def
|
||||
getopts.o: getopts.def
|
||||
reserved.o: reserved.def
|
||||
complete.o: complete.def
|
||||
|
||||
# C files
|
||||
bashgetopt.o: ../config.h $(topdir)/bashansi.h $(BASHINCDIR)/ansi_stdlib.h
|
||||
bashgetopt.o: $(topdir)/shell.h $(topdir)/syntax.h $(topdir)/bashjmp.h
|
||||
bashgetopt.o: $(topdir)/command.h $(topdir)/general.h $(topdir)/xmalloc.h $(topdir)/error.h
|
||||
bashgetopt.o: $(topdir)/variables.h $(topdir)/conftypes.h $(topdir)/quit.h $(BASHINCDIR)/maxpath.h
|
||||
bashgetopt.o: $(topdir)/unwind_prot.h $(topdir)/dispose_cmd.h
|
||||
bashgetopt.o: $(topdir)/make_cmd.h $(topdir)/subst.h $(topdir)/sig.h
|
||||
bashgetopt.o: ../pathnames.h $(topdir)/externs.h $(srcdir)/common.h
|
||||
bashgetopt.o: $(BASHINCDIR)/chartypes.h
|
||||
common.o: $(topdir)/bashtypes.h $(BASHINCDIR)/posixstat.h $(topdir)/bashansi.h $(BASHINCDIR)/ansi_stdlib.h
|
||||
common.o: $(topdir)/shell.h $(topdir)/syntax.h ../config.h $(topdir)/bashjmp.h $(BASHINCDIR)/posixjmp.h
|
||||
common.o: $(topdir)/sig.h $(topdir)/command.h
|
||||
common.o: $(topdir)/general.h $(topdir)/xmalloc.h $(BASHINCDIR)/stdc.h $(BASHINCDIR)/memalloc.h
|
||||
common.o: $(topdir)/variables.h $(topdir)/conftypes.h $(topdir)/input.h
|
||||
common.o: $(topdir)/siglist.h $(topdir)/bashhist.h $(topdir)/quit.h
|
||||
common.o: $(topdir)/unwind_prot.h $(BASHINCDIR)/maxpath.h $(topdir)/jobs.h
|
||||
common.o: $(topdir)/builtins.h $(topdir)/dispose_cmd.h $(topdir)/make_cmd.h
|
||||
common.o: $(topdir)/subst.h $(topdir)/execute_cmd.h $(topdir)/error.h
|
||||
common.o: $(topdir)/externs.h ../pathnames.h ./builtext.h
|
||||
common.o: $(BASHINCDIR)/chartypes.h
|
||||
evalfile.o: $(topdir)/bashtypes.h $(BASHINCDIR)/posixstat.h ${BASHINCDIR}/filecntl.h
|
||||
evalfile.o: $(topdir)/bashansi.h $(BASHINCDIR)/ansi_stdlib.h
|
||||
evalfile.o: $(topdir)/shell.h $(topdir)/syntax.h ../config.h $(topdir)/bashjmp.h
|
||||
evalfile.o: $(topdir)/command.h $(topdir)/general.h $(topdir)/xmalloc.h $(topdir)/error.h
|
||||
evalfile.o: $(topdir)/variables.h $(topdir)/conftypes.h $(topdir)/quit.h $(BASHINCDIR)/maxpath.h
|
||||
evalfile.o: $(topdir)/unwind_prot.h $(topdir)/dispose_cmd.h
|
||||
evalfile.o: $(topdir)/make_cmd.h $(topdir)/subst.h $(topdir)/sig.h
|
||||
evalfile.o: ../pathnames.h $(topdir)/externs.h
|
||||
evalfile.o: $(topdir)/jobs.h $(topdir)/builtins.h $(topdir)/flags.h
|
||||
evalfile.o: $(topdir)/input.h $(topdir)/execute_cmd.h
|
||||
evalfile.o: $(topdir)/bashhist.h $(srcdir)/common.h
|
||||
evalstring.o: ../config.h $(topdir)/bashansi.h $(BASHINCDIR)/ansi_stdlib.h
|
||||
evalstring.o: $(topdir)/shell.h $(topdir)/syntax.h $(topdir)/bashjmp.h $(BASHINCDIR)/posixjmp.h
|
||||
evalstring.o: $(topdir)/sig.h $(topdir)/command.h $(topdir)/siglist.h
|
||||
evalstring.o: $(BASHINCDIR)/memalloc.h $(topdir)/variables.h $(topdir)/conftypes.h $(topdir)/input.h
|
||||
evalstring.o: $(topdir)/quit.h $(topdir)/unwind_prot.h
|
||||
evalstring.o: $(BASHINCDIR)/maxpath.h $(topdir)/jobs.h $(topdir)/builtins.h
|
||||
evalstring.o: $(topdir)/dispose_cmd.h $(topdir)/make_cmd.h $(topdir)/subst.h
|
||||
evalstring.o: $(topdir)/externs.h $(topdir)/jobs.h $(topdir)/builtins.h
|
||||
evalstring.o: $(topdir)/flags.h $(topdir)/input.h $(topdir)/execute_cmd.h
|
||||
evalstring.o: $(topdir)/bashhist.h $(srcdir)/common.h
|
||||
evalstring.o: $(topdir)/trap.h $(topdir)/redir.h
|
||||
getopt.o: ../config.h $(BASHINCDIR)/memalloc.h
|
||||
getopt.o: $(topdir)/shell.h $(topdir)/syntax.h $(topdir)/bashjmp.h $(topdir)/command.h
|
||||
getopt.o: $(topdir)/general.h $(topdir)/xmalloc.h $(topdir)/error.h $(topdir)/variables.h $(topdir)/conftypes.h
|
||||
getopt.o: $(topdir)/quit.h $(BASHINCDIR)/maxpath.h $(topdir)/unwind_prot.h
|
||||
getopt.o: $(topdir)/dispose_cmd.h $(topdir)/make_cmd.h $(topdir)/subst.h
|
||||
getopt.o: $(topdir)/sig.h ../pathnames.h $(topdir)/externs.h
|
||||
getopt.o: $(srcdir)/getopt.h
|
||||
mkbuiltins.o: ../config.h $(topdir)/bashtypes.h $(BASHINCDIR)/posixstat.h
|
||||
mkbuiltins.o: ${BASHINCDIR}/filecntl.h
|
||||
mkbuiltins.o: $(topdir)/bashansi.h $(BASHINCDIR)/ansi_stdlib.h
|
||||
|
||||
# def files
|
||||
alias.o: $(topdir)/command.h ../config.h $(BASHINCDIR)/memalloc.h
|
||||
alias.o: $(topdir)/error.h $(topdir)/general.h $(topdir)/xmalloc.h $(BASHINCDIR)/maxpath.h
|
||||
alias.o: $(topdir)/quit.h $(topdir)/dispose_cmd.h $(topdir)/make_cmd.h
|
||||
alias.o: $(topdir)/subst.h $(topdir)/externs.h $(srcdir)/common.h
|
||||
alias.o: $(topdir)/shell.h $(topdir)/syntax.h $(topdir)/unwind_prot.h $(topdir)/variables.h $(topdir)/conftypes.h
|
||||
bind.o: $(topdir)/command.h ../config.h $(BASHINCDIR)/memalloc.h $(topdir)/error.h
|
||||
bind.o: $(topdir)/quit.h $(topdir)/dispose_cmd.h $(topdir)/make_cmd.h
|
||||
bind.o: $(topdir)/subst.h $(topdir)/externs.h $(srcdir)/bashgetopt.h
|
||||
bind.o: $(topdir)/general.h $(topdir)/xmalloc.h $(BASHINCDIR)/maxpath.h $(topdir)/bashline.h
|
||||
bind.o: $(topdir)/shell.h $(topdir)/syntax.h $(topdir)/unwind_prot.h $(topdir)/variables.h $(topdir)/conftypes.h
|
||||
break.o: $(topdir)/command.h ../config.h $(BASHINCDIR)/memalloc.h
|
||||
break.o: $(topdir)/error.h $(topdir)/general.h $(topdir)/xmalloc.h
|
||||
break.o: $(topdir)/quit.h $(topdir)/dispose_cmd.h $(topdir)/make_cmd.h
|
||||
break.o: $(topdir)/subst.h $(topdir)/externs.h $(BASHINCDIR)/maxpath.h
|
||||
break.o: $(topdir)/shell.h $(topdir)/syntax.h $(topdir)/unwind_prot.h $(topdir)/variables.h $(topdir)/conftypes.h
|
||||
builtin.o: $(topdir)/command.h ../config.h $(BASHINCDIR)/memalloc.h
|
||||
builtin.o: $(topdir)/error.h $(topdir)/general.h $(topdir)/xmalloc.h $(topdir)/externs.h
|
||||
builtin.o: $(topdir)/quit.h $(srcdir)/common.h $(BASHINCDIR)/maxpath.h
|
||||
builtin.o: $(topdir)/dispose_cmd.h $(topdir)/make_cmd.h $(topdir)/subst.h
|
||||
builtin.o: $(topdir)/shell.h $(topdir)/syntax.h $(topdir)/unwind_prot.h $(topdir)/variables.h $(topdir)/conftypes.h
|
||||
builtin.o: $(srcdir)/bashgetopt.h
|
||||
caller.o: $(topdir)/command.h ../config.h $(BASHINCDIR)/memalloc.h $(topdir)/error.h
|
||||
caller.o: $(topdir)/general.h $(topdir)/xmalloc.h $(topdir)/quit.h $(topdir)/dispose_cmd.h
|
||||
caller.o: $(topdir)/make_cmd.h $(topdir)/subst.h $(topdir)/externs.h
|
||||
caller.o: $(topdir)/shell.h $(topdir)/syntax.h $(topdir)/unwind_prot.h $(topdir)/variables.h $(topdir)/conftypes.h
|
||||
caller.o: $(srcdir)/common.h $(BASHINCDIR)/maxpath.h ./builtext.h
|
||||
caller.o: ${BASHINCDIR}/chartypes.h $(topdir)/bashtypes.h
|
||||
cd.o: $(topdir)/command.h ../config.h $(BASHINCDIR)/memalloc.h $(topdir)/error.h
|
||||
cd.o: $(topdir)/general.h $(topdir)/xmalloc.h $(topdir)/quit.h $(topdir)/dispose_cmd.h
|
||||
cd.o: $(topdir)/make_cmd.h $(topdir)/subst.h $(topdir)/externs.h
|
||||
cd.o: $(topdir)/shell.h $(topdir)/syntax.h $(topdir)/unwind_prot.h $(topdir)/variables.h $(topdir)/conftypes.h
|
||||
cd.o: $(srcdir)/common.h $(BASHINCDIR)/maxpath.h
|
||||
command.o: $(topdir)/command.h ../config.h $(BASHINCDIR)/memalloc.h
|
||||
command.o: $(topdir)/error.h $(topdir)/general.h $(topdir)/xmalloc.h $(topdir)/externs.h
|
||||
command.o: $(topdir)/quit.h $(srcdir)/bashgetopt.h $(BASHINCDIR)/maxpath.h
|
||||
command.o: $(topdir)/dispose_cmd.h $(topdir)/make_cmd.h $(topdir)/subst.h
|
||||
command.o: $(topdir)/shell.h $(topdir)/syntax.h $(topdir)/unwind_prot.h $(topdir)/variables.h $(topdir)/conftypes.h
|
||||
declare.o: $(topdir)/command.h ../config.h $(BASHINCDIR)/memalloc.h
|
||||
declare.o: $(topdir)/error.h $(topdir)/general.h $(topdir)/xmalloc.h
|
||||
declare.o: $(topdir)/quit.h $(topdir)/dispose_cmd.h $(topdir)/make_cmd.h
|
||||
declare.o: $(topdir)/subst.h $(topdir)/externs.h $(BASHINCDIR)/maxpath.h
|
||||
declare.o: $(topdir)/shell.h $(topdir)/syntax.h $(topdir)/unwind_prot.h $(topdir)/variables.h $(topdir)/conftypes.h
|
||||
declare.o: $(topdir)/arrayfunc.h $(srcdir)/bashgetopt.h
|
||||
declare.o: ./builtext.h
|
||||
echo.o: $(topdir)/command.h ../config.h $(BASHINCDIR)/memalloc.h $(topdir)/error.h
|
||||
echo.o: $(topdir)/general.h $(topdir)/xmalloc.h $(topdir)/subst.h $(topdir)/externs.h
|
||||
echo.o: $(topdir)/quit.h $(topdir)/dispose_cmd.h $(topdir)/make_cmd.h
|
||||
echo.o: $(topdir)/shell.h $(topdir)/syntax.h $(topdir)/unwind_prot.h $(topdir)/variables.h $(topdir)/conftypes.h
|
||||
echo.o: $(BASHINCDIR)/maxpath.h
|
||||
enable.o: $(topdir)/command.h ../config.h $(BASHINCDIR)/memalloc.h
|
||||
enable.o: $(topdir)/error.h $(topdir)/general.h $(topdir)/xmalloc.h
|
||||
enable.o: $(topdir)/quit.h $(topdir)/dispose_cmd.h $(topdir)/make_cmd.h
|
||||
enable.o: $(topdir)/subst.h $(topdir)/externs.h
|
||||
enable.o: $(topdir)/shell.h $(topdir)/syntax.h $(topdir)/unwind_prot.h $(topdir)/variables.h $(topdir)/conftypes.h
|
||||
enable.o: $(BASHINCDIR)/maxpath.h
|
||||
enable.o: $(topdir)/pcomplete.h
|
||||
eval.o: $(topdir)/command.h ../config.h $(BASHINCDIR)/memalloc.h
|
||||
eval.o: $(topdir)/error.h $(topdir)/general.h $(topdir)/xmalloc.h
|
||||
eval.o: $(topdir)/quit.h $(topdir)/dispose_cmd.h $(topdir)/make_cmd.h
|
||||
eval.o: $(topdir)/subst.h $(topdir)/externs.h
|
||||
eval.o: $(topdir)/shell.h $(topdir)/syntax.h $(topdir)/unwind_prot.h $(topdir)/variables.h $(topdir)/conftypes.h
|
||||
eval.o: $(BASHINCDIR)/maxpath.h
|
||||
exec.o: $(topdir)/bashtypes.h
|
||||
exec.o: $(topdir)/command.h ../config.h $(BASHINCDIR)/memalloc.h
|
||||
exec.o: $(topdir)/error.h $(topdir)/general.h $(topdir)/xmalloc.h
|
||||
exec.o: $(topdir)/quit.h $(topdir)/dispose_cmd.h $(topdir)/make_cmd.h
|
||||
exec.o: $(topdir)/subst.h $(topdir)/externs.h $(topdir)/flags.h
|
||||
exec.o: $(topdir)/shell.h $(topdir)/syntax.h $(topdir)/unwind_prot.h $(topdir)/variables.h $(topdir)/conftypes.h
|
||||
exec.o: $(srcdir)/common.h $(topdir)/execute_cmd.h $(BASHINCDIR)/maxpath.h
|
||||
exec.o: $(topdir)/findcmd.h $(topdir)/jobs.h
|
||||
exit.o: $(topdir)/bashtypes.h
|
||||
exit.o: $(topdir)/command.h ../config.h $(BASHINCDIR)/memalloc.h
|
||||
exit.o: $(topdir)/error.h $(topdir)/general.h $(topdir)/xmalloc.h
|
||||
exit.o: $(topdir)/quit.h $(topdir)/dispose_cmd.h $(topdir)/make_cmd.h
|
||||
exit.o: $(topdir)/subst.h $(topdir)/externs.h $(topdir)/jobs.h
|
||||
exit.o: $(topdir)/shell.h $(topdir)/syntax.h $(topdir)/unwind_prot.h $(topdir)/variables.h $(topdir)/conftypes.h
|
||||
exit.o: $(BASHINCDIR)/maxpath.h ./builtext.h
|
||||
fc.o: $(topdir)/bashtypes.h $(BASHINCDIR)/posixstat.h
|
||||
fc.o: $(topdir)/builtins.h $(topdir)/command.h $(srcdir)/bashgetopt.h
|
||||
fc.o: $(topdir)/bashhist.h
|
||||
fc.o: $(topdir)/command.h ../config.h $(BASHINCDIR)/memalloc.h $(topdir)/error.h
|
||||
fc.o: $(topdir)/general.h $(topdir)/xmalloc.h $(BASHINCDIR)/maxpath.h
|
||||
fc.o: $(topdir)/quit.h $(topdir)/dispose_cmd.h $(topdir)/make_cmd.h
|
||||
fc.o: $(topdir)/subst.h $(topdir)/externs.h $(topdir)/shell.h $(topdir)/syntax.h
|
||||
fc.o: $(topdir)/flags.h $(topdir)/unwind_prot.h $(topdir)/variables.h $(topdir)/conftypes.h
|
||||
fc.o: $(topdir)/bashansi.h $(BASHINCDIR)/ansi_stdlib.h $(BASHINCDIR)/chartypes.h
|
||||
fg_bg.o: $(topdir)/bashtypes.h $(srcdir)/bashgetopt.h
|
||||
fg_bg.o: $(topdir)/command.h ../config.h $(BASHINCDIR)/memalloc.h
|
||||
fg_bg.o: $(topdir)/error.h $(topdir)/general.h $(topdir)/xmalloc.h
|
||||
fg_bg.o: $(topdir)/quit.h $(topdir)/dispose_cmd.h $(topdir)/make_cmd.h
|
||||
fg_bg.o: $(topdir)/subst.h $(topdir)/externs.h $(BASHINCDIR)/maxpath.h
|
||||
fg_bg.o: $(topdir)/shell.h $(topdir)/syntax.h $(topdir)/unwind_prot.h $(topdir)/variables.h $(topdir)/conftypes.h
|
||||
fg_bg.o: $(topdir)/jobs.h
|
||||
getopts.o: $(topdir)/command.h ../config.h $(BASHINCDIR)/memalloc.h
|
||||
getopts.o: $(topdir)/error.h $(topdir)/general.h $(topdir)/xmalloc.h
|
||||
getopts.o: $(topdir)/quit.h $(topdir)/dispose_cmd.h $(topdir)/make_cmd.h
|
||||
getopts.o: $(topdir)/subst.h $(topdir)/externs.h $(BASHINCDIR)/maxpath.h
|
||||
getopts.o: $(topdir)/shell.h $(topdir)/syntax.h $(topdir)/unwind_prot.h $(topdir)/variables.h $(topdir)/conftypes.h
|
||||
hash.o: $(topdir)/builtins.h $(topdir)/command.h $(topdir)/quit.h
|
||||
hash.o: $(topdir)/findcmd.h $(topdir)/hashlib.h
|
||||
hash.o: $(topdir)/command.h ../config.h $(BASHINCDIR)/memalloc.h
|
||||
hash.o: $(topdir)/error.h $(topdir)/general.h $(topdir)/xmalloc.h
|
||||
hash.o: $(topdir)/shell.h $(topdir)/syntax.h $(topdir)/unwind_prot.h $(topdir)/variables.h $(topdir)/conftypes.h
|
||||
hash.o: $(srcdir)/common.h $(BASHINCDIR)/maxpath.h
|
||||
help.o: $(topdir)/command.h ../config.h $(BASHINCDIR)/memalloc.h
|
||||
help.o: $(topdir)/error.h $(topdir)/general.h $(topdir)/xmalloc.h
|
||||
help.o: $(topdir)/quit.h $(topdir)/dispose_cmd.h $(topdir)/make_cmd.h
|
||||
help.o: $(topdir)/subst.h $(topdir)/externs.h $(BASHINCDIR)/maxpath.h
|
||||
help.o: $(topdir)/shell.h $(topdir)/syntax.h $(topdir)/unwind_prot.h $(topdir)/variables.h $(topdir)/conftypes.h
|
||||
help.o: ${srcdir}/common.h
|
||||
history.o: $(topdir)/bashtypes.h
|
||||
history.o: $(topdir)/command.h ../config.h $(BASHINCDIR)/memalloc.h
|
||||
history.o: $(topdir)/error.h $(topdir)/general.h $(topdir)/xmalloc.h
|
||||
history.o: $(topdir)/quit.h $(topdir)/dispose_cmd.h $(topdir)/make_cmd.h
|
||||
history.o: $(topdir)/subst.h $(topdir)/externs.h
|
||||
history.o: ${BASHINCDIR}/filecntl.h $(topdir)/shell.h $(topdir)/syntax.h $(topdir)/unwind_prot.h
|
||||
history.o: $(topdir)/variables.h $(topdir)/conftypes.h $(topdir)/bashhist.h $(BASHINCDIR)/maxpath.h
|
||||
inlib.o: $(topdir)/command.h ../config.h $(BASHINCDIR)/memalloc.h
|
||||
inlib.o: $(topdir)/error.h $(topdir)/general.h $(topdir)/xmalloc.h
|
||||
inlib.o: $(topdir)/shell.h $(topdir)/syntax.h $(topdir)/unwind_prot.h $(topdir)/variables.h $(topdir)/conftypes.h
|
||||
inlib.o: $(BASHINCDIR)/maxpath.h $(topdir)/subst.h $(topdir)/externs.h
|
||||
inlib.o: $(topdir)/quit.h $(topdir)/dispose_cmd.h $(topdir)/make_cmd.h
|
||||
jobs.o: $(topdir)/command.h ../config.h $(BASHINCDIR)/memalloc.h $(topdir)/error.h
|
||||
jobs.o: $(topdir)/general.h $(topdir)/xmalloc.h $(topdir)/quit.h $(srcdir)/bashgetopt.h
|
||||
jobs.o: $(BASHINCDIR)/maxpath.h $(topdir)/externs.h $(topdir)/jobs.h
|
||||
jobs.o: $(topdir)/dispose_cmd.h $(topdir)/make_cmd.h $(topdir)/subst.h
|
||||
jobs.o: $(topdir)/shell.h $(topdir)/syntax.h $(topdir)/unwind_prot.h $(topdir)/variables.h $(topdir)/conftypes.h
|
||||
kill.o: $(topdir)/command.h ../config.h $(BASHINCDIR)/memalloc.h $(topdir)/error.h
|
||||
kill.o: $(topdir)/general.h $(topdir)/xmalloc.h $(topdir)/subst.h $(topdir)/externs.h
|
||||
kill.o: $(topdir)/quit.h $(topdir)/dispose_cmd.h $(topdir)/make_cmd.h
|
||||
kill.o: $(topdir)/shell.h $(topdir)/syntax.h $(topdir)/trap.h $(topdir)/unwind_prot.h
|
||||
kill.o: $(topdir)/variables.h $(topdir)/conftypes.h $(BASHINCDIR)/maxpath.h
|
||||
kill.o: $(topdir)/jobs.h
|
||||
let.o: $(topdir)/command.h ../config.h $(BASHINCDIR)/memalloc.h
|
||||
let.o: $(topdir)/error.h $(topdir)/general.h $(topdir)/xmalloc.h
|
||||
let.o: $(topdir)/quit.h $(topdir)/dispose_cmd.h $(topdir)/make_cmd.h
|
||||
let.o: $(topdir)/subst.h $(topdir)/externs.h $(BASHINCDIR)/maxpath.h
|
||||
let.o: $(topdir)/shell.h $(topdir)/syntax.h $(topdir)/unwind_prot.h $(topdir)/variables.h $(topdir)/conftypes.h
|
||||
printf.o: ../config.h $(BASHINCDIR)/memalloc.h $(topdir)/bashjmp.h
|
||||
printf.o: $(topdir)/command.h $(topdir)/error.h $(topdir)/general.h $(topdir)/xmalloc.h
|
||||
printf.o: $(topdir)/quit.h $(topdir)/dispose_cmd.h $(topdir)/make_cmd.h
|
||||
printf.o: $(topdir)/subst.h $(topdir)/externs.h $(topdir)/sig.h
|
||||
printf.o: ../pathnames.h $(topdir)/shell.h $(topdir)/syntax.h $(topdir)/unwind_prot.h
|
||||
printf.o: $(topdir)/variables.h $(topdir)/conftypes.h $(BASHINCDIR)/stdc.h $(srcdir)/bashgetopt.h
|
||||
printf.o: $(topdir)/bashtypes.h ${srcdir}/common.h $(BASHINCDIR)/chartypes.h
|
||||
pushd.o: $(topdir)/command.h ../config.h $(BASHINCDIR)/memalloc.h
|
||||
pushd.o: $(topdir)/error.h $(topdir)/general.h $(topdir)/xmalloc.h
|
||||
pushd.o: $(topdir)/quit.h $(topdir)/dispose_cmd.h $(topdir)/make_cmd.h
|
||||
pushd.o: $(topdir)/subst.h $(topdir)/externs.h
|
||||
pushd.o: $(topdir)/shell.h $(topdir)/syntax.h $(topdir)/unwind_prot.h $(topdir)/variables.h $(topdir)/conftypes.h
|
||||
pushd.o: $(BASHINCDIR)/maxpath.h $(srcdir)/common.h ./builtext.h
|
||||
read.o: $(topdir)/command.h ../config.h $(BASHINCDIR)/memalloc.h
|
||||
read.o: $(topdir)/error.h $(topdir)/general.h $(topdir)/xmalloc.h
|
||||
read.o: $(topdir)/quit.h $(topdir)/dispose_cmd.h $(topdir)/make_cmd.h
|
||||
read.o: $(topdir)/subst.h $(topdir)/externs.h $(BASHINCDIR)/maxpath.h
|
||||
read.o: $(topdir)/shell.h $(topdir)/syntax.h $(topdir)/unwind_prot.h $(topdir)/variables.h $(topdir)/conftypes.h
|
||||
read.o: $(BASHINCDIR)/shtty.h
|
||||
read.o: $(topdir)/arrayfunc.h
|
||||
return.o: $(topdir)/command.h ../config.h $(BASHINCDIR)/memalloc.h
|
||||
return.o: $(topdir)/error.h $(topdir)/general.h $(topdir)/xmalloc.h
|
||||
return.o: $(topdir)/quit.h $(topdir)/dispose_cmd.h $(topdir)/make_cmd.h
|
||||
return.o: $(topdir)/subst.h $(topdir)/externs.h $(BASHINCDIR)/maxpath.h
|
||||
return.o: $(topdir)/shell.h $(topdir)/syntax.h $(topdir)/unwind_prot.h $(topdir)/variables.h $(topdir)/conftypes.h
|
||||
set.o: $(topdir)/command.h ../config.h $(BASHINCDIR)/memalloc.h
|
||||
set.o: $(topdir)/general.h $(topdir)/xmalloc.h $(topdir)/subst.h $(topdir)/externs.h
|
||||
set.o: $(topdir)/quit.h $(topdir)/dispose_cmd.h $(topdir)/make_cmd.h
|
||||
set.o: $(topdir)/shell.h $(topdir)/syntax.h $(topdir)/unwind_prot.h $(topdir)/variables.h $(topdir)/conftypes.h
|
||||
set.o: $(BASHINCDIR)/maxpath.h $(topdir)/error.h
|
||||
set.o: $(topdir)/arrayfunc.h
|
||||
setattr.o: $(topdir)/command.h ../config.h $(BASHINCDIR)/memalloc.h
|
||||
setattr.o: $(topdir)/error.h $(topdir)/general.h $(topdir)/xmalloc.h $(BASHINCDIR)/maxpath.h
|
||||
setattr.o: $(topdir)/quit.h $(srcdir)/common.h $(srcdir)/bashgetopt.h
|
||||
setattr.o: $(topdir)/dispose_cmd.h $(topdir)/make_cmd.h $(topdir)/subst.h
|
||||
setattr.o: $(topdir)/externs.h
|
||||
setattr.o: $(topdir)/shell.h $(topdir)/syntax.h $(topdir)/unwind_prot.h $(topdir)/variables.h $(topdir)/conftypes.h
|
||||
setattr.o: $(topdir)/arrayfunc.h
|
||||
shift.o: $(topdir)/command.h ../config.h $(BASHINCDIR)/memalloc.h
|
||||
shift.o: $(topdir)/error.h $(topdir)/general.h $(topdir)/xmalloc.h
|
||||
shift.o: $(topdir)/quit.h $(topdir)/dispose_cmd.h $(topdir)/make_cmd.h
|
||||
shift.o: $(topdir)/subst.h $(topdir)/externs.h $(BASHINCDIR)/maxpath.h
|
||||
shift.o: $(topdir)/shell.h $(topdir)/syntax.h $(topdir)/unwind_prot.h $(topdir)/variables.h $(topdir)/conftypes.h
|
||||
source.o: $(topdir)/command.h ../config.h $(BASHINCDIR)/memalloc.h
|
||||
source.o: $(topdir)/error.h $(topdir)/general.h $(topdir)/xmalloc.h $(topdir)/findcmd.h
|
||||
source.o: $(topdir)/quit.h $(topdir)/dispose_cmd.h $(topdir)/make_cmd.h
|
||||
source.o: $(topdir)/subst.h $(topdir)/externs.h $(BASHINCDIR)/maxpath.h
|
||||
source.o: $(topdir)/shell.h $(topdir)/syntax.h $(topdir)/unwind_prot.h $(topdir)/variables.h $(topdir)/conftypes.h
|
||||
source.o: $(srcdir)/bashgetopt.h $(topdir)/flags.h $(topdir)/trap.h
|
||||
suspend.o: $(topdir)/command.h ../config.h $(BASHINCDIR)/memalloc.h
|
||||
suspend.o: $(topdir)/error.h $(topdir)/general.h $(topdir)/xmalloc.h
|
||||
suspend.o: $(topdir)/quit.h $(topdir)/dispose_cmd.h $(topdir)/make_cmd.h
|
||||
suspend.o: $(topdir)/subst.h $(topdir)/externs.h $(BASHINCDIR)/maxpath.h
|
||||
suspend.o: $(topdir)/shell.h $(topdir)/syntax.h $(topdir)/unwind_prot.h $(topdir)/variables.h $(topdir)/conftypes.h
|
||||
suspend.o: $(topdir)/jobs.h
|
||||
test.o: $(topdir)/command.h ../config.h $(BASHINCDIR)/memalloc.h
|
||||
test.o: $(topdir)/error.h $(topdir)/general.h $(topdir)/xmalloc.h
|
||||
test.o: $(topdir)/quit.h $(topdir)/dispose_cmd.h $(topdir)/make_cmd.h
|
||||
test.o: $(topdir)/subst.h $(topdir)/externs.h $(BASHINCDIR)/maxpath.h
|
||||
test.o: $(topdir)/shell.h $(topdir)/syntax.h $(topdir)/unwind_prot.h $(topdir)/variables.h $(topdir)/conftypes.h
|
||||
test.o: $(topdir)/test.h
|
||||
times.o: $(topdir)/command.h ../config.h $(BASHINCDIR)/memalloc.h
|
||||
times.o: $(topdir)/error.h $(topdir)/general.h $(topdir)/xmalloc.h
|
||||
times.o: $(topdir)/quit.h $(topdir)/dispose_cmd.h $(topdir)/make_cmd.h
|
||||
times.o: $(topdir)/subst.h $(topdir)/externs.h $(BASHINCDIR)/maxpath.h
|
||||
times.o: $(topdir)/shell.h $(topdir)/syntax.h $(topdir)/unwind_prot.h $(topdir)/variables.h $(topdir)/conftypes.h
|
||||
times.o: $(BASHINCDIR)/posixtime.h
|
||||
trap.o: $(topdir)/command.h ../config.h $(BASHINCDIR)/memalloc.h
|
||||
trap.o: $(topdir)/error.h $(topdir)/general.h $(topdir)/xmalloc.h $(topdir)/externs.h
|
||||
trap.o: $(topdir)/quit.h $(srcdir)/common.h $(BASHINCDIR)/maxpath.h
|
||||
trap.o: $(topdir)/dispose_cmd.h $(topdir)/make_cmd.h $(topdir)/subst.h
|
||||
trap.o: $(topdir)/shell.h $(topdir)/syntax.h $(topdir)/unwind_prot.h $(topdir)/variables.h $(topdir)/conftypes.h
|
||||
trap.o: $(topdir)/findcmd.h
|
||||
type.o: $(topdir)/command.h ../config.h $(BASHINCDIR)/memalloc.h
|
||||
type.o: $(topdir)/error.h $(topdir)/general.h $(topdir)/xmalloc.h
|
||||
type.o: $(topdir)/quit.h $(srcdir)/common.h $(BASHINCDIR)/maxpath.h
|
||||
type.o: $(topdir)/dispose_cmd.h $(topdir)/make_cmd.h $(topdir)/subst.h
|
||||
type.o: $(topdir)/externs.h $(topdir)/hashcmd.h
|
||||
type.o: $(topdir)/shell.h $(topdir)/syntax.h $(topdir)/unwind_prot.h $(topdir)/variables.h $(topdir)/conftypes.h
|
||||
ulimit.o: $(topdir)/command.h ../config.h $(BASHINCDIR)/memalloc.h
|
||||
ulimit.o: $(topdir)/error.h $(topdir)/general.h $(topdir)/xmalloc.h
|
||||
ulimit.o: $(topdir)/quit.h $(topdir)/dispose_cmd.h $(topdir)/make_cmd.h
|
||||
ulimit.o: $(topdir)/subst.h $(topdir)/externs.h $(BASHINCDIR)/maxpath.h
|
||||
ulimit.o: $(topdir)/shell.h $(topdir)/syntax.h $(topdir)/unwind_prot.h $(topdir)/variables.h $(topdir)/conftypes.h
|
||||
umask.o: $(topdir)/command.h ../config.h $(BASHINCDIR)/memalloc.h
|
||||
umask.o: $(topdir)/error.h $(topdir)/general.h $(topdir)/xmalloc.h
|
||||
umask.o: $(topdir)/quit.h $(topdir)/dispose_cmd.h $(topdir)/make_cmd.h
|
||||
umask.o: $(topdir)/subst.h $(topdir)/externs.h $(BASHINCDIR)/maxpath.h
|
||||
umask.o: $(topdir)/shell.h $(topdir)/syntax.h $(topdir)/unwind_prot.h $(topdir)/variables.h $(topdir)/conftypes.h
|
||||
umask.o: $(BASHINCDIR)/chartypes.h
|
||||
wait.o: $(topdir)/command.h ../config.h $(BASHINCDIR)/memalloc.h
|
||||
wait.o: $(topdir)/error.h $(topdir)/general.h $(topdir)/xmalloc.h
|
||||
wait.o: $(topdir)/quit.h $(topdir)/dispose_cmd.h $(topdir)/make_cmd.h
|
||||
wait.o: $(topdir)/subst.h $(topdir)/externs.h $(BASHINCDIR)/maxpath.h
|
||||
wait.o: $(topdir)/shell.h $(topdir)/syntax.h $(topdir)/unwind_prot.h $(topdir)/variables.h $(topdir)/conftypes.h
|
||||
wait.o: $(topdir)/jobs.h
|
||||
wait.o: $(BASHINCDIR)/chartypes.h
|
||||
shopt.o: $(topdir)/command.h ../config.h $(BASHINCDIR)/memalloc.h
|
||||
shopt.o: $(topdir)/error.h $(topdir)/general.h $(topdir)/xmalloc.h
|
||||
shopt.o: $(topdir)/quit.h $(topdir)/dispose_cmd.h $(topdir)/make_cmd.h
|
||||
shopt.o: $(topdir)/subst.h $(topdir)/externs.h $(BASHINCDIR)/maxpath.h
|
||||
shopt.o: $(topdir)/shell.h $(topdir)/syntax.h $(topdir)/unwind_prot.h $(topdir)/variables.h $(topdir)/conftypes.h
|
||||
shopt.o: $(srcdir)/common.h $(srcdir)/bashgetopt.h
|
||||
|
||||
complete.o: ../config.h
|
||||
complete.o: ${topdir}/shell.h $(topdir)/syntax.h ${topdir}/bashjmp.h ${BASHINCDIR}/posixjmp.h ${topdir}/sig.h
|
||||
complete.o: ${topdir}/unwind_prot.h ${topdir}/variables.h
|
||||
complete.o: ${topdir}/bashtypes.h ${topdir}/bashansi.h ${BASHINCDIR}/ansi_stdlib.h
|
||||
complete.o: ${topdir}/builtins.h
|
||||
complete.o: ${topdir}/pcomplete.h
|
||||
complete.o: ${srcdir}/common.h ${srcdir}/bashgetopt.h
|
||||
|
||||
#bind.o: $(RL_LIBSRC)chardefs.h $(RL_LIBSRC)readline.h $(RL_LIBSRC)keymaps.h
|
||||
|
||||
# libintl dependencies
|
||||
bind.o: ${topdir}/bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h
|
||||
break.o: ${topdir}/bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h
|
||||
caller.o: ${topdir}/bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h
|
||||
cd.o: ${topdir}/bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h
|
||||
common.c: ${topdir}/bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h
|
||||
complete.o: ${topdir}/bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h
|
||||
declare.o: ${topdir}/bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h
|
||||
enable.o: ${topdir}/bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h
|
||||
evalfile.c: ${topdir}/bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h
|
||||
exec.o: ${topdir}/bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h
|
||||
exit.o: ${topdir}/bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h
|
||||
fc.o: ${topdir}/bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h
|
||||
fg_bg.o: ${topdir}/bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h
|
||||
getopt.c: ${topdir}/bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h
|
||||
hash.o: ${topdir}/bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h
|
||||
help.o: ${topdir}/bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h
|
||||
history.o: ${topdir}/bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h
|
||||
inlib.o: ${topdir}/bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h
|
||||
jobs.o: ${topdir}/bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h
|
||||
kill.o: ${topdir}/bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h
|
||||
let.o: ${topdir}/bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h
|
||||
mkbuiltins.o: ${topdir}/bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h
|
||||
printf.o: ${topdir}/bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h
|
||||
pushd.o: ${topdir}/bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h
|
||||
read.o: ${topdir}/bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h
|
||||
return.o: ${topdir}/bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h
|
||||
set.o: ${topdir}/bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h
|
||||
setattr.o: ${topdir}/bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h
|
||||
shift.o: ${topdir}/bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h
|
||||
shopt.o: ${topdir}/bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h
|
||||
source.o: ${topdir}/bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h
|
||||
suspend.o: ${topdir}/bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h
|
||||
type.o: ${topdir}/bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h
|
||||
ulimit.o: ${topdir}/bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h
|
||||
umask.o: ${topdir}/bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h
|
||||
@@ -1,659 +0,0 @@
|
||||
# This Makefile for building libbuiltins.a is in -*- text -*- for Emacs.
|
||||
#
|
||||
# Copyright (C) 1996-2009 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
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
PACKAGE = @PACKAGE_NAME@
|
||||
PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
|
||||
PACKAGE_NAME = @PACKAGE_NAME@
|
||||
PACKAGE_STRING = @PACKAGE_STRING@
|
||||
PACKAGE_VERSION = @PACKAGE_VERSION@
|
||||
|
||||
#
|
||||
SHELL = @MAKE_SHELL@
|
||||
RANLIB = @RANLIB@
|
||||
CC = @CC@
|
||||
CC_FOR_BUILD = @CC_FOR_BUILD@
|
||||
AR = @AR@
|
||||
ARFLAGS = @ARFLAGS@
|
||||
RM = rm -f
|
||||
CP = cp
|
||||
|
||||
EXEEXT = @EXEEXT@
|
||||
|
||||
prefix = @prefix@
|
||||
|
||||
srcdir = @srcdir@
|
||||
VPATH = .:@srcdir@
|
||||
topdir = @top_srcdir@
|
||||
|
||||
datarootdir = @datarootdir@
|
||||
|
||||
includedir = @includedir@
|
||||
datadir = @datadir@
|
||||
localedir = @localedir@
|
||||
|
||||
# Support an alternate destination root directory for package building
|
||||
DESTDIR =
|
||||
|
||||
INSTALL = @INSTALL@
|
||||
INSTALL_DATA = @INSTALL_DATA@
|
||||
BUILD_DIR = @BUILD_DIR@
|
||||
|
||||
LIBBUILD = ${BUILD_DIR}/lib
|
||||
|
||||
PROFILE_FLAGS = @PROFILE_FLAGS@
|
||||
CFLAGS = @CFLAGS@
|
||||
CFLAGS_FOR_BUILD = @CFLAGS_FOR_BUILD@ @CROSS_COMPILE@
|
||||
CPPFLAGS = @CPPFLAGS@
|
||||
CPPFLAGS_FOR_BUILD = @CPPFLAGS_FOR_BUILD@
|
||||
LOCAL_CFLAGS = @LOCAL_CFLAGS@ ${DEBUG}
|
||||
DEFS = @DEFS@
|
||||
LOCAL_DEFS = @LOCAL_DEFS@
|
||||
|
||||
LIBS = @LIBS@
|
||||
LDFLAGS = @LDFLAGS@ $(LOCAL_LDFLAGS) $(CFLAGS)
|
||||
LDFLAGS_FOR_BUILD = @LDFLAGS_FOR_BUILD@ $(LOCAL_LDFLAGS) $(CFLAGS_FOR_BUILD)
|
||||
LOCAL_LDFLAGS = @LOCAL_LDFLAGS@
|
||||
#LIBS_FOR_BUILD = @LIBS_FOR_BUILD@
|
||||
LIBS_FOR_BUILD = $(LIBS)
|
||||
|
||||
BASHINCDIR = ${topdir}/include
|
||||
|
||||
RL_INCLUDEDIR = @RL_INCLUDEDIR@
|
||||
|
||||
INTL_LIBSRC = ${topdir}/lib/intl
|
||||
INTL_BUILDDIR = ${LIBBUILD}/intl
|
||||
INTL_LIBDIR = ${INTL_BUILDDIR}
|
||||
INTL_LIBRARY = ${INTL_BUILDDIR}/libintl.a
|
||||
INTL_INC = @INTL_INC@
|
||||
INTL_DEP = @INTL_DEP@
|
||||
LIBINTL_H = @LIBINTL_H@
|
||||
|
||||
HELPDIR = @HELPDIR@
|
||||
MKDIRS = ${topdir}/support/mkdirs
|
||||
|
||||
INCLUDES = -I. -I.. @RL_INCLUDE@ -I$(topdir) -I$(BASHINCDIR) -I$(topdir)/lib -I$(srcdir) ${INTL_INC}
|
||||
|
||||
BASE_CCFLAGS = ${PROFILE_FLAGS} $(DEFS) $(LOCAL_DEFS) $(SYSTEM_FLAGS) \
|
||||
${INCLUDES} $(LOCAL_CFLAGS)
|
||||
|
||||
CCFLAGS = $(BASE_CCFLAGS) $(CPPFLAGS) $(CFLAGS)
|
||||
|
||||
CCFLAGS_FOR_BUILD = $(BASE_CCFLAGS) $(CPPFLAGS_FOR_BUILD) $(CFLAGS_FOR_BUILD)
|
||||
|
||||
GCC_LINT_FLAGS = -Wall -Wshadow -Wpointer-arith -Wcast-qual \
|
||||
-Wcast-align -Wstrict-prototypes -Wconversion \
|
||||
-Wmissing-prototypes -Wtraditional -Wredundant-decls -pedantic
|
||||
|
||||
MKBUILTINS = mkbuiltins$(EXEEXT)
|
||||
DIRECTDEFINE = -D $(srcdir)
|
||||
HELPDIRDEFINE = @HELPDIRDEFINE@
|
||||
HELPSTRINGS = @HELPSTRINGS@
|
||||
|
||||
# xxx this is bad style
|
||||
RL_LIBSRC = $(topdir)/lib/readline
|
||||
|
||||
.SUFFIXES:
|
||||
.SUFFIXES: .def .c .o
|
||||
# How to make a .o file from a .def file.
|
||||
.def.o:
|
||||
$(RM) $@
|
||||
./$(MKBUILTINS) $(DIRECTDEFINE) $<
|
||||
$(CC) -c $(CCFLAGS) $*.c || ( $(RM) $*.c ; exit 1 )
|
||||
$(RM) $*.c
|
||||
|
||||
# How to make a .c file from a .def file.
|
||||
.def.c:
|
||||
$(RM) $@
|
||||
./$(MKBUILTINS) $(DIRECTDEFINE) $<
|
||||
|
||||
# default rule for making a .o file from a .c file
|
||||
.c.o:
|
||||
$(RM) $@
|
||||
$(CC) -c $(CCFLAGS) $<
|
||||
|
||||
DEFSRC = $(srcdir)/alias.def $(srcdir)/bind.def $(srcdir)/break.def \
|
||||
$(srcdir)/builtin.def $(srcdir)/caller.def \
|
||||
$(srcdir)/cd.def $(srcdir)/colon.def \
|
||||
$(srcdir)/command.def $(srcdir)/declare.def $(srcdir)/echo.def \
|
||||
$(srcdir)/enable.def $(srcdir)/eval.def $(srcdir)/getopts.def \
|
||||
$(srcdir)/exec.def $(srcdir)/exit.def $(srcdir)/fc.def \
|
||||
$(srcdir)/fg_bg.def $(srcdir)/hash.def $(srcdir)/help.def \
|
||||
$(srcdir)/history.def $(srcdir)/jobs.def $(srcdir)/kill.def \
|
||||
$(srcdir)/let.def $(srcdir)/read.def $(srcdir)/return.def \
|
||||
$(srcdir)/set.def $(srcdir)/setattr.def $(srcdir)/shift.def \
|
||||
$(srcdir)/source.def $(srcdir)/suspend.def $(srcdir)/test.def \
|
||||
$(srcdir)/times.def $(srcdir)/trap.def $(srcdir)/type.def \
|
||||
$(srcdir)/ulimit.def $(srcdir)/umask.def $(srcdir)/wait.def \
|
||||
$(srcdir)/reserved.def $(srcdir)/pushd.def $(srcdir)/shopt.def \
|
||||
$(srcdir)/printf.def $(srcdir)/complete.def $(srcdir)/mapfile.def
|
||||
|
||||
STATIC_SOURCE = common.c evalstring.c evalfile.c getopt.c bashgetopt.c \
|
||||
getopt.h
|
||||
|
||||
OFILES = builtins.o \
|
||||
alias.o bind.o break.o builtin.o caller.o cd.o colon.o command.o \
|
||||
common.o declare.o echo.o enable.o eval.o evalfile.o \
|
||||
evalstring.o exec.o exit.o fc.o fg_bg.o hash.o help.o history.o \
|
||||
jobs.o kill.o let.o mapfile.o \
|
||||
pushd.o read.o return.o set.o setattr.o shift.o source.o \
|
||||
suspend.o test.o times.o trap.o type.o ulimit.o umask.o \
|
||||
wait.o getopts.o shopt.o printf.o getopt.o bashgetopt.o complete.o
|
||||
|
||||
CREATED_FILES = builtext.h builtins.c psize.aux pipesize.h
|
||||
|
||||
all: $(MKBUILTINS) libbuiltins.a
|
||||
|
||||
libbuiltins.a: $(MKBUILTINS) $(OFILES) builtins.o
|
||||
$(RM) $@
|
||||
$(AR) $(ARFLAGS) $@ $(OFILES)
|
||||
-$(RANLIB) $@
|
||||
|
||||
builtext.h builtins.c: $(MKBUILTINS) $(DEFSRC)
|
||||
@-if test -f builtins.c; then mv -f builtins.c old-builtins.c; fi
|
||||
@-if test -f builtext.h; then mv -f builtext.h old-builtext.h; fi
|
||||
./$(MKBUILTINS) -externfile builtext.h -structfile builtins.c \
|
||||
-noproduction $(DIRECTDEFINE) $(HELPDIRDEFINE) $(HELPSTRINGS) $(DEFSRC)
|
||||
@-if cmp -s old-builtext.h builtext.h 2>/dev/null; then \
|
||||
mv old-builtext.h builtext.h; \
|
||||
else \
|
||||
$(RM) old-builtext.h; \
|
||||
fi
|
||||
@-if cmp -s old-builtins.c builtins.c 2>/dev/null; then \
|
||||
mv old-builtins.c builtins.c; \
|
||||
else \
|
||||
$(RM) old-builtins.c; \
|
||||
fi
|
||||
|
||||
helpdoc: $(MKBUILTINS) $(DEFSRC)
|
||||
./$(MKBUILTINS) ${HELPDIRDEFINE} -noproduction $(DIRECTDEFINE) $(DEFSRC)
|
||||
|
||||
install-help:
|
||||
@-if test -n "${HELPDIR}" && test -d helpfiles ; then \
|
||||
test -d $(DESTDIR)${HELPDIR} || ${SHELL} ${MKDIRS} $(DESTDIR)$(HELPDIR) ;\
|
||||
( for f in helpfiles/*; do \
|
||||
echo installing $$f; \
|
||||
${INSTALL_DATA} $$f $(DESTDIR)$(HELPDIR); \
|
||||
done; ) ; \
|
||||
fi
|
||||
|
||||
install: @HELPINSTALL@
|
||||
|
||||
mkbuiltins.o: ../config.h
|
||||
mkbuiltins.o: mkbuiltins.c
|
||||
$(RM) $@
|
||||
$(CC_FOR_BUILD) -c $(CCFLAGS_FOR_BUILD) $<
|
||||
|
||||
mkbuiltins$(EXEEXT): mkbuiltins.o
|
||||
$(CC_FOR_BUILD) $(LDFLAGS_FOR_BUILD) -o $(MKBUILTINS) mkbuiltins.o $(LIBS_FOR_BUILD)
|
||||
|
||||
# rules for deficient makes, like SunOS
|
||||
mkbuiltins.o: mkbuiltins.c
|
||||
builtins.o: builtins.c
|
||||
common.o: common.c
|
||||
bashgetopt.o: bashgetopt.c
|
||||
getopt.o: getopt.c
|
||||
evalstring.o: evalstring.c
|
||||
evalfile.o: evalfile.c
|
||||
|
||||
ulimit.o: pipesize.h
|
||||
|
||||
pipesize.h: psize.aux
|
||||
$(SHELL) $(srcdir)/psize.sh > $@
|
||||
|
||||
psize.aux: psize.c
|
||||
$(CC_FOR_BUILD) $(CCFLAGS_FOR_BUILD) -o $@ $(srcdir)/psize.c
|
||||
|
||||
documentation: builtins.texi
|
||||
|
||||
builtins.texi: $(MKBUILTINS)
|
||||
./$(MKBUILTINS) -documentonly $(DEFSRC)
|
||||
|
||||
clean:
|
||||
$(RM) $(OFILES) $(CREATED_FILES) $(MKBUILTINS) mkbuiltins.o libbuiltins.a
|
||||
-test -d helpfiles && $(RM) -r helpfiles
|
||||
|
||||
mostlyclean:
|
||||
$(RM) $(OFILES) libbuiltins.a
|
||||
|
||||
distclean maintainer-clean: clean
|
||||
$(RM) Makefile
|
||||
|
||||
$(OFILES): $(MKBUILTINS) ../config.h
|
||||
|
||||
../version.h: ../config.h ../Makefile Makefile
|
||||
-( cd ${BUILD_DIR} && ${MAKE} ${MFLAGS} version.h )
|
||||
|
||||
# maintainer special - for now
|
||||
po: builtins.c
|
||||
xgettext -L C -o $(topdir)/po/builtins.pot --keyword='N_' builtins.c 2>/dev/null
|
||||
|
||||
${LIBINTL_H}:
|
||||
@echo making $@ in ${INTL_BUILDDIR}
|
||||
@(cd ${INTL_BUILDDIR} && \
|
||||
$(MAKE) $(MFLAGS) libintl.h) || exit 1
|
||||
|
||||
# dependencies
|
||||
|
||||
alias.o: alias.def
|
||||
bind.o: bind.def
|
||||
break.o: break.def
|
||||
builtin.o: builtin.def
|
||||
caller.o: caller.def
|
||||
cd.o: cd.def
|
||||
colon.o: colon.def
|
||||
command.o: command.def
|
||||
declare.o: declare.def
|
||||
echo.o: echo.def
|
||||
enable.o: enable.def
|
||||
eval.o: eval.def
|
||||
exec.o: exec.def
|
||||
exit.o: exit.def
|
||||
fc.o: fc.def
|
||||
fg_bg.o: fg_bg.def
|
||||
hash.o: hash.def
|
||||
help.o: help.def
|
||||
history.o: history.def
|
||||
jobs.o: jobs.def
|
||||
kill.o: kill.def
|
||||
let.o: let.def
|
||||
mapfile.o: mapfile.def
|
||||
printf.o: printf.def
|
||||
pushd.o: pushd.def
|
||||
read.o: read.def
|
||||
return.o: return.def
|
||||
set.o: set.def
|
||||
setattr.o: setattr.def
|
||||
shift.o: shift.def
|
||||
shopt.o: shopt.def
|
||||
source.o: source.def
|
||||
suspend.o: suspend.def
|
||||
test.o: test.def
|
||||
times.o: times.def
|
||||
trap.o: trap.def
|
||||
type.o: type.def
|
||||
ulimit.o: ulimit.def
|
||||
umask.o: umask.def
|
||||
wait.o: wait.def
|
||||
getopts.o: getopts.def
|
||||
reserved.o: reserved.def
|
||||
complete.o: complete.def
|
||||
|
||||
# C files
|
||||
bashgetopt.o: ../config.h $(topdir)/bashansi.h $(BASHINCDIR)/ansi_stdlib.h
|
||||
bashgetopt.o: $(topdir)/shell.h $(topdir)/syntax.h $(topdir)/bashjmp.h
|
||||
bashgetopt.o: $(topdir)/command.h $(topdir)/general.h $(topdir)/xmalloc.h $(topdir)/error.h
|
||||
bashgetopt.o: $(topdir)/variables.h $(topdir)/conftypes.h $(topdir)/quit.h $(BASHINCDIR)/maxpath.h
|
||||
bashgetopt.o: $(topdir)/unwind_prot.h $(topdir)/dispose_cmd.h
|
||||
bashgetopt.o: $(topdir)/make_cmd.h $(topdir)/subst.h $(topdir)/sig.h
|
||||
bashgetopt.o: ../pathnames.h $(topdir)/externs.h $(srcdir)/common.h
|
||||
bashgetopt.o: $(BASHINCDIR)/chartypes.h
|
||||
common.o: $(topdir)/bashtypes.h $(BASHINCDIR)/posixstat.h $(topdir)/bashansi.h $(BASHINCDIR)/ansi_stdlib.h
|
||||
common.o: $(topdir)/shell.h $(topdir)/syntax.h ../config.h $(topdir)/bashjmp.h $(BASHINCDIR)/posixjmp.h
|
||||
common.o: $(topdir)/sig.h $(topdir)/command.h
|
||||
common.o: $(topdir)/general.h $(topdir)/xmalloc.h $(BASHINCDIR)/stdc.h $(BASHINCDIR)/memalloc.h
|
||||
common.o: $(topdir)/variables.h $(topdir)/conftypes.h $(topdir)/input.h
|
||||
common.o: $(topdir)/siglist.h $(topdir)/bashhist.h $(topdir)/quit.h
|
||||
common.o: $(topdir)/unwind_prot.h $(BASHINCDIR)/maxpath.h $(topdir)/jobs.h
|
||||
common.o: $(topdir)/builtins.h $(topdir)/dispose_cmd.h $(topdir)/make_cmd.h
|
||||
common.o: $(topdir)/subst.h $(topdir)/execute_cmd.h $(topdir)/error.h
|
||||
common.o: $(topdir)/externs.h ../pathnames.h ./builtext.h
|
||||
common.o: $(BASHINCDIR)/chartypes.h
|
||||
evalfile.o: $(topdir)/bashtypes.h $(BASHINCDIR)/posixstat.h ${BASHINCDIR}/filecntl.h
|
||||
evalfile.o: $(topdir)/bashansi.h $(BASHINCDIR)/ansi_stdlib.h
|
||||
evalfile.o: $(topdir)/shell.h $(topdir)/syntax.h ../config.h $(topdir)/bashjmp.h
|
||||
evalfile.o: $(topdir)/command.h $(topdir)/general.h $(topdir)/xmalloc.h $(topdir)/error.h
|
||||
evalfile.o: $(topdir)/variables.h $(topdir)/conftypes.h $(topdir)/quit.h $(BASHINCDIR)/maxpath.h
|
||||
evalfile.o: $(topdir)/unwind_prot.h $(topdir)/dispose_cmd.h
|
||||
evalfile.o: $(topdir)/make_cmd.h $(topdir)/subst.h $(topdir)/sig.h
|
||||
evalfile.o: ../pathnames.h $(topdir)/externs.h
|
||||
evalfile.o: $(topdir)/jobs.h $(topdir)/builtins.h $(topdir)/flags.h
|
||||
evalfile.o: $(topdir)/input.h $(topdir)/execute_cmd.h
|
||||
evalfile.o: $(topdir)/bashhist.h $(srcdir)/common.h
|
||||
evalstring.o: ../config.h $(topdir)/bashansi.h $(BASHINCDIR)/ansi_stdlib.h
|
||||
evalstring.o: $(topdir)/shell.h $(topdir)/syntax.h $(topdir)/bashjmp.h $(BASHINCDIR)/posixjmp.h
|
||||
evalstring.o: $(topdir)/sig.h $(topdir)/command.h $(topdir)/siglist.h
|
||||
evalstring.o: $(BASHINCDIR)/memalloc.h $(topdir)/variables.h $(topdir)/conftypes.h $(topdir)/input.h
|
||||
evalstring.o: $(topdir)/quit.h $(topdir)/unwind_prot.h
|
||||
evalstring.o: $(BASHINCDIR)/maxpath.h $(topdir)/jobs.h $(topdir)/builtins.h
|
||||
evalstring.o: $(topdir)/dispose_cmd.h $(topdir)/make_cmd.h $(topdir)/subst.h
|
||||
evalstring.o: $(topdir)/externs.h $(topdir)/jobs.h $(topdir)/builtins.h
|
||||
evalstring.o: $(topdir)/flags.h $(topdir)/input.h $(topdir)/execute_cmd.h
|
||||
evalstring.o: $(topdir)/bashhist.h $(srcdir)/common.h
|
||||
evalstring.o: $(topdir)/trap.h $(topdir)/redir.h ../pathnames.h
|
||||
getopt.o: ../config.h $(BASHINCDIR)/memalloc.h
|
||||
getopt.o: $(topdir)/shell.h $(topdir)/syntax.h $(topdir)/bashjmp.h $(topdir)/command.h
|
||||
getopt.o: $(topdir)/general.h $(topdir)/xmalloc.h $(topdir)/error.h $(topdir)/variables.h $(topdir)/conftypes.h
|
||||
getopt.o: $(topdir)/quit.h $(BASHINCDIR)/maxpath.h $(topdir)/unwind_prot.h
|
||||
getopt.o: $(topdir)/dispose_cmd.h $(topdir)/make_cmd.h $(topdir)/subst.h
|
||||
getopt.o: $(topdir)/sig.h ../pathnames.h $(topdir)/externs.h
|
||||
getopt.o: $(srcdir)/getopt.h
|
||||
mkbuiltins.o: ../config.h $(topdir)/bashtypes.h $(BASHINCDIR)/posixstat.h
|
||||
mkbuiltins.o: ${BASHINCDIR}/filecntl.h
|
||||
mkbuiltins.o: $(topdir)/bashansi.h $(BASHINCDIR)/ansi_stdlib.h
|
||||
|
||||
# def files
|
||||
alias.o: $(topdir)/command.h ../config.h $(BASHINCDIR)/memalloc.h
|
||||
alias.o: $(topdir)/error.h $(topdir)/general.h $(topdir)/xmalloc.h $(BASHINCDIR)/maxpath.h
|
||||
alias.o: $(topdir)/quit.h $(topdir)/dispose_cmd.h $(topdir)/make_cmd.h
|
||||
alias.o: $(topdir)/subst.h $(topdir)/externs.h $(srcdir)/common.h
|
||||
alias.o: $(topdir)/shell.h $(topdir)/syntax.h $(topdir)/unwind_prot.h $(topdir)/variables.h $(topdir)/conftypes.h
|
||||
alias.o: ../pathnames.h
|
||||
bind.o: $(topdir)/command.h ../config.h $(BASHINCDIR)/memalloc.h $(topdir)/error.h
|
||||
bind.o: $(topdir)/quit.h $(topdir)/dispose_cmd.h $(topdir)/make_cmd.h
|
||||
bind.o: $(topdir)/subst.h $(topdir)/externs.h $(srcdir)/bashgetopt.h
|
||||
bind.o: $(topdir)/general.h $(topdir)/xmalloc.h $(BASHINCDIR)/maxpath.h $(topdir)/bashline.h
|
||||
bind.o: $(topdir)/shell.h $(topdir)/syntax.h $(topdir)/unwind_prot.h $(topdir)/variables.h $(topdir)/conftypes.h
|
||||
bind.o: ../pathnames.h
|
||||
break.o: $(topdir)/command.h ../config.h $(BASHINCDIR)/memalloc.h
|
||||
break.o: $(topdir)/error.h $(topdir)/general.h $(topdir)/xmalloc.h
|
||||
break.o: $(topdir)/quit.h $(topdir)/dispose_cmd.h $(topdir)/make_cmd.h
|
||||
break.o: $(topdir)/subst.h $(topdir)/externs.h $(BASHINCDIR)/maxpath.h
|
||||
break.o: $(topdir)/shell.h $(topdir)/syntax.h $(topdir)/unwind_prot.h $(topdir)/variables.h $(topdir)/conftypes.h
|
||||
break.o: ../pathnames.h
|
||||
builtin.o: $(topdir)/command.h ../config.h $(BASHINCDIR)/memalloc.h
|
||||
builtin.o: $(topdir)/error.h $(topdir)/general.h $(topdir)/xmalloc.h $(topdir)/externs.h
|
||||
builtin.o: $(topdir)/quit.h $(srcdir)/common.h $(BASHINCDIR)/maxpath.h
|
||||
builtin.o: $(topdir)/dispose_cmd.h $(topdir)/make_cmd.h $(topdir)/subst.h
|
||||
builtin.o: $(topdir)/shell.h $(topdir)/syntax.h $(topdir)/unwind_prot.h $(topdir)/variables.h $(topdir)/conftypes.h
|
||||
builtin.o: $(srcdir)/bashgetopt.h ../pathnames.h
|
||||
caller.o: $(topdir)/command.h ../config.h $(BASHINCDIR)/memalloc.h $(topdir)/error.h
|
||||
caller.o: $(topdir)/general.h $(topdir)/xmalloc.h $(topdir)/quit.h $(topdir)/dispose_cmd.h
|
||||
caller.o: $(topdir)/make_cmd.h $(topdir)/subst.h $(topdir)/externs.h
|
||||
caller.o: $(topdir)/shell.h $(topdir)/syntax.h $(topdir)/unwind_prot.h $(topdir)/variables.h $(topdir)/conftypes.h
|
||||
caller.o: $(srcdir)/common.h $(BASHINCDIR)/maxpath.h ./builtext.h
|
||||
caller.o: ${BASHINCDIR}/chartypes.h $(topdir)/bashtypes.h ../pathnames.h
|
||||
cd.o: $(topdir)/command.h ../config.h $(BASHINCDIR)/memalloc.h $(topdir)/error.h
|
||||
cd.o: $(topdir)/general.h $(topdir)/xmalloc.h $(topdir)/quit.h $(topdir)/dispose_cmd.h
|
||||
cd.o: $(topdir)/make_cmd.h $(topdir)/subst.h $(topdir)/externs.h
|
||||
cd.o: $(topdir)/shell.h $(topdir)/syntax.h $(topdir)/unwind_prot.h $(topdir)/variables.h $(topdir)/conftypes.h
|
||||
cd.o: $(srcdir)/common.h $(BASHINCDIR)/maxpath.h ../pathnames.h
|
||||
command.o: $(topdir)/command.h ../config.h $(BASHINCDIR)/memalloc.h
|
||||
command.o: $(topdir)/error.h $(topdir)/general.h $(topdir)/xmalloc.h $(topdir)/externs.h
|
||||
command.o: $(topdir)/quit.h $(srcdir)/bashgetopt.h $(BASHINCDIR)/maxpath.h
|
||||
command.o: $(topdir)/dispose_cmd.h $(topdir)/make_cmd.h $(topdir)/subst.h
|
||||
command.o: $(topdir)/shell.h $(topdir)/syntax.h $(topdir)/unwind_prot.h $(topdir)/variables.h $(topdir)/conftypes.h
|
||||
command.o: ../pathnames.h
|
||||
declare.o: $(topdir)/command.h ../config.h $(BASHINCDIR)/memalloc.h
|
||||
declare.o: $(topdir)/error.h $(topdir)/general.h $(topdir)/xmalloc.h
|
||||
declare.o: $(topdir)/quit.h $(topdir)/dispose_cmd.h $(topdir)/make_cmd.h
|
||||
declare.o: $(topdir)/subst.h $(topdir)/externs.h $(BASHINCDIR)/maxpath.h
|
||||
declare.o: $(topdir)/shell.h $(topdir)/syntax.h $(topdir)/unwind_prot.h $(topdir)/variables.h $(topdir)/conftypes.h
|
||||
declare.o: $(topdir)/arrayfunc.h $(srcdir)/bashgetopt.h
|
||||
declare.o: ./builtext.h ../pathnames.h
|
||||
echo.o: $(topdir)/command.h ../config.h $(BASHINCDIR)/memalloc.h $(topdir)/error.h
|
||||
echo.o: $(topdir)/general.h $(topdir)/xmalloc.h $(topdir)/subst.h $(topdir)/externs.h
|
||||
echo.o: $(topdir)/quit.h $(topdir)/dispose_cmd.h $(topdir)/make_cmd.h
|
||||
echo.o: $(topdir)/shell.h $(topdir)/syntax.h $(topdir)/unwind_prot.h $(topdir)/variables.h $(topdir)/conftypes.h
|
||||
echo.o: $(BASHINCDIR)/maxpath.h ../pathnames.h
|
||||
enable.o: $(topdir)/command.h ../config.h $(BASHINCDIR)/memalloc.h
|
||||
enable.o: $(topdir)/error.h $(topdir)/general.h $(topdir)/xmalloc.h
|
||||
enable.o: $(topdir)/quit.h $(topdir)/dispose_cmd.h $(topdir)/make_cmd.h
|
||||
enable.o: $(topdir)/subst.h $(topdir)/externs.h
|
||||
enable.o: $(topdir)/shell.h $(topdir)/syntax.h $(topdir)/unwind_prot.h $(topdir)/variables.h $(topdir)/conftypes.h
|
||||
enable.o: $(BASHINCDIR)/maxpath.h ../pathnames.h
|
||||
enable.o: $(topdir)/pcomplete.h
|
||||
eval.o: $(topdir)/command.h ../config.h $(BASHINCDIR)/memalloc.h
|
||||
eval.o: $(topdir)/error.h $(topdir)/general.h $(topdir)/xmalloc.h
|
||||
eval.o: $(topdir)/quit.h $(topdir)/dispose_cmd.h $(topdir)/make_cmd.h
|
||||
eval.o: $(topdir)/subst.h $(topdir)/externs.h
|
||||
eval.o: $(topdir)/shell.h $(topdir)/syntax.h $(topdir)/unwind_prot.h $(topdir)/variables.h $(topdir)/conftypes.h
|
||||
eval.o: $(BASHINCDIR)/maxpath.h ../pathnames.h
|
||||
exec.o: $(topdir)/bashtypes.h
|
||||
exec.o: $(topdir)/command.h ../config.h $(BASHINCDIR)/memalloc.h
|
||||
exec.o: $(topdir)/error.h $(topdir)/general.h $(topdir)/xmalloc.h
|
||||
exec.o: $(topdir)/quit.h $(topdir)/dispose_cmd.h $(topdir)/make_cmd.h
|
||||
exec.o: $(topdir)/subst.h $(topdir)/externs.h $(topdir)/flags.h
|
||||
exec.o: $(topdir)/shell.h $(topdir)/syntax.h $(topdir)/unwind_prot.h $(topdir)/variables.h $(topdir)/conftypes.h
|
||||
exec.o: $(srcdir)/common.h $(topdir)/execute_cmd.h $(BASHINCDIR)/maxpath.h
|
||||
exec.o: $(topdir)/findcmd.h $(topdir)/jobs.h ../pathnames.h
|
||||
exit.o: $(topdir)/bashtypes.h
|
||||
exit.o: $(topdir)/command.h ../config.h $(BASHINCDIR)/memalloc.h
|
||||
exit.o: $(topdir)/error.h $(topdir)/general.h $(topdir)/xmalloc.h
|
||||
exit.o: $(topdir)/quit.h $(topdir)/dispose_cmd.h $(topdir)/make_cmd.h
|
||||
exit.o: $(topdir)/subst.h $(topdir)/externs.h $(topdir)/jobs.h
|
||||
exit.o: $(topdir)/shell.h $(topdir)/syntax.h $(topdir)/unwind_prot.h $(topdir)/variables.h $(topdir)/conftypes.h
|
||||
exit.o: $(BASHINCDIR)/maxpath.h ./builtext.h ../pathnames.h
|
||||
fc.o: $(topdir)/bashtypes.h $(BASHINCDIR)/posixstat.h
|
||||
fc.o: $(topdir)/builtins.h $(topdir)/command.h $(srcdir)/bashgetopt.h
|
||||
fc.o: $(topdir)/bashhist.h
|
||||
fc.o: $(topdir)/command.h ../config.h $(BASHINCDIR)/memalloc.h $(topdir)/error.h
|
||||
fc.o: $(topdir)/general.h $(topdir)/xmalloc.h $(BASHINCDIR)/maxpath.h
|
||||
fc.o: $(topdir)/quit.h $(topdir)/dispose_cmd.h $(topdir)/make_cmd.h
|
||||
fc.o: $(topdir)/subst.h $(topdir)/externs.h $(topdir)/shell.h $(topdir)/syntax.h
|
||||
fc.o: $(topdir)/flags.h $(topdir)/unwind_prot.h $(topdir)/variables.h $(topdir)/conftypes.h
|
||||
fc.o: $(topdir)/bashansi.h $(BASHINCDIR)/ansi_stdlib.h $(BASHINCDIR)/chartypes.h
|
||||
fc.o: ../pathnames.h
|
||||
fg_bg.o: $(topdir)/bashtypes.h $(srcdir)/bashgetopt.h
|
||||
fg_bg.o: $(topdir)/command.h ../config.h $(BASHINCDIR)/memalloc.h
|
||||
fg_bg.o: $(topdir)/error.h $(topdir)/general.h $(topdir)/xmalloc.h
|
||||
fg_bg.o: $(topdir)/quit.h $(topdir)/dispose_cmd.h $(topdir)/make_cmd.h
|
||||
fg_bg.o: $(topdir)/subst.h $(topdir)/externs.h $(BASHINCDIR)/maxpath.h
|
||||
fg_bg.o: $(topdir)/shell.h $(topdir)/syntax.h $(topdir)/unwind_prot.h $(topdir)/variables.h $(topdir)/conftypes.h
|
||||
fg_bg.o: $(topdir)/jobs.h ../pathnames.h
|
||||
getopts.o: $(topdir)/command.h ../config.h $(BASHINCDIR)/memalloc.h
|
||||
getopts.o: $(topdir)/error.h $(topdir)/general.h $(topdir)/xmalloc.h
|
||||
getopts.o: $(topdir)/quit.h $(topdir)/dispose_cmd.h $(topdir)/make_cmd.h
|
||||
getopts.o: $(topdir)/subst.h $(topdir)/externs.h $(BASHINCDIR)/maxpath.h
|
||||
getopts.o: $(topdir)/shell.h $(topdir)/syntax.h $(topdir)/unwind_prot.h $(topdir)/variables.h $(topdir)/conftypes.h
|
||||
getopts.o: ../pathnames.h
|
||||
hash.o: $(topdir)/builtins.h $(topdir)/command.h $(topdir)/quit.h
|
||||
hash.o: $(topdir)/findcmd.h $(topdir)/hashlib.h
|
||||
hash.o: $(topdir)/command.h ../config.h $(BASHINCDIR)/memalloc.h
|
||||
hash.o: $(topdir)/error.h $(topdir)/general.h $(topdir)/xmalloc.h
|
||||
hash.o: $(topdir)/shell.h $(topdir)/syntax.h $(topdir)/unwind_prot.h $(topdir)/variables.h $(topdir)/conftypes.h
|
||||
hash.o: $(srcdir)/common.h $(BASHINCDIR)/maxpath.h ../pathnames.h
|
||||
help.o: $(topdir)/command.h ../config.h $(BASHINCDIR)/memalloc.h
|
||||
help.o: $(topdir)/error.h $(topdir)/general.h $(topdir)/xmalloc.h
|
||||
help.o: $(topdir)/quit.h $(topdir)/dispose_cmd.h $(topdir)/make_cmd.h
|
||||
help.o: $(topdir)/subst.h $(topdir)/externs.h $(BASHINCDIR)/maxpath.h
|
||||
help.o: $(topdir)/shell.h $(topdir)/syntax.h $(topdir)/unwind_prot.h $(topdir)/variables.h $(topdir)/conftypes.h
|
||||
help.o: ${srcdir}/common.h ../pathnames.h
|
||||
history.o: $(topdir)/bashtypes.h
|
||||
history.o: $(topdir)/command.h ../config.h $(BASHINCDIR)/memalloc.h
|
||||
history.o: $(topdir)/error.h $(topdir)/general.h $(topdir)/xmalloc.h
|
||||
history.o: $(topdir)/quit.h $(topdir)/dispose_cmd.h $(topdir)/make_cmd.h
|
||||
history.o: $(topdir)/subst.h $(topdir)/externs.h
|
||||
history.o: ${BASHINCDIR}/filecntl.h $(topdir)/shell.h $(topdir)/syntax.h $(topdir)/unwind_prot.h
|
||||
history.o: $(topdir)/variables.h $(topdir)/conftypes.h $(topdir)/bashhist.h $(BASHINCDIR)/maxpath.h
|
||||
history.o: ../pathnames.h
|
||||
inlib.o: $(topdir)/command.h ../config.h $(BASHINCDIR)/memalloc.h
|
||||
inlib.o: $(topdir)/error.h $(topdir)/general.h $(topdir)/xmalloc.h
|
||||
inlib.o: $(topdir)/shell.h $(topdir)/syntax.h $(topdir)/unwind_prot.h $(topdir)/variables.h $(topdir)/conftypes.h
|
||||
inlib.o: $(BASHINCDIR)/maxpath.h $(topdir)/subst.h $(topdir)/externs.h
|
||||
inlib.o: $(topdir)/quit.h $(topdir)/dispose_cmd.h $(topdir)/make_cmd.h ../pathnames.h
|
||||
jobs.o: $(topdir)/command.h ../config.h $(BASHINCDIR)/memalloc.h $(topdir)/error.h
|
||||
jobs.o: $(topdir)/general.h $(topdir)/xmalloc.h $(topdir)/quit.h $(srcdir)/bashgetopt.h
|
||||
jobs.o: $(BASHINCDIR)/maxpath.h $(topdir)/externs.h $(topdir)/jobs.h
|
||||
jobs.o: $(topdir)/dispose_cmd.h $(topdir)/make_cmd.h $(topdir)/subst.h
|
||||
jobs.o: $(topdir)/shell.h $(topdir)/syntax.h $(topdir)/unwind_prot.h $(topdir)/variables.h $(topdir)/conftypes.h
|
||||
jobs.o: ../pathnames.h
|
||||
kill.o: $(topdir)/command.h ../config.h $(BASHINCDIR)/memalloc.h $(topdir)/error.h
|
||||
kill.o: $(topdir)/general.h $(topdir)/xmalloc.h $(topdir)/subst.h $(topdir)/externs.h
|
||||
kill.o: $(topdir)/quit.h $(topdir)/dispose_cmd.h $(topdir)/make_cmd.h
|
||||
kill.o: $(topdir)/shell.h $(topdir)/syntax.h $(topdir)/trap.h $(topdir)/unwind_prot.h
|
||||
kill.o: $(topdir)/variables.h $(topdir)/conftypes.h $(BASHINCDIR)/maxpath.h
|
||||
kill.o: $(topdir)/jobs.h ../pathnames.h
|
||||
let.o: $(topdir)/command.h ../config.h $(BASHINCDIR)/memalloc.h
|
||||
let.o: $(topdir)/error.h $(topdir)/general.h $(topdir)/xmalloc.h
|
||||
let.o: $(topdir)/quit.h $(topdir)/dispose_cmd.h $(topdir)/make_cmd.h
|
||||
let.o: $(topdir)/subst.h $(topdir)/externs.h $(BASHINCDIR)/maxpath.h
|
||||
let.o: $(topdir)/shell.h $(topdir)/syntax.h $(topdir)/unwind_prot.h $(topdir)/variables.h $(topdir)/conftypes.h
|
||||
let.o: ../pathnames.h
|
||||
printf.o: ../config.h $(BASHINCDIR)/memalloc.h $(topdir)/bashjmp.h
|
||||
printf.o: $(topdir)/command.h $(topdir)/error.h $(topdir)/general.h $(topdir)/xmalloc.h
|
||||
printf.o: $(topdir)/quit.h $(topdir)/dispose_cmd.h $(topdir)/make_cmd.h
|
||||
printf.o: $(topdir)/subst.h $(topdir)/externs.h $(topdir)/sig.h
|
||||
printf.o: ../pathnames.h $(topdir)/shell.h $(topdir)/syntax.h $(topdir)/unwind_prot.h
|
||||
printf.o: $(topdir)/variables.h $(topdir)/conftypes.h $(BASHINCDIR)/stdc.h $(srcdir)/bashgetopt.h
|
||||
printf.o: $(topdir)/bashtypes.h ${srcdir}/common.h $(BASHINCDIR)/chartypes.h
|
||||
printf.o: ../pathnames.h
|
||||
pushd.o: $(topdir)/command.h ../config.h $(BASHINCDIR)/memalloc.h
|
||||
pushd.o: $(topdir)/error.h $(topdir)/general.h $(topdir)/xmalloc.h
|
||||
pushd.o: $(topdir)/quit.h $(topdir)/dispose_cmd.h $(topdir)/make_cmd.h
|
||||
pushd.o: $(topdir)/subst.h $(topdir)/externs.h
|
||||
pushd.o: $(topdir)/shell.h $(topdir)/syntax.h $(topdir)/unwind_prot.h $(topdir)/variables.h $(topdir)/conftypes.h
|
||||
pushd.o: $(BASHINCDIR)/maxpath.h $(srcdir)/common.h ./builtext.h
|
||||
pushd.o: ../pathnames.h
|
||||
read.o: $(topdir)/command.h ../config.h $(BASHINCDIR)/memalloc.h
|
||||
read.o: $(topdir)/error.h $(topdir)/general.h $(topdir)/xmalloc.h
|
||||
read.o: $(topdir)/quit.h $(topdir)/dispose_cmd.h $(topdir)/make_cmd.h
|
||||
read.o: $(topdir)/subst.h $(topdir)/externs.h $(BASHINCDIR)/maxpath.h
|
||||
read.o: $(topdir)/shell.h $(topdir)/syntax.h $(topdir)/unwind_prot.h $(topdir)/variables.h $(topdir)/conftypes.h
|
||||
read.o: $(BASHINCDIR)/shtty.h
|
||||
read.o: $(topdir)/arrayfunc.h ../pathnames.h
|
||||
return.o: $(topdir)/command.h ../config.h $(BASHINCDIR)/memalloc.h
|
||||
return.o: $(topdir)/error.h $(topdir)/general.h $(topdir)/xmalloc.h
|
||||
return.o: $(topdir)/quit.h $(topdir)/dispose_cmd.h $(topdir)/make_cmd.h
|
||||
return.o: $(topdir)/subst.h $(topdir)/externs.h $(BASHINCDIR)/maxpath.h
|
||||
return.o: $(topdir)/shell.h $(topdir)/syntax.h $(topdir)/unwind_prot.h $(topdir)/variables.h $(topdir)/conftypes.h
|
||||
return.o: ../pathnames.h
|
||||
set.o: $(topdir)/command.h ../config.h $(BASHINCDIR)/memalloc.h
|
||||
set.o: $(topdir)/general.h $(topdir)/xmalloc.h $(topdir)/subst.h $(topdir)/externs.h
|
||||
set.o: $(topdir)/quit.h $(topdir)/dispose_cmd.h $(topdir)/make_cmd.h
|
||||
set.o: $(topdir)/shell.h $(topdir)/syntax.h $(topdir)/unwind_prot.h $(topdir)/variables.h $(topdir)/conftypes.h
|
||||
set.o: $(BASHINCDIR)/maxpath.h $(topdir)/error.h
|
||||
set.o: $(topdir)/arrayfunc.h ../pathnames.h
|
||||
setattr.o: $(topdir)/command.h ../config.h $(BASHINCDIR)/memalloc.h
|
||||
setattr.o: $(topdir)/error.h $(topdir)/general.h $(topdir)/xmalloc.h $(BASHINCDIR)/maxpath.h
|
||||
setattr.o: $(topdir)/quit.h $(srcdir)/common.h $(srcdir)/bashgetopt.h
|
||||
setattr.o: $(topdir)/dispose_cmd.h $(topdir)/make_cmd.h $(topdir)/subst.h
|
||||
setattr.o: $(topdir)/externs.h
|
||||
setattr.o: $(topdir)/shell.h $(topdir)/syntax.h $(topdir)/unwind_prot.h $(topdir)/variables.h $(topdir)/conftypes.h
|
||||
setattr.o: $(topdir)/arrayfunc.h ../pathnames.h
|
||||
shift.o: $(topdir)/command.h ../config.h $(BASHINCDIR)/memalloc.h
|
||||
shift.o: $(topdir)/error.h $(topdir)/general.h $(topdir)/xmalloc.h
|
||||
shift.o: $(topdir)/quit.h $(topdir)/dispose_cmd.h $(topdir)/make_cmd.h
|
||||
shift.o: $(topdir)/subst.h $(topdir)/externs.h $(BASHINCDIR)/maxpath.h
|
||||
shift.o: $(topdir)/shell.h $(topdir)/syntax.h $(topdir)/unwind_prot.h $(topdir)/variables.h $(topdir)/conftypes.h
|
||||
shift.o: ../pathnames.h
|
||||
shopt.o: $(topdir)/command.h ../config.h $(BASHINCDIR)/memalloc.h
|
||||
shopt.o: $(topdir)/error.h $(topdir)/general.h $(topdir)/xmalloc.h
|
||||
shopt.o: $(topdir)/quit.h $(topdir)/dispose_cmd.h $(topdir)/make_cmd.h
|
||||
shopt.o: $(topdir)/subst.h $(topdir)/externs.h $(BASHINCDIR)/maxpath.h
|
||||
shopt.o: $(topdir)/shell.h $(topdir)/syntax.h $(topdir)/unwind_prot.h $(topdir)/variables.h $(topdir)/conftypes.h
|
||||
shopt.o: $(srcdir)/common.h $(srcdir)/bashgetopt.h ../pathnames.h
|
||||
shopt.o: $(topdir)/bashhist.h
|
||||
source.o: $(topdir)/command.h ../config.h $(BASHINCDIR)/memalloc.h
|
||||
source.o: $(topdir)/error.h $(topdir)/general.h $(topdir)/xmalloc.h $(topdir)/findcmd.h
|
||||
source.o: $(topdir)/quit.h $(topdir)/dispose_cmd.h $(topdir)/make_cmd.h
|
||||
source.o: $(topdir)/subst.h $(topdir)/externs.h $(BASHINCDIR)/maxpath.h
|
||||
source.o: $(topdir)/shell.h $(topdir)/syntax.h $(topdir)/unwind_prot.h $(topdir)/variables.h $(topdir)/conftypes.h
|
||||
source.o: $(srcdir)/bashgetopt.h $(topdir)/flags.h $(topdir)/trap.h
|
||||
source.o: ../pathnames.h
|
||||
suspend.o: $(topdir)/command.h ../config.h $(BASHINCDIR)/memalloc.h
|
||||
suspend.o: $(topdir)/error.h $(topdir)/general.h $(topdir)/xmalloc.h
|
||||
suspend.o: $(topdir)/quit.h $(topdir)/dispose_cmd.h $(topdir)/make_cmd.h
|
||||
suspend.o: $(topdir)/subst.h $(topdir)/externs.h $(BASHINCDIR)/maxpath.h
|
||||
suspend.o: $(topdir)/shell.h $(topdir)/syntax.h $(topdir)/unwind_prot.h $(topdir)/variables.h $(topdir)/conftypes.h
|
||||
suspend.o: $(topdir)/jobs.h ../pathnames.h
|
||||
test.o: $(topdir)/command.h ../config.h $(BASHINCDIR)/memalloc.h
|
||||
test.o: $(topdir)/error.h $(topdir)/general.h $(topdir)/xmalloc.h
|
||||
test.o: $(topdir)/quit.h $(topdir)/dispose_cmd.h $(topdir)/make_cmd.h
|
||||
test.o: $(topdir)/subst.h $(topdir)/externs.h $(BASHINCDIR)/maxpath.h
|
||||
test.o: $(topdir)/shell.h $(topdir)/syntax.h $(topdir)/unwind_prot.h $(topdir)/variables.h $(topdir)/conftypes.h
|
||||
test.o: $(topdir)/test.h ../pathnames.h
|
||||
times.o: $(topdir)/command.h ../config.h $(BASHINCDIR)/memalloc.h
|
||||
times.o: $(topdir)/error.h $(topdir)/general.h $(topdir)/xmalloc.h
|
||||
times.o: $(topdir)/quit.h $(topdir)/dispose_cmd.h $(topdir)/make_cmd.h
|
||||
times.o: $(topdir)/subst.h $(topdir)/externs.h $(BASHINCDIR)/maxpath.h
|
||||
times.o: $(topdir)/shell.h $(topdir)/syntax.h $(topdir)/unwind_prot.h $(topdir)/variables.h $(topdir)/conftypes.h
|
||||
times.o: $(BASHINCDIR)/posixtime.h ../pathnames.h
|
||||
trap.o: $(topdir)/command.h ../config.h $(BASHINCDIR)/memalloc.h
|
||||
trap.o: $(topdir)/error.h $(topdir)/general.h $(topdir)/xmalloc.h $(topdir)/externs.h
|
||||
trap.o: $(topdir)/quit.h $(srcdir)/common.h $(BASHINCDIR)/maxpath.h
|
||||
trap.o: $(topdir)/dispose_cmd.h $(topdir)/make_cmd.h $(topdir)/subst.h
|
||||
trap.o: $(topdir)/shell.h $(topdir)/syntax.h $(topdir)/unwind_prot.h $(topdir)/variables.h $(topdir)/conftypes.h
|
||||
trap.o: $(topdir)/findcmd.h ../pathnames.h
|
||||
type.o: $(topdir)/command.h ../config.h $(BASHINCDIR)/memalloc.h
|
||||
type.o: $(topdir)/error.h $(topdir)/general.h $(topdir)/xmalloc.h
|
||||
type.o: $(topdir)/quit.h $(srcdir)/common.h $(BASHINCDIR)/maxpath.h
|
||||
type.o: $(topdir)/dispose_cmd.h $(topdir)/make_cmd.h $(topdir)/subst.h
|
||||
type.o: $(topdir)/externs.h $(topdir)/hashcmd.h ../pathnames.h
|
||||
type.o: $(topdir)/shell.h $(topdir)/syntax.h $(topdir)/unwind_prot.h $(topdir)/variables.h $(topdir)/conftypes.h
|
||||
ulimit.o: $(topdir)/command.h ../config.h $(BASHINCDIR)/memalloc.h
|
||||
ulimit.o: $(topdir)/error.h $(topdir)/general.h $(topdir)/xmalloc.h
|
||||
ulimit.o: $(topdir)/quit.h $(topdir)/dispose_cmd.h $(topdir)/make_cmd.h
|
||||
ulimit.o: $(topdir)/subst.h $(topdir)/externs.h $(BASHINCDIR)/maxpath.h
|
||||
ulimit.o: $(topdir)/shell.h $(topdir)/syntax.h $(topdir)/unwind_prot.h $(topdir)/variables.h $(topdir)/conftypes.h
|
||||
ulimit.o: ../pathnames.h
|
||||
umask.o: $(topdir)/command.h ../config.h $(BASHINCDIR)/memalloc.h
|
||||
umask.o: $(topdir)/error.h $(topdir)/general.h $(topdir)/xmalloc.h
|
||||
umask.o: $(topdir)/quit.h $(topdir)/dispose_cmd.h $(topdir)/make_cmd.h
|
||||
umask.o: $(topdir)/subst.h $(topdir)/externs.h $(BASHINCDIR)/maxpath.h
|
||||
umask.o: $(topdir)/shell.h $(topdir)/syntax.h $(topdir)/unwind_prot.h $(topdir)/variables.h $(topdir)/conftypes.h
|
||||
umask.o: $(BASHINCDIR)/chartypes.h ../pathnames.h
|
||||
wait.o: $(topdir)/command.h ../config.h $(BASHINCDIR)/memalloc.h
|
||||
wait.o: $(topdir)/error.h $(topdir)/general.h $(topdir)/xmalloc.h
|
||||
wait.o: $(topdir)/quit.h $(topdir)/dispose_cmd.h $(topdir)/make_cmd.h
|
||||
wait.o: $(topdir)/subst.h $(topdir)/externs.h $(BASHINCDIR)/maxpath.h
|
||||
wait.o: $(topdir)/shell.h $(topdir)/syntax.h $(topdir)/unwind_prot.h $(topdir)/variables.h $(topdir)/conftypes.h
|
||||
wait.o: $(topdir)/jobs.h
|
||||
wait.o: $(BASHINCDIR)/chartypes.h ../pathnames.h
|
||||
|
||||
complete.o: ../config.h ../pathnames.h
|
||||
complete.o: ${topdir}/shell.h $(topdir)/syntax.h ${topdir}/bashjmp.h ${BASHINCDIR}/posixjmp.h ${topdir}/sig.h
|
||||
complete.o: ${topdir}/unwind_prot.h ${topdir}/variables.h
|
||||
complete.o: ${topdir}/bashtypes.h ${topdir}/bashansi.h ${BASHINCDIR}/ansi_stdlib.h
|
||||
complete.o: ${topdir}/builtins.h
|
||||
complete.o: ${topdir}/pcomplete.h
|
||||
complete.o: ${srcdir}/common.h ${srcdir}/bashgetopt.h
|
||||
mapfile.o: $(topdir)/command.h ../config.h $(BASHINCDIR)/memalloc.h
|
||||
mapfile.o: $(topdir)/error.h $(topdir)/general.h $(topdir)/xmalloc.h
|
||||
mapfile.o: $(topdir)/quit.h $(topdir)/dispose_cmd.h $(topdir)/make_cmd.h
|
||||
mapfile.o: $(topdir)/subst.h $(topdir)/externs.h $(BASHINCDIR)/maxpath.h
|
||||
mapfile.o: $(topdir)/shell.h $(topdir)/syntax.h $(topdir)/variables.h $(topdir)/conftypes.h
|
||||
mapfile.o: $(topdir)/arrayfunc.h ../pathnames.h
|
||||
|
||||
#bind.o: $(RL_LIBSRC)chardefs.h $(RL_LIBSRC)readline.h $(RL_LIBSRC)keymaps.h
|
||||
|
||||
# libintl dependencies
|
||||
bind.o: ${topdir}/bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h
|
||||
break.o: ${topdir}/bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h
|
||||
caller.o: ${topdir}/bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h
|
||||
cd.o: ${topdir}/bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h
|
||||
common.c: ${topdir}/bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h
|
||||
complete.o: ${topdir}/bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h
|
||||
declare.o: ${topdir}/bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h
|
||||
enable.o: ${topdir}/bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h
|
||||
evalfile.c: ${topdir}/bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h
|
||||
exec.o: ${topdir}/bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h
|
||||
exit.o: ${topdir}/bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h
|
||||
fc.o: ${topdir}/bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h
|
||||
fg_bg.o: ${topdir}/bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h
|
||||
getopt.c: ${topdir}/bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h
|
||||
hash.o: ${topdir}/bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h
|
||||
help.o: ${topdir}/bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h
|
||||
history.o: ${topdir}/bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h
|
||||
inlib.o: ${topdir}/bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h
|
||||
jobs.o: ${topdir}/bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h
|
||||
kill.o: ${topdir}/bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h
|
||||
let.o: ${topdir}/bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h
|
||||
mapfile.o: ${topdir}/bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h
|
||||
mkbuiltins.o: ${topdir}/bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h
|
||||
printf.o: ${topdir}/bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h
|
||||
pushd.o: ${topdir}/bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h
|
||||
read.o: ${topdir}/bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h
|
||||
return.o: ${topdir}/bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h
|
||||
set.o: ${topdir}/bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h
|
||||
setattr.o: ${topdir}/bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h
|
||||
shift.o: ${topdir}/bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h
|
||||
shopt.o: ${topdir}/bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h
|
||||
source.o: ${topdir}/bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h
|
||||
suspend.o: ${topdir}/bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h
|
||||
type.o: ${topdir}/bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h
|
||||
ulimit.o: ${topdir}/bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h
|
||||
umask.o: ${topdir}/bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h
|
||||
@@ -1,533 +0,0 @@
|
||||
This file is cd.def, from which is created cd.c. It implements the
|
||||
builtins "cd" and "pwd" in Bash.
|
||||
|
||||
Copyright (C) 1987-2010 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Bash, the Bourne Again SHell.
|
||||
|
||||
Bash is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Bash is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Bash. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
$PRODUCES cd.c
|
||||
#include <config.h>
|
||||
|
||||
#if defined (HAVE_UNISTD_H)
|
||||
# ifdef _MINIX
|
||||
# include <sys/types.h>
|
||||
# endif
|
||||
# include <unistd.h>
|
||||
#endif
|
||||
|
||||
#include "../bashtypes.h"
|
||||
#include "posixdir.h"
|
||||
#include "posixstat.h"
|
||||
#ifndef _MINIX
|
||||
#include <sys/param.h>
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "../bashansi.h"
|
||||
#include "../bashintl.h"
|
||||
|
||||
#include <errno.h>
|
||||
#include <tilde/tilde.h>
|
||||
|
||||
#include "../shell.h"
|
||||
#include "../flags.h"
|
||||
#include "maxpath.h"
|
||||
#include "common.h"
|
||||
#include "bashgetopt.h"
|
||||
|
||||
#if !defined (errno)
|
||||
extern int errno;
|
||||
#endif /* !errno */
|
||||
|
||||
extern int posixly_correct;
|
||||
extern int array_needs_making;
|
||||
extern const char * const bash_getcwd_errstr;
|
||||
|
||||
static int bindpwd __P((int));
|
||||
static void setpwd __P((char *));
|
||||
static char *resetpwd __P((char *));
|
||||
static int change_to_directory __P((char *, int));
|
||||
|
||||
/* Change this to 1 to get cd spelling correction by default. */
|
||||
int cdspelling = 0;
|
||||
|
||||
int cdable_vars;
|
||||
|
||||
static int eflag; /* file scope so bindpwd() can see it */
|
||||
|
||||
$BUILTIN cd
|
||||
$FUNCTION cd_builtin
|
||||
$SHORT_DOC cd [-L|[-P [-e]]] [dir]
|
||||
Change the shell working directory.
|
||||
|
||||
Change the current directory to DIR. The default DIR is the value of the
|
||||
HOME shell variable.
|
||||
|
||||
The variable CDPATH defines the search path for the directory containing
|
||||
DIR. Alternative directory names in CDPATH are separated by a colon (:).
|
||||
A null directory name is the same as the current directory. If DIR begins
|
||||
with a slash (/), then CDPATH is not used.
|
||||
|
||||
If the directory is not found, and the shell option `cdable_vars' is set,
|
||||
the word is assumed to be a variable name. If that variable has a value,
|
||||
its value is used for DIR.
|
||||
|
||||
Options:
|
||||
-L force symbolic links to be followed
|
||||
-P use the physical directory structure without following symbolic
|
||||
links
|
||||
-e if the -P option is supplied, and the current working directory
|
||||
cannot be determined successfully, exit with a non-zero status
|
||||
|
||||
The default is to follow symbolic links, as if `-L' were specified.
|
||||
|
||||
Exit Status:
|
||||
Returns 0 if the directory is changed, and if $PWD is set successfully when
|
||||
-P is used; non-zero otherwise.
|
||||
$END
|
||||
|
||||
/* Just set $PWD, don't change OLDPWD. Used by `pwd -P' in posix mode. */
|
||||
static void
|
||||
setpwd (dirname)
|
||||
char *dirname;
|
||||
{
|
||||
int old_anm;
|
||||
SHELL_VAR *tvar;
|
||||
|
||||
old_anm = array_needs_making;
|
||||
tvar = bind_variable ("PWD", dirname ? dirname : "", 0);
|
||||
if (old_anm == 0 && array_needs_making && exported_p (tvar))
|
||||
{
|
||||
update_export_env_inplace ("PWD=", 4, dirname ? dirname : "");
|
||||
array_needs_making = 0;
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
bindpwd (no_symlinks)
|
||||
int no_symlinks;
|
||||
{
|
||||
char *dirname, *pwdvar;
|
||||
int old_anm, r;
|
||||
SHELL_VAR *tvar;
|
||||
|
||||
r = sh_chkwrite (EXECUTION_SUCCESS);
|
||||
|
||||
#define tcwd the_current_working_directory
|
||||
dirname = tcwd ? (no_symlinks ? sh_physpath (tcwd, 0) : tcwd)
|
||||
: get_working_directory ("cd");
|
||||
#undef tcwd
|
||||
|
||||
old_anm = array_needs_making;
|
||||
pwdvar = get_string_value ("PWD");
|
||||
|
||||
tvar = bind_variable ("OLDPWD", pwdvar, 0);
|
||||
if (old_anm == 0 && array_needs_making && exported_p (tvar))
|
||||
{
|
||||
update_export_env_inplace ("OLDPWD=", 7, pwdvar);
|
||||
array_needs_making = 0;
|
||||
}
|
||||
|
||||
setpwd (dirname);
|
||||
if (dirname == 0 && eflag)
|
||||
r = EXECUTION_FAILURE;
|
||||
|
||||
if (dirname && dirname != the_current_working_directory)
|
||||
free (dirname);
|
||||
|
||||
return (r);
|
||||
}
|
||||
|
||||
/* Call get_working_directory to reset the value of
|
||||
the_current_working_directory () */
|
||||
static char *
|
||||
resetpwd (caller)
|
||||
char *caller;
|
||||
{
|
||||
char *tdir;
|
||||
|
||||
FREE (the_current_working_directory);
|
||||
the_current_working_directory = (char *)NULL;
|
||||
tdir = get_working_directory (caller);
|
||||
return (tdir);
|
||||
}
|
||||
|
||||
#define LCD_DOVARS 0x001
|
||||
#define LCD_DOSPELL 0x002
|
||||
#define LCD_PRINTPATH 0x004
|
||||
#define LCD_FREEDIRNAME 0x008
|
||||
|
||||
/* This builtin is ultimately the way that all user-visible commands should
|
||||
change the current working directory. It is called by cd_to_string (),
|
||||
so the programming interface is simple, and it handles errors and
|
||||
restrictions properly. */
|
||||
int
|
||||
cd_builtin (list)
|
||||
WORD_LIST *list;
|
||||
{
|
||||
char *dirname, *cdpath, *path, *temp;
|
||||
int path_index, no_symlinks, opt, lflag;
|
||||
|
||||
#if defined (RESTRICTED_SHELL)
|
||||
if (restricted)
|
||||
{
|
||||
sh_restricted ((char *)NULL);
|
||||
return (EXECUTION_FAILURE);
|
||||
}
|
||||
#endif /* RESTRICTED_SHELL */
|
||||
|
||||
eflag = 0;
|
||||
no_symlinks = no_symbolic_links;
|
||||
reset_internal_getopt ();
|
||||
while ((opt = internal_getopt (list, "LP")) != -1)
|
||||
{
|
||||
switch (opt)
|
||||
{
|
||||
case 'P':
|
||||
no_symlinks = 1;
|
||||
break;
|
||||
case 'L':
|
||||
no_symlinks = 0;
|
||||
break;
|
||||
case 'e':
|
||||
eflag = 1;
|
||||
break;
|
||||
default:
|
||||
builtin_usage ();
|
||||
return (EXECUTION_FAILURE);
|
||||
}
|
||||
}
|
||||
list = loptend;
|
||||
|
||||
lflag = (cdable_vars ? LCD_DOVARS : 0) |
|
||||
((interactive && cdspelling) ? LCD_DOSPELL : 0);
|
||||
if (eflag && no_symlinks == 0)
|
||||
eflag = 0;
|
||||
|
||||
if (list == 0)
|
||||
{
|
||||
/* `cd' without arguments is equivalent to `cd $HOME' */
|
||||
dirname = get_string_value ("HOME");
|
||||
|
||||
if (dirname == 0)
|
||||
{
|
||||
builtin_error (_("HOME not set"));
|
||||
return (EXECUTION_FAILURE);
|
||||
}
|
||||
lflag = 0;
|
||||
}
|
||||
else if (list->word->word[0] == '-' && list->word->word[1] == '\0')
|
||||
{
|
||||
/* This is `cd -', equivalent to `cd $OLDPWD' */
|
||||
dirname = get_string_value ("OLDPWD");
|
||||
|
||||
if (dirname == 0)
|
||||
{
|
||||
builtin_error (_("OLDPWD not set"));
|
||||
return (EXECUTION_FAILURE);
|
||||
}
|
||||
#if 0
|
||||
lflag = interactive ? LCD_PRINTPATH : 0;
|
||||
#else
|
||||
lflag = LCD_PRINTPATH; /* According to SUSv3 */
|
||||
#endif
|
||||
}
|
||||
else if (absolute_pathname (list->word->word))
|
||||
dirname = list->word->word;
|
||||
else if (privileged_mode == 0 && (cdpath = get_string_value ("CDPATH")))
|
||||
{
|
||||
dirname = list->word->word;
|
||||
|
||||
/* Find directory in $CDPATH. */
|
||||
path_index = 0;
|
||||
while (path = extract_colon_unit (cdpath, &path_index))
|
||||
{
|
||||
/* OPT is 1 if the path element is non-empty */
|
||||
opt = path[0] != '\0';
|
||||
temp = sh_makepath (path, dirname, MP_DOTILDE);
|
||||
free (path);
|
||||
|
||||
if (change_to_directory (temp, no_symlinks))
|
||||
{
|
||||
/* POSIX.2 says that if a nonempty directory from CDPATH
|
||||
is used to find the directory to change to, the new
|
||||
directory name is echoed to stdout, whether or not
|
||||
the shell is interactive. */
|
||||
if (opt && (path = no_symlinks ? temp : the_current_working_directory))
|
||||
printf ("%s\n", path);
|
||||
|
||||
free (temp);
|
||||
#if 0
|
||||
/* Posix.2 says that after using CDPATH, the resultant
|
||||
value of $PWD will not contain `.' or `..'. */
|
||||
return (bindpwd (posixly_correct || no_symlinks));
|
||||
#else
|
||||
return (bindpwd (no_symlinks));
|
||||
#endif
|
||||
}
|
||||
else
|
||||
free (temp);
|
||||
}
|
||||
|
||||
/* POSIX.2 says that if `.' does not appear in $CDPATH, we don't
|
||||
try the current directory, so we just punt now with an error
|
||||
message if POSIXLY_CORRECT is non-zero. The check for cdpath[0]
|
||||
is so we don't mistakenly treat a CDPATH value of "" as not
|
||||
specifying the current directory. */
|
||||
if (posixly_correct && cdpath[0])
|
||||
{
|
||||
#if 0
|
||||
builtin_error ("%s: %s", dirname, strerror (ENOENT));
|
||||
return (EXECUTION_FAILURE);
|
||||
#else /* changed for bash-4.2 Posix cd description steps 5-6 */
|
||||
if (no_symlinks)
|
||||
dirname = list->word->word;
|
||||
else
|
||||
dirname =
|
||||
#endif
|
||||
}
|
||||
}
|
||||
else
|
||||
dirname = list->word->word;
|
||||
|
||||
/* When we get here, DIRNAME is the directory to change to. If we
|
||||
chdir successfully, just return. */
|
||||
if (change_to_directory (dirname, no_symlinks))
|
||||
{
|
||||
if (lflag & LCD_PRINTPATH)
|
||||
printf ("%s\n", dirname);
|
||||
return (bindpwd (no_symlinks));
|
||||
}
|
||||
|
||||
/* If the user requests it, then perhaps this is the name of
|
||||
a shell variable, whose value contains the directory to
|
||||
change to. */
|
||||
if (lflag & LCD_DOVARS)
|
||||
{
|
||||
temp = get_string_value (dirname);
|
||||
if (temp && change_to_directory (temp, no_symlinks))
|
||||
{
|
||||
printf ("%s\n", temp);
|
||||
return (bindpwd (no_symlinks));
|
||||
}
|
||||
}
|
||||
|
||||
/* If the user requests it, try to find a directory name similar in
|
||||
spelling to the one requested, in case the user made a simple
|
||||
typo. This is similar to the UNIX 8th and 9th Edition shells. */
|
||||
if (lflag & LCD_DOSPELL)
|
||||
{
|
||||
temp = dirspell (dirname);
|
||||
if (temp && change_to_directory (temp, no_symlinks))
|
||||
{
|
||||
printf ("%s\n", temp);
|
||||
return (bindpwd (no_symlinks));
|
||||
}
|
||||
else
|
||||
FREE (temp);
|
||||
}
|
||||
|
||||
builtin_error ("%s: %s", dirname, strerror (errno));
|
||||
return (EXECUTION_FAILURE);
|
||||
}
|
||||
|
||||
$BUILTIN pwd
|
||||
$FUNCTION pwd_builtin
|
||||
$SHORT_DOC pwd [-LP]
|
||||
Print the name of the current working directory.
|
||||
|
||||
Options:
|
||||
-L print the value of $PWD if it names the current working
|
||||
directory
|
||||
-P print the physical directory, without any symbolic links
|
||||
|
||||
By default, `pwd' behaves as if `-L' were specified.
|
||||
|
||||
Exit Status:
|
||||
Returns 0 unless an invalid option is given or the current directory
|
||||
cannot be read.
|
||||
$END
|
||||
|
||||
/* Non-zero means that pwd always prints the physical directory, without
|
||||
symbolic links. */
|
||||
static int verbatim_pwd;
|
||||
|
||||
/* Print the name of the current working directory. */
|
||||
int
|
||||
pwd_builtin (list)
|
||||
WORD_LIST *list;
|
||||
{
|
||||
char *directory;
|
||||
int opt, pflag;
|
||||
|
||||
verbatim_pwd = no_symbolic_links;
|
||||
pflag = 0;
|
||||
reset_internal_getopt ();
|
||||
while ((opt = internal_getopt (list, "LP")) != -1)
|
||||
{
|
||||
switch (opt)
|
||||
{
|
||||
case 'P':
|
||||
verbatim_pwd = pflag = 1;
|
||||
break;
|
||||
case 'L':
|
||||
verbatim_pwd = 0;
|
||||
break;
|
||||
default:
|
||||
builtin_usage ();
|
||||
return (EXECUTION_FAILURE);
|
||||
}
|
||||
}
|
||||
list = loptend;
|
||||
|
||||
#define tcwd the_current_working_directory
|
||||
|
||||
directory = tcwd ? (verbatim_pwd ? sh_physpath (tcwd, 0) : tcwd)
|
||||
: get_working_directory ("pwd");
|
||||
|
||||
/* Try again using getcwd() if canonicalization fails (for instance, if
|
||||
the file system has changed state underneath bash). */
|
||||
if ((tcwd && directory == 0) ||
|
||||
(posixly_correct && same_file (".", tcwd, (struct stat *)0, (struct stat *)0) == 0))
|
||||
directory = resetpwd ("pwd");
|
||||
|
||||
#undef tcwd
|
||||
|
||||
if (directory)
|
||||
{
|
||||
printf ("%s\n", directory);
|
||||
/* This is dumb but posix-mandated. */
|
||||
if (posixly_correct && pflag)
|
||||
setpwd (directory);
|
||||
if (directory != the_current_working_directory)
|
||||
free (directory);
|
||||
return (sh_chkwrite (EXECUTION_SUCCESS));
|
||||
}
|
||||
else
|
||||
return (EXECUTION_FAILURE);
|
||||
}
|
||||
|
||||
/* Do the work of changing to the directory NEWDIR. Handle symbolic
|
||||
link following, etc. This function *must* return with
|
||||
the_current_working_directory either set to NULL (in which case
|
||||
getcwd() will eventually be called), or set to a string corresponding
|
||||
to the working directory. Return 1 on success, 0 on failure. */
|
||||
|
||||
static int
|
||||
change_to_directory (newdir, nolinks)
|
||||
char *newdir;
|
||||
int nolinks;
|
||||
{
|
||||
char *t, *tdir;
|
||||
int err, canon_failed, r, ndlen, dlen;
|
||||
|
||||
tdir = (char *)NULL;
|
||||
|
||||
if (the_current_working_directory == 0)
|
||||
{
|
||||
t = get_working_directory ("chdir");
|
||||
FREE (t);
|
||||
}
|
||||
|
||||
t = make_absolute (newdir, the_current_working_directory);
|
||||
|
||||
/* TDIR is either the canonicalized absolute pathname of NEWDIR
|
||||
(nolinks == 0) or the absolute physical pathname of NEWDIR
|
||||
(nolinks != 0). */
|
||||
tdir = nolinks ? sh_physpath (t, 0)
|
||||
: sh_canonpath (t, PATH_CHECKDOTDOT|PATH_CHECKEXISTS);
|
||||
|
||||
ndlen = strlen (newdir);
|
||||
dlen = strlen (t);
|
||||
|
||||
/* Use the canonicalized version of NEWDIR, or, if canonicalization
|
||||
failed, use the non-canonical form. */
|
||||
canon_failed = 0;
|
||||
if (tdir && *tdir)
|
||||
free (t);
|
||||
else
|
||||
{
|
||||
FREE (tdir);
|
||||
tdir = t;
|
||||
canon_failed = 1;
|
||||
}
|
||||
|
||||
/* In POSIX mode, if we're resolving symlinks logically and sh_canonpath
|
||||
returns NULL (because it checks the path, it will return NULL if the
|
||||
resolved path doesn't exist), fail immediately. */
|
||||
if (posixly_correct && nolinks == 0 && canon_failed && (errno != ENAMETOOLONG || ndlen > PATH_MAX))
|
||||
{
|
||||
#if defined ENAMETOOLONG
|
||||
if (errno != ENOENT && errno != ENAMETOOLONG)
|
||||
#else
|
||||
if (errno != ENOENT)
|
||||
#endif
|
||||
errno = ENOTDIR;
|
||||
free (tdir);
|
||||
return (0);
|
||||
}
|
||||
|
||||
/* If the chdir succeeds, update the_current_working_directory. */
|
||||
if (chdir (nolinks ? newdir : tdir) == 0)
|
||||
{
|
||||
/* If canonicalization failed, but the chdir succeeded, reset the
|
||||
shell's idea of the_current_working_directory. */
|
||||
if (canon_failed)
|
||||
{
|
||||
t = resetpwd ("cd");
|
||||
if (t == 0)
|
||||
set_working_directory (tdir);
|
||||
}
|
||||
else
|
||||
set_working_directory (tdir);
|
||||
|
||||
free (tdir);
|
||||
return (1);
|
||||
}
|
||||
|
||||
/* We failed to change to the appropriate directory name. If we tried
|
||||
what the user passed (nolinks != 0), punt now. */
|
||||
if (nolinks)
|
||||
{
|
||||
free (tdir);
|
||||
return (0);
|
||||
}
|
||||
|
||||
err = errno;
|
||||
|
||||
/* We're not in physical mode (nolinks == 0), but we failed to change to
|
||||
the canonicalized directory name (TDIR). Try what the user passed
|
||||
verbatim. If we succeed, reinitialize the_current_working_directory. */
|
||||
if (chdir (newdir) == 0)
|
||||
{
|
||||
t = resetpwd ("cd");
|
||||
if (t == 0)
|
||||
set_working_directory (tdir);
|
||||
else
|
||||
free (t);
|
||||
|
||||
r = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
errno = err;
|
||||
r = 0;
|
||||
}
|
||||
|
||||
free (tdir);
|
||||
return r;
|
||||
}
|
||||
@@ -1,890 +0,0 @@
|
||||
/* common.c - utility functions for all builtins */
|
||||
|
||||
/* Copyright (C) 1987-2009 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Bash, the Bourne Again SHell.
|
||||
|
||||
Bash is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Bash is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Bash. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#if defined (HAVE_UNISTD_H)
|
||||
# ifdef _MINIX
|
||||
# include <sys/types.h>
|
||||
# endif
|
||||
# include <unistd.h>
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <chartypes.h>
|
||||
#include "../bashtypes.h"
|
||||
#include "posixstat.h"
|
||||
#include <signal.h>
|
||||
|
||||
#include <errno.h>
|
||||
|
||||
#if defined (PREFER_STDARG)
|
||||
# include <stdarg.h>
|
||||
#else
|
||||
# include <varargs.h>
|
||||
#endif
|
||||
|
||||
#include "../bashansi.h"
|
||||
#include "../bashintl.h"
|
||||
|
||||
#define NEED_FPURGE_DECL
|
||||
|
||||
#include "../shell.h"
|
||||
#include "maxpath.h"
|
||||
#include "../flags.h"
|
||||
#include "../jobs.h"
|
||||
#include "../builtins.h"
|
||||
#include "../input.h"
|
||||
#include "../execute_cmd.h"
|
||||
#include "../trap.h"
|
||||
#include "bashgetopt.h"
|
||||
#include "common.h"
|
||||
#include "builtext.h"
|
||||
#include <tilde/tilde.h>
|
||||
|
||||
#if defined (HISTORY)
|
||||
# include "../bashhist.h"
|
||||
#endif
|
||||
|
||||
#if !defined (errno)
|
||||
extern int errno;
|
||||
#endif /* !errno */
|
||||
|
||||
extern int indirection_level, subshell_environment;
|
||||
extern int line_number;
|
||||
extern int last_command_exit_value;
|
||||
extern int running_trap;
|
||||
extern int posixly_correct;
|
||||
extern char *this_command_name, *shell_name;
|
||||
extern const char * const bash_getcwd_errstr;
|
||||
|
||||
/* Used by some builtins and the mainline code. */
|
||||
sh_builtin_func_t *last_shell_builtin = (sh_builtin_func_t *)NULL;
|
||||
sh_builtin_func_t *this_shell_builtin = (sh_builtin_func_t *)NULL;
|
||||
|
||||
/* **************************************************************** */
|
||||
/* */
|
||||
/* Error reporting, usage, and option processing */
|
||||
/* */
|
||||
/* **************************************************************** */
|
||||
|
||||
/* This is a lot like report_error (), but it is for shell builtins
|
||||
instead of shell control structures, and it won't ever exit the
|
||||
shell. */
|
||||
|
||||
static void
|
||||
builtin_error_prolog ()
|
||||
{
|
||||
char *name;
|
||||
|
||||
name = get_name_for_error ();
|
||||
fprintf (stderr, "%s: ", name);
|
||||
|
||||
if (interactive_shell == 0)
|
||||
fprintf (stderr, _("line %d: "), executing_line_number ());
|
||||
|
||||
if (this_command_name && *this_command_name)
|
||||
fprintf (stderr, "%s: ", this_command_name);
|
||||
}
|
||||
|
||||
void
|
||||
#if defined (PREFER_STDARG)
|
||||
builtin_error (const char *format, ...)
|
||||
#else
|
||||
builtin_error (format, va_alist)
|
||||
const char *format;
|
||||
va_dcl
|
||||
#endif
|
||||
{
|
||||
va_list args;
|
||||
|
||||
builtin_error_prolog ();
|
||||
|
||||
SH_VA_START (args, format);
|
||||
|
||||
vfprintf (stderr, format, args);
|
||||
va_end (args);
|
||||
fprintf (stderr, "\n");
|
||||
}
|
||||
|
||||
void
|
||||
#if defined (PREFER_STDARG)
|
||||
builtin_warning (const char *format, ...)
|
||||
#else
|
||||
builtin_warning (format, va_alist)
|
||||
const char *format;
|
||||
va_dcl
|
||||
#endif
|
||||
{
|
||||
va_list args;
|
||||
|
||||
builtin_error_prolog ();
|
||||
fprintf (stderr, _("warning: "));
|
||||
|
||||
SH_VA_START (args, format);
|
||||
|
||||
vfprintf (stderr, format, args);
|
||||
va_end (args);
|
||||
fprintf (stderr, "\n");
|
||||
}
|
||||
|
||||
/* Print a usage summary for the currently-executing builtin command. */
|
||||
void
|
||||
builtin_usage ()
|
||||
{
|
||||
if (this_command_name && *this_command_name)
|
||||
fprintf (stderr, _("%s: usage: "), this_command_name);
|
||||
fprintf (stderr, "%s\n", current_builtin->short_doc);
|
||||
fflush (stderr);
|
||||
}
|
||||
|
||||
/* Return if LIST is NULL else barf and jump to top_level. Used by some
|
||||
builtins that do not accept arguments. */
|
||||
void
|
||||
no_args (list)
|
||||
WORD_LIST *list;
|
||||
{
|
||||
if (list)
|
||||
{
|
||||
builtin_error (_("too many arguments"));
|
||||
top_level_cleanup ();
|
||||
jump_to_top_level (DISCARD);
|
||||
}
|
||||
}
|
||||
|
||||
/* Check that no options were given to the currently-executing builtin,
|
||||
and return 0 if there were options. */
|
||||
int
|
||||
no_options (list)
|
||||
WORD_LIST *list;
|
||||
{
|
||||
reset_internal_getopt ();
|
||||
if (internal_getopt (list, "") != -1)
|
||||
{
|
||||
builtin_usage ();
|
||||
return (1);
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
void
|
||||
sh_needarg (s)
|
||||
char *s;
|
||||
{
|
||||
builtin_error (_("%s: option requires an argument"), s);
|
||||
}
|
||||
|
||||
void
|
||||
sh_neednumarg (s)
|
||||
char *s;
|
||||
{
|
||||
builtin_error (_("%s: numeric argument required"), s);
|
||||
}
|
||||
|
||||
void
|
||||
sh_notfound (s)
|
||||
char *s;
|
||||
{
|
||||
builtin_error (_("%s: not found"), s);
|
||||
}
|
||||
|
||||
/* Function called when one of the builtin commands detects an invalid
|
||||
option. */
|
||||
void
|
||||
sh_invalidopt (s)
|
||||
char *s;
|
||||
{
|
||||
builtin_error (_("%s: invalid option"), s);
|
||||
}
|
||||
|
||||
void
|
||||
sh_invalidoptname (s)
|
||||
char *s;
|
||||
{
|
||||
builtin_error (_("%s: invalid option name"), s);
|
||||
}
|
||||
|
||||
void
|
||||
sh_invalidid (s)
|
||||
char *s;
|
||||
{
|
||||
builtin_error (_("`%s': not a valid identifier"), s);
|
||||
}
|
||||
|
||||
void
|
||||
sh_invalidnum (s)
|
||||
char *s;
|
||||
{
|
||||
char *msg;
|
||||
|
||||
if (*s == '0' && isdigit (s[1]))
|
||||
msg = _("invalid octal number");
|
||||
else if (*s == '0' && s[1] == 'x')
|
||||
msg = _("invalid hex number");
|
||||
else
|
||||
msg = _("invalid number");
|
||||
builtin_error ("%s: %s", s, msg);
|
||||
}
|
||||
|
||||
void
|
||||
sh_invalidsig (s)
|
||||
char *s;
|
||||
{
|
||||
builtin_error (_("%s: invalid signal specification"), s);
|
||||
}
|
||||
|
||||
void
|
||||
sh_badpid (s)
|
||||
char *s;
|
||||
{
|
||||
builtin_error (_("`%s': not a pid or valid job spec"), s);
|
||||
}
|
||||
|
||||
void
|
||||
sh_readonly (s)
|
||||
const char *s;
|
||||
{
|
||||
builtin_error (_("%s: readonly variable"), s);
|
||||
}
|
||||
|
||||
void
|
||||
sh_erange (s, desc)
|
||||
char *s, *desc;
|
||||
{
|
||||
if (s)
|
||||
builtin_error (_("%s: %s out of range"), s, desc ? desc : _("argument"));
|
||||
else
|
||||
builtin_error (_("%s out of range"), desc ? desc : _("argument"));
|
||||
}
|
||||
|
||||
#if defined (JOB_CONTROL)
|
||||
void
|
||||
sh_badjob (s)
|
||||
char *s;
|
||||
{
|
||||
builtin_error (_("%s: no such job"), s);
|
||||
}
|
||||
|
||||
void
|
||||
sh_nojobs (s)
|
||||
char *s;
|
||||
{
|
||||
if (s)
|
||||
builtin_error (_("%s: no job control"), s);
|
||||
else
|
||||
builtin_error (_("no job control"));
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined (RESTRICTED_SHELL)
|
||||
void
|
||||
sh_restricted (s)
|
||||
char *s;
|
||||
{
|
||||
if (s)
|
||||
builtin_error (_("%s: restricted"), s);
|
||||
else
|
||||
builtin_error (_("restricted"));
|
||||
}
|
||||
#endif
|
||||
|
||||
void
|
||||
sh_notbuiltin (s)
|
||||
char *s;
|
||||
{
|
||||
builtin_error (_("%s: not a shell builtin"), s);
|
||||
}
|
||||
|
||||
void
|
||||
sh_wrerror ()
|
||||
{
|
||||
#if defined (DONT_REPORT_BROKEN_PIPE_WRITE_ERRORS) && defined (EPIPE)
|
||||
if (errno != EPIPE)
|
||||
#endif /* DONT_REPORT_BROKEN_PIPE_WRITE_ERRORS && EPIPE */
|
||||
builtin_error (_("write error: %s"), strerror (errno));
|
||||
}
|
||||
|
||||
void
|
||||
sh_ttyerror (set)
|
||||
int set;
|
||||
{
|
||||
if (set)
|
||||
builtin_error (_("error setting terminal attributes: %s"), strerror (errno));
|
||||
else
|
||||
builtin_error (_("error getting terminal attributes: %s"), strerror (errno));
|
||||
}
|
||||
|
||||
int
|
||||
sh_chkwrite (s)
|
||||
int s;
|
||||
{
|
||||
fflush (stdout);
|
||||
if (ferror (stdout))
|
||||
{
|
||||
sh_wrerror ();
|
||||
fpurge (stdout);
|
||||
clearerr (stdout);
|
||||
return (EXECUTION_FAILURE);
|
||||
}
|
||||
return (s);
|
||||
}
|
||||
|
||||
/* **************************************************************** */
|
||||
/* */
|
||||
/* Shell positional parameter manipulation */
|
||||
/* */
|
||||
/* **************************************************************** */
|
||||
|
||||
/* Convert a WORD_LIST into a C-style argv. Return the number of elements
|
||||
in the list in *IP, if IP is non-null. A convenience function for
|
||||
loadable builtins; also used by `test'. */
|
||||
char **
|
||||
make_builtin_argv (list, ip)
|
||||
WORD_LIST *list;
|
||||
int *ip;
|
||||
{
|
||||
char **argv;
|
||||
|
||||
argv = strvec_from_word_list (list, 0, 1, ip);
|
||||
argv[0] = this_command_name;
|
||||
return argv;
|
||||
}
|
||||
|
||||
/* Remember LIST in $1 ... $9, and REST_OF_ARGS. If DESTRUCTIVE is
|
||||
non-zero, then discard whatever the existing arguments are, else
|
||||
only discard the ones that are to be replaced. */
|
||||
void
|
||||
remember_args (list, destructive)
|
||||
WORD_LIST *list;
|
||||
int destructive;
|
||||
{
|
||||
register int i;
|
||||
|
||||
for (i = 1; i < 10; i++)
|
||||
{
|
||||
if ((destructive || list) && dollar_vars[i])
|
||||
{
|
||||
free (dollar_vars[i]);
|
||||
dollar_vars[i] = (char *)NULL;
|
||||
}
|
||||
|
||||
if (list)
|
||||
{
|
||||
dollar_vars[i] = savestring (list->word->word);
|
||||
list = list->next;
|
||||
}
|
||||
}
|
||||
|
||||
/* If arguments remain, assign them to REST_OF_ARGS.
|
||||
Note that copy_word_list (NULL) returns NULL, and
|
||||
that dispose_words (NULL) does nothing. */
|
||||
if (destructive || list)
|
||||
{
|
||||
dispose_words (rest_of_args);
|
||||
rest_of_args = copy_word_list (list);
|
||||
}
|
||||
|
||||
if (destructive)
|
||||
set_dollar_vars_changed ();
|
||||
}
|
||||
|
||||
static int changed_dollar_vars;
|
||||
|
||||
/* Have the dollar variables been reset to new values since we last
|
||||
checked? */
|
||||
int
|
||||
dollar_vars_changed ()
|
||||
{
|
||||
return (changed_dollar_vars);
|
||||
}
|
||||
|
||||
void
|
||||
set_dollar_vars_unchanged ()
|
||||
{
|
||||
changed_dollar_vars = 0;
|
||||
}
|
||||
|
||||
void
|
||||
set_dollar_vars_changed ()
|
||||
{
|
||||
if (variable_context)
|
||||
changed_dollar_vars |= ARGS_FUNC;
|
||||
else if (this_shell_builtin == set_builtin)
|
||||
changed_dollar_vars |= ARGS_SETBLTIN;
|
||||
else
|
||||
changed_dollar_vars |= ARGS_INVOC;
|
||||
}
|
||||
|
||||
/* **************************************************************** */
|
||||
/* */
|
||||
/* Validating numeric input and arguments */
|
||||
/* */
|
||||
/* **************************************************************** */
|
||||
|
||||
/* Read a numeric arg for this_command_name, the name of the shell builtin
|
||||
that wants it. LIST is the word list that the arg is to come from.
|
||||
Accept only the numeric argument; report an error if other arguments
|
||||
follow. If FATAL is 1, call throw_to_top_level, which exits the
|
||||
shell; if it's 2, call jump_to_top_level (DISCARD), which aborts the
|
||||
current command; if FATAL is 0, return an indication of an invalid
|
||||
number by setting *NUMOK == 0 and return -1. */
|
||||
int
|
||||
get_numeric_arg (list, fatal, count)
|
||||
WORD_LIST *list;
|
||||
int fatal;
|
||||
intmax_t *count;
|
||||
{
|
||||
char *arg;
|
||||
|
||||
if (count)
|
||||
*count = 1;
|
||||
|
||||
if (list && list->word && ISOPTION (list->word->word, '-'))
|
||||
list = list->next;
|
||||
|
||||
if (list)
|
||||
{
|
||||
arg = list->word->word;
|
||||
if (arg == 0 || (legal_number (arg, count) == 0))
|
||||
{
|
||||
sh_neednumarg (list->word->word ? list->word->word : "`'");
|
||||
if (fatal == 0)
|
||||
return 0;
|
||||
else if (fatal == 1) /* fatal == 1; abort */
|
||||
throw_to_top_level ();
|
||||
else /* fatal == 2; discard current command */
|
||||
{
|
||||
top_level_cleanup ();
|
||||
jump_to_top_level (DISCARD);
|
||||
}
|
||||
}
|
||||
no_args (list->next);
|
||||
}
|
||||
|
||||
return (1);
|
||||
}
|
||||
|
||||
/* Get an eight-bit status value from LIST */
|
||||
int
|
||||
get_exitstat (list)
|
||||
WORD_LIST *list;
|
||||
{
|
||||
int status;
|
||||
intmax_t sval;
|
||||
char *arg;
|
||||
|
||||
if (list && list->word && ISOPTION (list->word->word, '-'))
|
||||
list = list->next;
|
||||
|
||||
if (list == 0)
|
||||
return (last_command_exit_value);
|
||||
|
||||
arg = list->word->word;
|
||||
if (arg == 0 || legal_number (arg, &sval) == 0)
|
||||
{
|
||||
sh_neednumarg (list->word->word ? list->word->word : "`'");
|
||||
return 255;
|
||||
}
|
||||
no_args (list->next);
|
||||
|
||||
status = sval & 255;
|
||||
return status;
|
||||
}
|
||||
|
||||
/* Return the octal number parsed from STRING, or -1 to indicate
|
||||
that the string contained a bad number. */
|
||||
int
|
||||
read_octal (string)
|
||||
char *string;
|
||||
{
|
||||
int result, digits;
|
||||
|
||||
result = digits = 0;
|
||||
while (*string && ISOCTAL (*string))
|
||||
{
|
||||
digits++;
|
||||
result = (result * 8) + (*string++ - '0');
|
||||
if (result > 0777)
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (digits == 0 || *string)
|
||||
result = -1;
|
||||
|
||||
return (result);
|
||||
}
|
||||
|
||||
/* **************************************************************** */
|
||||
/* */
|
||||
/* Manipulating the current working directory */
|
||||
/* */
|
||||
/* **************************************************************** */
|
||||
|
||||
/* Return a consed string which is the current working directory.
|
||||
FOR_WHOM is the name of the caller for error printing. */
|
||||
char *the_current_working_directory = (char *)NULL;
|
||||
|
||||
char *
|
||||
get_working_directory (for_whom)
|
||||
char *for_whom;
|
||||
{
|
||||
if (no_symbolic_links)
|
||||
{
|
||||
FREE (the_current_working_directory);
|
||||
the_current_working_directory = (char *)NULL;
|
||||
}
|
||||
|
||||
if (the_current_working_directory == 0)
|
||||
{
|
||||
#if defined (GETCWD_BROKEN)
|
||||
the_current_working_directory = getcwd (0, PATH_MAX);
|
||||
#else
|
||||
the_current_working_directory = getcwd (0, 0);
|
||||
#endif
|
||||
if (the_current_working_directory == 0)
|
||||
{
|
||||
fprintf (stderr, _("%s: error retrieving current directory: %s: %s\n"),
|
||||
(for_whom && *for_whom) ? for_whom : get_name_for_error (),
|
||||
_(bash_getcwd_errstr), strerror (errno));
|
||||
return (char *)NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return (savestring (the_current_working_directory));
|
||||
}
|
||||
|
||||
/* Make NAME our internal idea of the current working directory. */
|
||||
void
|
||||
set_working_directory (name)
|
||||
char *name;
|
||||
{
|
||||
FREE (the_current_working_directory);
|
||||
the_current_working_directory = savestring (name);
|
||||
}
|
||||
|
||||
/* **************************************************************** */
|
||||
/* */
|
||||
/* Job control support functions */
|
||||
/* */
|
||||
/* **************************************************************** */
|
||||
|
||||
#if defined (JOB_CONTROL)
|
||||
int
|
||||
get_job_by_name (name, flags)
|
||||
const char *name;
|
||||
int flags;
|
||||
{
|
||||
register int i, wl, cl, match, job;
|
||||
register PROCESS *p;
|
||||
register JOB *j;
|
||||
|
||||
job = NO_JOB;
|
||||
wl = strlen (name);
|
||||
for (i = js.j_jobslots - 1; i >= 0; i--)
|
||||
{
|
||||
j = get_job_by_jid (i);
|
||||
if (j == 0 || ((flags & JM_STOPPED) && J_JOBSTATE(j) != JSTOPPED))
|
||||
continue;
|
||||
|
||||
p = j->pipe;
|
||||
do
|
||||
{
|
||||
if (flags & JM_EXACT)
|
||||
{
|
||||
cl = strlen (p->command);
|
||||
match = STREQN (p->command, name, cl);
|
||||
}
|
||||
else if (flags & JM_SUBSTRING)
|
||||
match = strcasestr (p->command, name) != (char *)0;
|
||||
else
|
||||
match = STREQN (p->command, name, wl);
|
||||
|
||||
if (match == 0)
|
||||
{
|
||||
p = p->next;
|
||||
continue;
|
||||
}
|
||||
else if (flags & JM_FIRSTMATCH)
|
||||
return i; /* return first match */
|
||||
else if (job != NO_JOB)
|
||||
{
|
||||
if (this_shell_builtin)
|
||||
builtin_error (_("%s: ambiguous job spec"), name);
|
||||
else
|
||||
report_error (_("%s: ambiguous job spec"), name);
|
||||
return (DUP_JOB);
|
||||
}
|
||||
else
|
||||
job = i;
|
||||
}
|
||||
while (p != j->pipe);
|
||||
}
|
||||
|
||||
return (job);
|
||||
}
|
||||
|
||||
/* Return the job spec found in LIST. */
|
||||
int
|
||||
get_job_spec (list)
|
||||
WORD_LIST *list;
|
||||
{
|
||||
register char *word;
|
||||
int job, jflags;
|
||||
|
||||
if (list == 0)
|
||||
return (js.j_current);
|
||||
|
||||
word = list->word->word;
|
||||
|
||||
if (*word == '\0')
|
||||
return (NO_JOB);
|
||||
|
||||
if (*word == '%')
|
||||
word++;
|
||||
|
||||
if (DIGIT (*word) && all_digits (word))
|
||||
{
|
||||
job = atoi (word);
|
||||
return (job > js.j_jobslots ? NO_JOB : job - 1);
|
||||
}
|
||||
|
||||
jflags = 0;
|
||||
switch (*word)
|
||||
{
|
||||
case 0:
|
||||
case '%':
|
||||
case '+':
|
||||
return (js.j_current);
|
||||
|
||||
case '-':
|
||||
return (js.j_previous);
|
||||
|
||||
case '?': /* Substring search requested. */
|
||||
jflags |= JM_SUBSTRING;
|
||||
word++;
|
||||
/* FALLTHROUGH */
|
||||
|
||||
default:
|
||||
return get_job_by_name (word, jflags);
|
||||
}
|
||||
}
|
||||
#endif /* JOB_CONTROL */
|
||||
|
||||
/*
|
||||
* NOTE: `kill' calls this function with forcecols == 0
|
||||
*/
|
||||
int
|
||||
display_signal_list (list, forcecols)
|
||||
WORD_LIST *list;
|
||||
int forcecols;
|
||||
{
|
||||
register int i, column;
|
||||
char *name;
|
||||
int result, signum, dflags;
|
||||
intmax_t lsignum;
|
||||
|
||||
result = EXECUTION_SUCCESS;
|
||||
if (!list)
|
||||
{
|
||||
for (i = 1, column = 0; i < NSIG; i++)
|
||||
{
|
||||
name = signal_name (i);
|
||||
if (STREQN (name, "SIGJUNK", 7) || STREQN (name, "Unknown", 7))
|
||||
continue;
|
||||
|
||||
if (posixly_correct && !forcecols)
|
||||
{
|
||||
/* This is for the kill builtin. POSIX.2 says the signal names
|
||||
are displayed without the `SIG' prefix. */
|
||||
if (STREQN (name, "SIG", 3))
|
||||
name += 3;
|
||||
printf ("%s%s", name, (i == NSIG - 1) ? "" : " ");
|
||||
}
|
||||
else
|
||||
{
|
||||
printf ("%2d) %s", i, name);
|
||||
|
||||
if (++column < 5)
|
||||
printf ("\t");
|
||||
else
|
||||
{
|
||||
printf ("\n");
|
||||
column = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ((posixly_correct && !forcecols) || column != 0)
|
||||
printf ("\n");
|
||||
return result;
|
||||
}
|
||||
|
||||
/* List individual signal names or numbers. */
|
||||
while (list)
|
||||
{
|
||||
if (legal_number (list->word->word, &lsignum))
|
||||
{
|
||||
/* This is specified by Posix.2 so that exit statuses can be
|
||||
mapped into signal numbers. */
|
||||
if (lsignum > 128)
|
||||
lsignum -= 128;
|
||||
if (lsignum < 0 || lsignum >= NSIG)
|
||||
{
|
||||
sh_invalidsig (list->word->word);
|
||||
result = EXECUTION_FAILURE;
|
||||
list = list->next;
|
||||
continue;
|
||||
}
|
||||
|
||||
signum = lsignum;
|
||||
name = signal_name (signum);
|
||||
if (STREQN (name, "SIGJUNK", 7) || STREQN (name, "Unknown", 7))
|
||||
{
|
||||
list = list->next;
|
||||
continue;
|
||||
}
|
||||
#if defined (JOB_CONTROL)
|
||||
/* POSIX.2 says that `kill -l signum' prints the signal name without
|
||||
the `SIG' prefix. */
|
||||
printf ("%s\n", (this_shell_builtin == kill_builtin) ? name + 3 : name);
|
||||
#else
|
||||
printf ("%s\n", name);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
dflags = DSIG_NOCASE;
|
||||
if (posixly_correct == 0 || this_shell_builtin != kill_builtin)
|
||||
dflags |= DSIG_SIGPREFIX;
|
||||
signum = decode_signal (list->word->word, dflags);
|
||||
if (signum == NO_SIG)
|
||||
{
|
||||
sh_invalidsig (list->word->word);
|
||||
result = EXECUTION_FAILURE;
|
||||
list = list->next;
|
||||
continue;
|
||||
}
|
||||
printf ("%d\n", signum);
|
||||
}
|
||||
list = list->next;
|
||||
}
|
||||
return (result);
|
||||
}
|
||||
|
||||
/* **************************************************************** */
|
||||
/* */
|
||||
/* Finding builtin commands and their functions */
|
||||
/* */
|
||||
/* **************************************************************** */
|
||||
|
||||
/* Perform a binary search and return the address of the builtin function
|
||||
whose name is NAME. If the function couldn't be found, or the builtin
|
||||
is disabled or has no function associated with it, return NULL.
|
||||
Return the address of the builtin.
|
||||
DISABLED_OKAY means find it even if the builtin is disabled. */
|
||||
struct builtin *
|
||||
builtin_address_internal (name, disabled_okay)
|
||||
char *name;
|
||||
int disabled_okay;
|
||||
{
|
||||
int hi, lo, mid, j;
|
||||
|
||||
hi = num_shell_builtins - 1;
|
||||
lo = 0;
|
||||
|
||||
while (lo <= hi)
|
||||
{
|
||||
mid = (lo + hi) / 2;
|
||||
|
||||
j = shell_builtins[mid].name[0] - name[0];
|
||||
|
||||
if (j == 0)
|
||||
j = strcmp (shell_builtins[mid].name, name);
|
||||
|
||||
if (j == 0)
|
||||
{
|
||||
/* It must have a function pointer. It must be enabled, or we
|
||||
must have explicitly allowed disabled functions to be found,
|
||||
and it must not have been deleted. */
|
||||
if (shell_builtins[mid].function &&
|
||||
((shell_builtins[mid].flags & BUILTIN_DELETED) == 0) &&
|
||||
((shell_builtins[mid].flags & BUILTIN_ENABLED) || disabled_okay))
|
||||
return (&shell_builtins[mid]);
|
||||
else
|
||||
return ((struct builtin *)NULL);
|
||||
}
|
||||
if (j > 0)
|
||||
hi = mid - 1;
|
||||
else
|
||||
lo = mid + 1;
|
||||
}
|
||||
return ((struct builtin *)NULL);
|
||||
}
|
||||
|
||||
/* Return the pointer to the function implementing builtin command NAME. */
|
||||
sh_builtin_func_t *
|
||||
find_shell_builtin (name)
|
||||
char *name;
|
||||
{
|
||||
current_builtin = builtin_address_internal (name, 0);
|
||||
return (current_builtin ? current_builtin->function : (sh_builtin_func_t *)NULL);
|
||||
}
|
||||
|
||||
/* Return the address of builtin with NAME, whether it is enabled or not. */
|
||||
sh_builtin_func_t *
|
||||
builtin_address (name)
|
||||
char *name;
|
||||
{
|
||||
current_builtin = builtin_address_internal (name, 1);
|
||||
return (current_builtin ? current_builtin->function : (sh_builtin_func_t *)NULL);
|
||||
}
|
||||
|
||||
/* Return the function implementing the builtin NAME, but only if it is a
|
||||
POSIX.2 special builtin. */
|
||||
sh_builtin_func_t *
|
||||
find_special_builtin (name)
|
||||
char *name;
|
||||
{
|
||||
current_builtin = builtin_address_internal (name, 0);
|
||||
return ((current_builtin && (current_builtin->flags & SPECIAL_BUILTIN)) ?
|
||||
current_builtin->function :
|
||||
(sh_builtin_func_t *)NULL);
|
||||
}
|
||||
|
||||
static int
|
||||
shell_builtin_compare (sbp1, sbp2)
|
||||
struct builtin *sbp1, *sbp2;
|
||||
{
|
||||
int result;
|
||||
|
||||
if ((result = sbp1->name[0] - sbp2->name[0]) == 0)
|
||||
result = strcmp (sbp1->name, sbp2->name);
|
||||
|
||||
return (result);
|
||||
}
|
||||
|
||||
/* Sort the table of shell builtins so that the binary search will work
|
||||
in find_shell_builtin. */
|
||||
void
|
||||
initialize_shell_builtins ()
|
||||
{
|
||||
qsort (shell_builtins, num_shell_builtins, sizeof (struct builtin),
|
||||
(QSFUNC *)shell_builtin_compare);
|
||||
}
|
||||
@@ -1,174 +0,0 @@
|
||||
/* common.h -- extern declarations for functions defined in common.c. */
|
||||
|
||||
/* Copyright (C) 1993-2004 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Bash, the Bourne Again SHell.
|
||||
|
||||
Bash is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Bash is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Bash. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#if !defined (__COMMON_H)
|
||||
# define __COMMON_H
|
||||
|
||||
#include "stdc.h"
|
||||
|
||||
#define ISOPTION(s, c) (s[0] == '-' && !s[2] && s[1] == c)
|
||||
|
||||
/* Flag values for parse_and_execute () */
|
||||
#define SEVAL_NONINT 0x001
|
||||
#define SEVAL_INTERACT 0x002
|
||||
#define SEVAL_NOHIST 0x004
|
||||
#define SEVAL_NOFREE 0x008
|
||||
#define SEVAL_RESETLINE 0x010
|
||||
#define SEVAL_PARSEONLY 0x020
|
||||
#define SEVAL_NOLONGJMP 0x040
|
||||
|
||||
/* Flags for describe_command, shared between type.def and command.def */
|
||||
#define CDESC_ALL 0x001 /* type -a */
|
||||
#define CDESC_SHORTDESC 0x002 /* command -V */
|
||||
#define CDESC_REUSABLE 0x004 /* command -v */
|
||||
#define CDESC_TYPE 0x008 /* type -t */
|
||||
#define CDESC_PATH_ONLY 0x010 /* type -p */
|
||||
#define CDESC_FORCE_PATH 0x020 /* type -ap or type -P */
|
||||
#define CDESC_NOFUNCS 0x040 /* type -f */
|
||||
#define CDESC_ABSPATH 0x080 /* convert to absolute path, no ./ */
|
||||
|
||||
/* Flags for get_job_by_name */
|
||||
#define JM_PREFIX 0x01 /* prefix of job name */
|
||||
#define JM_SUBSTRING 0x02 /* substring of job name */
|
||||
#define JM_EXACT 0x04 /* match job name exactly */
|
||||
#define JM_STOPPED 0x08 /* match stopped jobs only */
|
||||
#define JM_FIRSTMATCH 0x10 /* return first matching job */
|
||||
|
||||
/* Flags for remember_args and value of changed_dollar_vars */
|
||||
#define ARGS_NONE 0x0
|
||||
#define ARGS_INVOC 0x01
|
||||
#define ARGS_FUNC 0x02
|
||||
#define ARGS_SETBLTIN 0x04
|
||||
|
||||
/* Functions from common.c */
|
||||
extern void builtin_error __P((const char *, ...)) __attribute__((__format__ (printf, 1, 2)));
|
||||
extern void builtin_warning __P((const char *, ...)) __attribute__((__format__ (printf, 1, 2)));
|
||||
extern void builtin_usage __P((void));
|
||||
extern void no_args __P((WORD_LIST *));
|
||||
extern int no_options __P((WORD_LIST *));
|
||||
|
||||
/* common error message functions */
|
||||
extern void sh_needarg __P((char *));
|
||||
extern void sh_neednumarg __P((char *));
|
||||
extern void sh_notfound __P((char *));
|
||||
extern void sh_invalidopt __P((char *));
|
||||
extern void sh_invalidoptname __P((char *));
|
||||
extern void sh_invalidid __P((char *));
|
||||
extern void sh_invalidnum __P((char *));
|
||||
extern void sh_invalidsig __P((char *));
|
||||
extern void sh_erange __P((char *, char *));
|
||||
extern void sh_badpid __P((char *));
|
||||
extern void sh_badjob __P((char *));
|
||||
extern void sh_readonly __P((const char *));
|
||||
extern void sh_nojobs __P((char *));
|
||||
extern void sh_restricted __P((char *));
|
||||
extern void sh_notbuiltin __P((char *));
|
||||
extern void sh_wrerror __P((void));
|
||||
extern void sh_ttyerror __P((int));
|
||||
extern int sh_chkwrite __P((int));
|
||||
|
||||
extern char **make_builtin_argv __P((WORD_LIST *, int *));
|
||||
extern void remember_args __P((WORD_LIST *, int));
|
||||
|
||||
extern int dollar_vars_changed __P((void));
|
||||
extern void set_dollar_vars_unchanged __P((void));
|
||||
extern void set_dollar_vars_changed __P((void));
|
||||
|
||||
extern int get_numeric_arg __P((WORD_LIST *, int, intmax_t *));
|
||||
extern int get_exitstat __P((WORD_LIST *));
|
||||
extern int read_octal __P((char *));
|
||||
|
||||
/* Keeps track of the current working directory. */
|
||||
extern char *the_current_working_directory;
|
||||
extern char *get_working_directory __P((char *));
|
||||
extern void set_working_directory __P((char *));
|
||||
|
||||
#if defined (JOB_CONTROL)
|
||||
extern int get_job_by_name __P((const char *, int));
|
||||
extern int get_job_spec __P((WORD_LIST *));
|
||||
#endif
|
||||
extern int display_signal_list __P((WORD_LIST *, int));
|
||||
|
||||
/* It's OK to declare a function as returning a Function * without
|
||||
providing a definition of what a `Function' is. */
|
||||
extern struct builtin *builtin_address_internal __P((char *, int));
|
||||
extern sh_builtin_func_t *find_shell_builtin __P((char *));
|
||||
extern sh_builtin_func_t *builtin_address __P((char *));
|
||||
extern sh_builtin_func_t *find_special_builtin __P((char *));
|
||||
extern void initialize_shell_builtins __P((void));
|
||||
|
||||
/* Functions from exit.def */
|
||||
extern void bash_logout __P((void));
|
||||
|
||||
/* Functions from getopts.def */
|
||||
extern void getopts_reset __P((int));
|
||||
|
||||
/* Functions from set.def */
|
||||
extern int minus_o_option_value __P((char *));
|
||||
extern void list_minus_o_opts __P((int, int));
|
||||
extern char **get_minus_o_opts __P((void));
|
||||
extern int set_minus_o_option __P((int, char *));
|
||||
|
||||
extern void set_shellopts __P((void));
|
||||
extern void parse_shellopts __P((char *));
|
||||
extern void initialize_shell_options __P((int));
|
||||
|
||||
extern void reset_shell_options __P((void));
|
||||
|
||||
/* Functions from shopt.def */
|
||||
extern void reset_shopt_options __P((void));
|
||||
extern char **get_shopt_options __P((void));
|
||||
|
||||
extern int shopt_setopt __P((char *, int));
|
||||
extern int shopt_listopt __P((char *, int));
|
||||
|
||||
extern int set_login_shell __P((char *, int));
|
||||
|
||||
extern void set_bashopts __P((void));
|
||||
extern void parse_bashopts __P((char *));
|
||||
extern void initialize_bashopts __P((int));
|
||||
|
||||
/* Functions from type.def */
|
||||
extern int describe_command __P((char *, int));
|
||||
|
||||
/* Functions from setattr.def */
|
||||
extern int set_or_show_attributes __P((WORD_LIST *, int, int));
|
||||
extern int show_all_var_attributes __P((int, int));
|
||||
extern int show_var_attributes __P((SHELL_VAR *, int, int));
|
||||
extern int show_name_attributes __P((char *, int));
|
||||
extern void set_var_attribute __P((char *, int, int));
|
||||
|
||||
/* Functions from pushd.def */
|
||||
extern char *get_dirstack_from_string __P((char *));
|
||||
extern char *get_dirstack_element __P((intmax_t, int));
|
||||
extern void set_dirstack_element __P((intmax_t, int, char *));
|
||||
extern WORD_LIST *get_directory_stack __P((int));
|
||||
|
||||
/* Functions from evalstring.c */
|
||||
extern int parse_and_execute __P((char *, const char *, int));
|
||||
extern void parse_and_execute_cleanup __P((void));
|
||||
extern int parse_string __P((char *, const char *, int, char **));
|
||||
|
||||
/* Functions from evalfile.c */
|
||||
extern int maybe_execute_file __P((const char *, int));
|
||||
extern int source_file __P((const char *, int));
|
||||
extern int fc_execute_file __P((const char *));
|
||||
|
||||
#endif /* !__COMMON_H */
|
||||
@@ -1,869 +0,0 @@
|
||||
This file is complete.def, from which is created complete.c.
|
||||
It implements the builtins "complete", "compgen", and "compopt" in Bash.
|
||||
|
||||
Copyright (C) 1999-2009 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Bash, the Bourne Again SHell.
|
||||
|
||||
Bash is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Bash is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Bash. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
$PRODUCES complete.c
|
||||
|
||||
$BUILTIN complete
|
||||
$DEPENDS_ON PROGRAMMABLE_COMPLETION
|
||||
$FUNCTION complete_builtin
|
||||
$SHORT_DOC complete [-abcdefgjksuv] [-pr] [-DE] [-o option] [-A action] [-G globpat] [-W wordlist] [-F function] [-C command] [-X filterpat] [-P prefix] [-S suffix] [name ...]
|
||||
Specify how arguments are to be completed by Readline.
|
||||
|
||||
For each NAME, specify how arguments are to be completed. If no options
|
||||
are supplied, existing completion specifications are printed in a way that
|
||||
allows them to be reused as input.
|
||||
|
||||
Options:
|
||||
-p print existing completion specifications in a reusable format
|
||||
-r remove a completion specification for each NAME, or, if no
|
||||
NAMEs are supplied, all completion specifications
|
||||
-D apply the completions and actions as the default for commands
|
||||
without any specific completion defined
|
||||
-E apply the completions and actions to "empty" commands --
|
||||
completion attempted on a blank line
|
||||
|
||||
When completion is attempted, the actions are applied in the order the
|
||||
uppercase-letter options are listed above. The -D option takes
|
||||
precedence over -E.
|
||||
|
||||
Exit Status:
|
||||
Returns success unless an invalid option is supplied or an error occurs.
|
||||
$END
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "../bashtypes.h"
|
||||
|
||||
#if defined (HAVE_UNISTD_H)
|
||||
# include <unistd.h>
|
||||
#endif
|
||||
|
||||
#include "../bashansi.h"
|
||||
#include "../bashintl.h"
|
||||
|
||||
#include "../shell.h"
|
||||
#include "../builtins.h"
|
||||
#include "../pcomplete.h"
|
||||
#include "../bashline.h"
|
||||
|
||||
#include "common.h"
|
||||
#include "bashgetopt.h"
|
||||
|
||||
#include <readline/readline.h>
|
||||
|
||||
#define STRDUP(x) ((x) ? savestring (x) : (char *)NULL)
|
||||
|
||||
/* Structure containing all the non-action (binary) options; filled in by
|
||||
build_actions(). */
|
||||
struct _optflags {
|
||||
int pflag;
|
||||
int rflag;
|
||||
int Dflag;
|
||||
int Eflag;
|
||||
};
|
||||
|
||||
static int find_compact __P((char *));
|
||||
static int find_compopt __P((char *));
|
||||
|
||||
static int build_actions __P((WORD_LIST *, struct _optflags *, unsigned long *, unsigned long *));
|
||||
|
||||
static int remove_cmd_completions __P((WORD_LIST *));
|
||||
|
||||
static int print_one_completion __P((char *, COMPSPEC *));
|
||||
static int print_compitem __P((BUCKET_CONTENTS *));
|
||||
static void print_compopts __P((const char *, COMPSPEC *, int));
|
||||
static void print_all_completions __P((void));
|
||||
static int print_cmd_completions __P((WORD_LIST *));
|
||||
|
||||
static char *Garg, *Warg, *Parg, *Sarg, *Xarg, *Farg, *Carg;
|
||||
|
||||
static const struct _compacts {
|
||||
const char * const actname;
|
||||
int actflag;
|
||||
int actopt;
|
||||
} compacts[] = {
|
||||
{ "alias", CA_ALIAS, 'a' },
|
||||
{ "arrayvar", CA_ARRAYVAR, 0 },
|
||||
{ "binding", CA_BINDING, 0 },
|
||||
{ "builtin", CA_BUILTIN, 'b' },
|
||||
{ "command", CA_COMMAND, 'c' },
|
||||
{ "directory", CA_DIRECTORY, 'd' },
|
||||
{ "disabled", CA_DISABLED, 0 },
|
||||
{ "enabled", CA_ENABLED, 0 },
|
||||
{ "export", CA_EXPORT, 'e' },
|
||||
{ "file", CA_FILE, 'f' },
|
||||
{ "function", CA_FUNCTION, 0 },
|
||||
{ "helptopic", CA_BUILTIN, 0 }, /* for now */
|
||||
{ "hostname", CA_HOSTNAME, 0 },
|
||||
{ "group", CA_GROUP, 'g' },
|
||||
{ "job", CA_JOB, 'j' },
|
||||
{ "keyword", CA_KEYWORD, 'k' },
|
||||
{ "running", CA_RUNNING, 0 },
|
||||
{ "service", CA_SERVICE, 's' },
|
||||
{ "setopt", CA_SETOPT, 0 },
|
||||
{ "shopt", CA_SHOPT, 0 },
|
||||
{ "signal", CA_SIGNAL, 0 },
|
||||
{ "stopped", CA_STOPPED, 0 },
|
||||
{ "user", CA_USER, 'u' },
|
||||
{ "variable", CA_VARIABLE, 'v' },
|
||||
{ (char *)NULL, 0, 0 },
|
||||
};
|
||||
|
||||
/* This should be a STRING_INT_ALIST */
|
||||
const static struct _compopt {
|
||||
const char * const optname;
|
||||
int optflag;
|
||||
} compopts[] = {
|
||||
{ "bashdefault", COPT_BASHDEFAULT },
|
||||
{ "default", COPT_DEFAULT },
|
||||
{ "dirnames", COPT_DIRNAMES },
|
||||
{ "filenames",COPT_FILENAMES},
|
||||
{ "nospace", COPT_NOSPACE },
|
||||
{ "plusdirs", COPT_PLUSDIRS },
|
||||
{ (char *)NULL, 0 },
|
||||
};
|
||||
|
||||
static int
|
||||
find_compact (name)
|
||||
char *name;
|
||||
{
|
||||
register int i;
|
||||
|
||||
for (i = 0; compacts[i].actname; i++)
|
||||
if (STREQ (name, compacts[i].actname))
|
||||
return i;
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int
|
||||
find_compopt (name)
|
||||
char *name;
|
||||
{
|
||||
register int i;
|
||||
|
||||
for (i = 0; compopts[i].optname; i++)
|
||||
if (STREQ (name, compopts[i].optname))
|
||||
return i;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Build the actions and compspec options from the options specified in LIST.
|
||||
ACTP is a pointer to an unsigned long in which to place the bitmap of
|
||||
actions. OPTP is a pointer to an unsigned long in which to place the
|
||||
btmap of compspec options (arguments to `-o'). PP, if non-null, gets 1
|
||||
if -p is supplied; RP, if non-null, gets 1 if -r is supplied.
|
||||
If either is null, the corresponding option generates an error.
|
||||
This also sets variables corresponding to options that take arguments as
|
||||
a side effect; the caller should ensure that those variables are set to
|
||||
NULL before calling build_actions. Return value:
|
||||
EX_USAGE = bad option
|
||||
EXECUTION_SUCCESS = some options supplied
|
||||
EXECUTION_FAILURE = no options supplied
|
||||
*/
|
||||
|
||||
static int
|
||||
build_actions (list, flagp, actp, optp)
|
||||
WORD_LIST *list;
|
||||
struct _optflags *flagp;
|
||||
unsigned long *actp, *optp;
|
||||
{
|
||||
int opt, ind, opt_given;
|
||||
unsigned long acts, copts;
|
||||
|
||||
acts = copts = (unsigned long)0L;
|
||||
opt_given = 0;
|
||||
|
||||
reset_internal_getopt ();
|
||||
while ((opt = internal_getopt (list, "abcdefgjko:prsuvA:G:W:P:S:X:F:C:DE")) != -1)
|
||||
{
|
||||
opt_given = 1;
|
||||
switch (opt)
|
||||
{
|
||||
case 'r':
|
||||
if (flagp)
|
||||
{
|
||||
flagp->rflag = 1;
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
sh_invalidopt ("-r");
|
||||
builtin_usage ();
|
||||
return (EX_USAGE);
|
||||
}
|
||||
|
||||
case 'p':
|
||||
if (flagp)
|
||||
{
|
||||
flagp->pflag = 1;
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
sh_invalidopt ("-p");
|
||||
builtin_usage ();
|
||||
return (EX_USAGE);
|
||||
}
|
||||
|
||||
case 'a':
|
||||
acts |= CA_ALIAS;
|
||||
break;
|
||||
case 'b':
|
||||
acts |= CA_BUILTIN;
|
||||
break;
|
||||
case 'c':
|
||||
acts |= CA_COMMAND;
|
||||
break;
|
||||
case 'd':
|
||||
acts |= CA_DIRECTORY;
|
||||
break;
|
||||
case 'e':
|
||||
acts |= CA_EXPORT;
|
||||
break;
|
||||
case 'f':
|
||||
acts |= CA_FILE;
|
||||
break;
|
||||
case 'g':
|
||||
acts |= CA_GROUP;
|
||||
break;
|
||||
case 'j':
|
||||
acts |= CA_JOB;
|
||||
break;
|
||||
case 'k':
|
||||
acts |= CA_KEYWORD;
|
||||
break;
|
||||
case 's':
|
||||
acts |= CA_SERVICE;
|
||||
break;
|
||||
case 'u':
|
||||
acts |= CA_USER;
|
||||
break;
|
||||
case 'v':
|
||||
acts |= CA_VARIABLE;
|
||||
break;
|
||||
case 'o':
|
||||
ind = find_compopt (list_optarg);
|
||||
if (ind < 0)
|
||||
{
|
||||
sh_invalidoptname (list_optarg);
|
||||
return (EX_USAGE);
|
||||
}
|
||||
copts |= compopts[ind].optflag;
|
||||
break;
|
||||
case 'A':
|
||||
ind = find_compact (list_optarg);
|
||||
if (ind < 0)
|
||||
{
|
||||
builtin_error (_("%s: invalid action name"), list_optarg);
|
||||
return (EX_USAGE);
|
||||
}
|
||||
acts |= compacts[ind].actflag;
|
||||
break;
|
||||
case 'C':
|
||||
Carg = list_optarg;
|
||||
break;
|
||||
case 'D':
|
||||
if (flagp)
|
||||
{
|
||||
flagp->Dflag = 1;
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
sh_invalidopt ("-D");
|
||||
builtin_usage ();
|
||||
return (EX_USAGE);
|
||||
}
|
||||
case 'E':
|
||||
if (flagp)
|
||||
{
|
||||
flagp->Eflag = 1;
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
sh_invalidopt ("-E");
|
||||
builtin_usage ();
|
||||
return (EX_USAGE);
|
||||
}
|
||||
case 'F':
|
||||
Farg = list_optarg;
|
||||
break;
|
||||
case 'G':
|
||||
Garg = list_optarg;
|
||||
break;
|
||||
case 'P':
|
||||
Parg = list_optarg;
|
||||
break;
|
||||
case 'S':
|
||||
Sarg = list_optarg;
|
||||
break;
|
||||
case 'W':
|
||||
Warg = list_optarg;
|
||||
break;
|
||||
case 'X':
|
||||
Xarg = list_optarg;
|
||||
break;
|
||||
default:
|
||||
builtin_usage ();
|
||||
return (EX_USAGE);
|
||||
}
|
||||
}
|
||||
|
||||
*actp = acts;
|
||||
*optp = copts;
|
||||
|
||||
return (opt_given ? EXECUTION_SUCCESS : EXECUTION_FAILURE);
|
||||
}
|
||||
|
||||
/* Add, remove, and display completion specifiers. */
|
||||
int
|
||||
complete_builtin (list)
|
||||
WORD_LIST *list;
|
||||
{
|
||||
int opt_given, rval;
|
||||
unsigned long acts, copts;
|
||||
COMPSPEC *cs;
|
||||
struct _optflags oflags;
|
||||
WORD_LIST *l, *wl;
|
||||
|
||||
if (list == 0)
|
||||
{
|
||||
print_all_completions ();
|
||||
return (EXECUTION_SUCCESS);
|
||||
}
|
||||
|
||||
opt_given = oflags.pflag = oflags.rflag = oflags.Dflag = oflags.Eflag = 0;
|
||||
|
||||
acts = copts = (unsigned long)0L;
|
||||
Garg = Warg = Parg = Sarg = Xarg = Farg = Carg = (char *)NULL;
|
||||
cs = (COMPSPEC *)NULL;
|
||||
|
||||
/* Build the actions from the arguments. Also sets the [A-Z]arg variables
|
||||
as a side effect if they are supplied as options. */
|
||||
rval = build_actions (list, &oflags, &acts, &copts);
|
||||
if (rval == EX_USAGE)
|
||||
return (rval);
|
||||
opt_given = rval != EXECUTION_FAILURE;
|
||||
|
||||
list = loptend;
|
||||
|
||||
wl = oflags.Dflag ? make_word_list (make_bare_word (DEFAULTCMD), (WORD_LIST *)NULL)
|
||||
: (oflags.Eflag ? make_word_list (make_bare_word (EMPTYCMD), (WORD_LIST *)NULL) : 0);
|
||||
|
||||
/* -p overrides everything else */
|
||||
if (oflags.pflag || (list == 0 && opt_given == 0))
|
||||
{
|
||||
if (wl)
|
||||
{
|
||||
rval = print_cmd_completions (wl);
|
||||
dispose_words (wl);
|
||||
return rval;
|
||||
}
|
||||
else if (list == 0)
|
||||
{
|
||||
print_all_completions ();
|
||||
return (EXECUTION_SUCCESS);
|
||||
}
|
||||
return (print_cmd_completions (list));
|
||||
}
|
||||
|
||||
/* next, -r overrides everything else. */
|
||||
if (oflags.rflag)
|
||||
{
|
||||
if (wl)
|
||||
{
|
||||
rval = remove_cmd_completions (wl);
|
||||
dispose_words (wl);
|
||||
return rval;
|
||||
}
|
||||
else if (list == 0)
|
||||
{
|
||||
progcomp_flush ();
|
||||
return (EXECUTION_SUCCESS);
|
||||
}
|
||||
return (remove_cmd_completions (list));
|
||||
}
|
||||
|
||||
if (wl == 0 && list == 0 && opt_given)
|
||||
{
|
||||
builtin_usage ();
|
||||
return (EX_USAGE);
|
||||
}
|
||||
|
||||
/* If we get here, we need to build a compspec and add it for each
|
||||
remaining argument. */
|
||||
cs = compspec_create ();
|
||||
cs->actions = acts;
|
||||
cs->options = copts;
|
||||
|
||||
cs->globpat = STRDUP (Garg);
|
||||
cs->words = STRDUP (Warg);
|
||||
cs->prefix = STRDUP (Parg);
|
||||
cs->suffix = STRDUP (Sarg);
|
||||
cs->funcname = STRDUP (Farg);
|
||||
cs->command = STRDUP (Carg);
|
||||
cs->filterpat = STRDUP (Xarg);
|
||||
|
||||
for (rval = EXECUTION_SUCCESS, l = wl ? wl : list ; l; l = l->next)
|
||||
{
|
||||
/* Add CS as the compspec for the specified commands. */
|
||||
if (progcomp_insert (l->word->word, cs) == 0)
|
||||
rval = EXECUTION_FAILURE;
|
||||
}
|
||||
|
||||
dispose_words (wl);
|
||||
return (rval);
|
||||
}
|
||||
|
||||
static int
|
||||
remove_cmd_completions (list)
|
||||
WORD_LIST *list;
|
||||
{
|
||||
WORD_LIST *l;
|
||||
int ret;
|
||||
|
||||
for (ret = EXECUTION_SUCCESS, l = list; l; l = l->next)
|
||||
{
|
||||
if (progcomp_remove (l->word->word) == 0)
|
||||
{
|
||||
builtin_error (_("%s: no completion specification"), l->word->word);
|
||||
ret = EXECUTION_FAILURE;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
#define SQPRINTARG(a, f) \
|
||||
do { \
|
||||
if (a) \
|
||||
{ \
|
||||
x = sh_single_quote (a); \
|
||||
printf ("%s %s ", f, x); \
|
||||
free (x); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define PRINTARG(a, f) \
|
||||
do { \
|
||||
if (a) \
|
||||
printf ("%s %s ", f, a); \
|
||||
} while (0)
|
||||
|
||||
#define PRINTOPT(a, f) \
|
||||
do { \
|
||||
if (acts & a) \
|
||||
printf ("%s ", f); \
|
||||
} while (0)
|
||||
|
||||
#define PRINTACT(a, f) \
|
||||
do { \
|
||||
if (acts & a) \
|
||||
printf ("-A %s ", f); \
|
||||
} while (0)
|
||||
|
||||
#define PRINTCOMPOPT(a, f) \
|
||||
do { \
|
||||
if (copts & a) \
|
||||
printf ("-o %s ", f); \
|
||||
} while (0)
|
||||
|
||||
#define XPRINTCOMPOPT(a, f) \
|
||||
do { \
|
||||
if (copts & a) \
|
||||
printf ("-o %s ", f); \
|
||||
else \
|
||||
printf ("+o %s ", f); \
|
||||
} while (0)
|
||||
|
||||
static int
|
||||
print_one_completion (cmd, cs)
|
||||
char *cmd;
|
||||
COMPSPEC *cs;
|
||||
{
|
||||
unsigned long acts, copts;
|
||||
char *x;
|
||||
|
||||
printf ("complete ");
|
||||
|
||||
copts = cs->options;
|
||||
|
||||
/* First, print the -o options. */
|
||||
PRINTCOMPOPT (COPT_BASHDEFAULT, "bashdefault");
|
||||
PRINTCOMPOPT (COPT_DEFAULT, "default");
|
||||
PRINTCOMPOPT (COPT_DIRNAMES, "dirnames");
|
||||
PRINTCOMPOPT (COPT_FILENAMES, "filenames");
|
||||
PRINTCOMPOPT (COPT_NOSPACE, "nospace");
|
||||
PRINTCOMPOPT (COPT_PLUSDIRS, "plusdirs");
|
||||
|
||||
acts = cs->actions;
|
||||
|
||||
/* simple flags next */
|
||||
PRINTOPT (CA_ALIAS, "-a");
|
||||
PRINTOPT (CA_BUILTIN, "-b");
|
||||
PRINTOPT (CA_COMMAND, "-c");
|
||||
PRINTOPT (CA_DIRECTORY, "-d");
|
||||
PRINTOPT (CA_EXPORT, "-e");
|
||||
PRINTOPT (CA_FILE, "-f");
|
||||
PRINTOPT (CA_GROUP, "-g");
|
||||
PRINTOPT (CA_JOB, "-j");
|
||||
PRINTOPT (CA_KEYWORD, "-k");
|
||||
PRINTOPT (CA_SERVICE, "-s");
|
||||
PRINTOPT (CA_USER, "-u");
|
||||
PRINTOPT (CA_VARIABLE, "-v");
|
||||
|
||||
/* now the rest of the actions */
|
||||
PRINTACT (CA_ARRAYVAR, "arrayvar");
|
||||
PRINTACT (CA_BINDING, "binding");
|
||||
PRINTACT (CA_DISABLED, "disabled");
|
||||
PRINTACT (CA_ENABLED, "enabled");
|
||||
PRINTACT (CA_FUNCTION, "function");
|
||||
PRINTACT (CA_HELPTOPIC, "helptopic");
|
||||
PRINTACT (CA_HOSTNAME, "hostname");
|
||||
PRINTACT (CA_RUNNING, "running");
|
||||
PRINTACT (CA_SETOPT, "setopt");
|
||||
PRINTACT (CA_SHOPT, "shopt");
|
||||
PRINTACT (CA_SIGNAL, "signal");
|
||||
PRINTACT (CA_STOPPED, "stopped");
|
||||
|
||||
/* now the rest of the arguments */
|
||||
|
||||
/* arguments that require quoting */
|
||||
SQPRINTARG (cs->globpat, "-G");
|
||||
SQPRINTARG (cs->words, "-W");
|
||||
SQPRINTARG (cs->prefix, "-P");
|
||||
SQPRINTARG (cs->suffix, "-S");
|
||||
SQPRINTARG (cs->filterpat, "-X");
|
||||
|
||||
SQPRINTARG (cs->command, "-C");
|
||||
|
||||
/* simple arguments that don't require quoting */
|
||||
PRINTARG (cs->funcname, "-F");
|
||||
|
||||
if (STREQ (cmd, EMPTYCMD))
|
||||
printf ("-E\n");
|
||||
else if (STREQ (cmd, DEFAULTCMD))
|
||||
printf ("-D\n");
|
||||
else
|
||||
printf ("%s\n", cmd);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static void
|
||||
print_compopts (cmd, cs, full)
|
||||
const char *cmd;
|
||||
COMPSPEC *cs;
|
||||
int full;
|
||||
{
|
||||
int copts;
|
||||
|
||||
printf ("compopt ");
|
||||
copts = cs->options;
|
||||
|
||||
if (full)
|
||||
{
|
||||
XPRINTCOMPOPT (COPT_BASHDEFAULT, "bashdefault");
|
||||
XPRINTCOMPOPT (COPT_DEFAULT, "default");
|
||||
XPRINTCOMPOPT (COPT_DIRNAMES, "dirnames");
|
||||
XPRINTCOMPOPT (COPT_FILENAMES, "filenames");
|
||||
XPRINTCOMPOPT (COPT_NOSPACE, "nospace");
|
||||
XPRINTCOMPOPT (COPT_PLUSDIRS, "plusdirs");
|
||||
}
|
||||
else
|
||||
{
|
||||
PRINTCOMPOPT (COPT_BASHDEFAULT, "bashdefault");
|
||||
PRINTCOMPOPT (COPT_DEFAULT, "default");
|
||||
PRINTCOMPOPT (COPT_DIRNAMES, "dirnames");
|
||||
PRINTCOMPOPT (COPT_FILENAMES, "filenames");
|
||||
PRINTCOMPOPT (COPT_NOSPACE, "nospace");
|
||||
PRINTCOMPOPT (COPT_PLUSDIRS, "plusdirs");
|
||||
}
|
||||
|
||||
if (STREQ (cmd, EMPTYCMD))
|
||||
printf ("-E\n");
|
||||
else if (STREQ (cmd, DEFAULTCMD))
|
||||
printf ("-D\n");
|
||||
else
|
||||
printf ("%s\n", cmd);
|
||||
}
|
||||
|
||||
static int
|
||||
print_compitem (item)
|
||||
BUCKET_CONTENTS *item;
|
||||
{
|
||||
COMPSPEC *cs;
|
||||
char *cmd;
|
||||
|
||||
cmd = item->key;
|
||||
cs = (COMPSPEC *)item->data;
|
||||
|
||||
return (print_one_completion (cmd, cs));
|
||||
}
|
||||
|
||||
static void
|
||||
print_all_completions ()
|
||||
{
|
||||
progcomp_walk (print_compitem);
|
||||
}
|
||||
|
||||
static int
|
||||
print_cmd_completions (list)
|
||||
WORD_LIST *list;
|
||||
{
|
||||
WORD_LIST *l;
|
||||
COMPSPEC *cs;
|
||||
int ret;
|
||||
|
||||
for (ret = EXECUTION_SUCCESS, l = list; l; l = l->next)
|
||||
{
|
||||
cs = progcomp_search (l->word->word);
|
||||
if (cs)
|
||||
print_one_completion (l->word->word, cs);
|
||||
else
|
||||
{
|
||||
builtin_error (_("%s: no completion specification"), l->word->word);
|
||||
ret = EXECUTION_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
return (sh_chkwrite (ret));
|
||||
}
|
||||
|
||||
$BUILTIN compgen
|
||||
$DEPENDS_ON PROGRAMMABLE_COMPLETION
|
||||
$FUNCTION compgen_builtin
|
||||
$SHORT_DOC compgen [-abcdefgjksuv] [-o option] [-A action] [-G globpat] [-W wordlist] [-F function] [-C command] [-X filterpat] [-P prefix] [-S suffix] [word]
|
||||
Display possible completions depending on the options.
|
||||
|
||||
Intended to be used from within a shell function generating possible
|
||||
completions. If the optional WORD argument is supplied, matches against
|
||||
WORD are generated.
|
||||
|
||||
Exit Status:
|
||||
Returns success unless an invalid option is supplied or an error occurs.
|
||||
$END
|
||||
|
||||
int
|
||||
compgen_builtin (list)
|
||||
WORD_LIST *list;
|
||||
{
|
||||
int rval;
|
||||
unsigned long acts, copts;
|
||||
COMPSPEC *cs;
|
||||
STRINGLIST *sl;
|
||||
char *word, **matches;
|
||||
|
||||
if (list == 0)
|
||||
return (EXECUTION_SUCCESS);
|
||||
|
||||
acts = copts = (unsigned long)0L;
|
||||
Garg = Warg = Parg = Sarg = Xarg = Farg = Carg = (char *)NULL;
|
||||
cs = (COMPSPEC *)NULL;
|
||||
|
||||
/* Build the actions from the arguments. Also sets the [A-Z]arg variables
|
||||
as a side effect if they are supplied as options. */
|
||||
rval = build_actions (list, (struct _optflags *)NULL, &acts, &copts);
|
||||
if (rval == EX_USAGE)
|
||||
return (rval);
|
||||
if (rval == EXECUTION_FAILURE)
|
||||
return (EXECUTION_SUCCESS);
|
||||
|
||||
list = loptend;
|
||||
|
||||
word = (list && list->word) ? list->word->word : "";
|
||||
|
||||
if (Farg)
|
||||
builtin_error (_("warning: -F option may not work as you expect"));
|
||||
if (Carg)
|
||||
builtin_error (_("warning: -C option may not work as you expect"));
|
||||
|
||||
/* If we get here, we need to build a compspec and evaluate it. */
|
||||
cs = compspec_create ();
|
||||
cs->actions = acts;
|
||||
cs->options = copts;
|
||||
cs->refcount = 1;
|
||||
|
||||
cs->globpat = STRDUP (Garg);
|
||||
cs->words = STRDUP (Warg);
|
||||
cs->prefix = STRDUP (Parg);
|
||||
cs->suffix = STRDUP (Sarg);
|
||||
cs->funcname = STRDUP (Farg);
|
||||
cs->command = STRDUP (Carg);
|
||||
cs->filterpat = STRDUP (Xarg);
|
||||
|
||||
rval = EXECUTION_FAILURE;
|
||||
sl = gen_compspec_completions (cs, "compgen", word, 0, 0, 0);
|
||||
|
||||
/* If the compspec wants the bash default completions, temporarily
|
||||
turn off programmable completion and call the bash completion code. */
|
||||
if ((sl == 0 || sl->list_len == 0) && (copts & COPT_BASHDEFAULT))
|
||||
{
|
||||
matches = bash_default_completion (word, 0, 0, 0, 0);
|
||||
sl = completions_to_stringlist (matches);
|
||||
strvec_dispose (matches);
|
||||
}
|
||||
|
||||
/* This isn't perfect, but it's the best we can do, given what readline
|
||||
exports from its set of completion utility functions. */
|
||||
if ((sl == 0 || sl->list_len == 0) && (copts & COPT_DEFAULT))
|
||||
{
|
||||
matches = rl_completion_matches (word, rl_filename_completion_function);
|
||||
sl = completions_to_stringlist (matches);
|
||||
strvec_dispose (matches);
|
||||
}
|
||||
|
||||
if (sl)
|
||||
{
|
||||
if (sl->list && sl->list_len)
|
||||
{
|
||||
rval = EXECUTION_SUCCESS;
|
||||
strlist_print (sl, (char *)NULL);
|
||||
}
|
||||
strlist_dispose (sl);
|
||||
}
|
||||
|
||||
compspec_dispose (cs);
|
||||
return (rval);
|
||||
}
|
||||
|
||||
$BUILTIN compopt
|
||||
$DEPENDS_ON PROGRAMMABLE_COMPLETION
|
||||
$FUNCTION compopt_builtin
|
||||
$SHORT_DOC compopt [-o|+o option] [-DE] [name ...]
|
||||
Modify or display completion options.
|
||||
|
||||
Modify the completion options for each NAME, or, if no NAMEs are supplied,
|
||||
the completion currently being executed. If no OPTIONs are given, print
|
||||
the completion options for each NAME or the current completion specification.
|
||||
|
||||
Options:
|
||||
-o option Set completion option OPTION for each NAME
|
||||
-D Change options for the "default" command completion
|
||||
-E Change options for the "empty" command completion
|
||||
|
||||
Using `+o' instead of `-o' turns off the specified option.
|
||||
|
||||
Arguments:
|
||||
|
||||
Each NAME refers to a command for which a completion specification must
|
||||
have previously been defined using the `complete' builtin. If no NAMEs
|
||||
are supplied, compopt must be called by a function currently generating
|
||||
completions, and the options for that currently-executing completion
|
||||
generator are modified.
|
||||
|
||||
Exit Status:
|
||||
Returns success unless an invalid option is supplied or NAME does not
|
||||
have a completion specification defined.
|
||||
$END
|
||||
|
||||
int
|
||||
compopt_builtin (list)
|
||||
WORD_LIST *list;
|
||||
{
|
||||
int opts_on, opts_off, *opts, opt, oind, ret, Dflag, Eflag;
|
||||
WORD_LIST *l, *wl;
|
||||
COMPSPEC *cs;
|
||||
|
||||
opts_on = opts_off = Eflag = Dflag = 0;
|
||||
ret = EXECUTION_SUCCESS;
|
||||
|
||||
reset_internal_getopt ();
|
||||
while ((opt = internal_getopt (list, "+o:DE")) != EOF)
|
||||
{
|
||||
opts = (list_opttype == '-') ? &opts_on : &opts_off;
|
||||
|
||||
switch (opt)
|
||||
{
|
||||
case 'o':
|
||||
oind = find_compopt (list_optarg);
|
||||
if (oind < 0)
|
||||
{
|
||||
sh_invalidoptname (list_optarg);
|
||||
return (EX_USAGE);
|
||||
}
|
||||
*opts |= compopts[oind].optflag;
|
||||
break;
|
||||
case 'D':
|
||||
Dflag = 1;
|
||||
break;
|
||||
case 'E':
|
||||
Eflag = 1;
|
||||
break;
|
||||
default:
|
||||
builtin_usage ();
|
||||
return (EX_USAGE);
|
||||
}
|
||||
}
|
||||
list = loptend;
|
||||
|
||||
wl = Dflag ? make_word_list (make_bare_word (DEFAULTCMD), (WORD_LIST *)NULL)
|
||||
: (Eflag ? make_word_list (make_bare_word (EMPTYCMD), (WORD_LIST *)NULL) : 0);
|
||||
|
||||
if (list == 0 && wl == 0)
|
||||
{
|
||||
if (RL_ISSTATE (RL_STATE_COMPLETING) == 0 || pcomp_curcs == 0)
|
||||
{
|
||||
builtin_error (_("not currently executing completion function"));
|
||||
return (EXECUTION_FAILURE);
|
||||
}
|
||||
cs = pcomp_curcs;
|
||||
|
||||
if (opts_on == 0 && opts_off == 0)
|
||||
{
|
||||
print_compopts (pcomp_curcmd, cs, 1);
|
||||
return (sh_chkwrite (ret));
|
||||
}
|
||||
|
||||
/* Set the compspec options */
|
||||
pcomp_set_compspec_options (cs, opts_on, 1);
|
||||
pcomp_set_compspec_options (cs, opts_off, 0);
|
||||
|
||||
/* And change the readline variables the options control */
|
||||
pcomp_set_readline_variables (opts_on, 1);
|
||||
pcomp_set_readline_variables (opts_off, 0);
|
||||
|
||||
return (ret);
|
||||
}
|
||||
|
||||
for (l = wl ? wl : list; l; l = l->next)
|
||||
{
|
||||
cs = progcomp_search (l->word->word);
|
||||
if (cs == 0)
|
||||
{
|
||||
builtin_error (_("%s: no completion specification"), l->word->word);
|
||||
ret = EXECUTION_FAILURE;
|
||||
continue;
|
||||
}
|
||||
if (opts_on == 0 && opts_off == 0)
|
||||
{
|
||||
print_compopts (l->word->word, cs, 1);
|
||||
continue; /* XXX -- fill in later */
|
||||
}
|
||||
|
||||
/* Set the compspec options */
|
||||
pcomp_set_compspec_options (cs, opts_on, 1);
|
||||
pcomp_set_compspec_options (cs, opts_off, 0);
|
||||
}
|
||||
|
||||
return (ret);
|
||||
}
|
||||
@@ -1,568 +0,0 @@
|
||||
This file is declare.def, from which is created declare.c.
|
||||
It implements the builtins "declare" and "local" in Bash.
|
||||
|
||||
Copyright (C) 1987-2010 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Bash, the Bourne Again SHell.
|
||||
|
||||
Bash is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Bash is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Bash. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
$PRODUCES declare.c
|
||||
|
||||
$BUILTIN declare
|
||||
$FUNCTION declare_builtin
|
||||
$SHORT_DOC declare [-aAfFgilrtux] [-p] [name[=value] ...]
|
||||
Set variable values and attributes.
|
||||
|
||||
Declare variables and give them attributes. If no NAMEs are given,
|
||||
display the attributes and values of all variables.
|
||||
|
||||
Options:
|
||||
-f restrict action or display to function names and definitions
|
||||
-F restrict display to function names only (plus line number and
|
||||
source file when debugging)
|
||||
-g create global variables when used in a shell function; otherwise
|
||||
ignored
|
||||
-p display the attributes and value of each NAME
|
||||
|
||||
Options which set attributes:
|
||||
-a to make NAMEs indexed arrays (if supported)
|
||||
-A to make NAMEs associative arrays (if supported)
|
||||
-i to make NAMEs have the `integer' attribute
|
||||
-l to convert NAMEs to lower case on assignment
|
||||
-r to make NAMEs readonly
|
||||
-t to make NAMEs have the `trace' attribute
|
||||
-u to convert NAMEs to upper case on assignment
|
||||
-x to make NAMEs export
|
||||
|
||||
Using `+' instead of `-' turns off the given attribute.
|
||||
|
||||
Variables with the integer attribute have arithmetic evaluation (see
|
||||
the `let' command) performed when the variable is assigned a value.
|
||||
|
||||
When used in a function, `declare' makes NAMEs local, as with the `local'
|
||||
command. The `-g' option suppresses this behavior.
|
||||
|
||||
Exit Status:
|
||||
Returns success unless an invalid option is supplied or an error occurs.
|
||||
$END
|
||||
|
||||
$BUILTIN typeset
|
||||
$FUNCTION declare_builtin
|
||||
$SHORT_DOC typeset [-aAfFgilrtux] [-p] name[=value] ...
|
||||
Set variable values and attributes.
|
||||
|
||||
Obsolete. See `help declare'.
|
||||
$END
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#if defined (HAVE_UNISTD_H)
|
||||
# ifdef _MINIX
|
||||
# include <sys/types.h>
|
||||
# endif
|
||||
# include <unistd.h>
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "../bashansi.h"
|
||||
#include "../bashintl.h"
|
||||
|
||||
#include "../shell.h"
|
||||
#include "common.h"
|
||||
#include "builtext.h"
|
||||
#include "bashgetopt.h"
|
||||
|
||||
extern int array_needs_making;
|
||||
extern int posixly_correct;
|
||||
|
||||
static int declare_internal __P((register WORD_LIST *, int));
|
||||
|
||||
/* Declare or change variable attributes. */
|
||||
int
|
||||
declare_builtin (list)
|
||||
register WORD_LIST *list;
|
||||
{
|
||||
return (declare_internal (list, 0));
|
||||
}
|
||||
|
||||
$BUILTIN local
|
||||
$FUNCTION local_builtin
|
||||
$SHORT_DOC local [option] name[=value] ...
|
||||
Define local variables.
|
||||
|
||||
Create a local variable called NAME, and give it VALUE. OPTION can
|
||||
be any option accepted by `declare'.
|
||||
|
||||
Local variables can only be used within a function; they are visible
|
||||
only to the function where they are defined and its children.
|
||||
|
||||
Exit Status:
|
||||
Returns success unless an invalid option is supplied, an error occurs,
|
||||
or the shell is not executing a function.
|
||||
$END
|
||||
int
|
||||
local_builtin (list)
|
||||
register WORD_LIST *list;
|
||||
{
|
||||
if (variable_context)
|
||||
return (declare_internal (list, 1));
|
||||
else
|
||||
{
|
||||
builtin_error (_("can only be used in a function"));
|
||||
return (EXECUTION_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
#if defined (ARRAY_VARS)
|
||||
# define DECLARE_OPTS "+acfgilprtuxAF"
|
||||
#else
|
||||
# define DECLARE_OPTS "+cfgilprtuxF"
|
||||
#endif
|
||||
|
||||
/* The workhorse function. */
|
||||
static int
|
||||
declare_internal (list, local_var)
|
||||
register WORD_LIST *list;
|
||||
int local_var;
|
||||
{
|
||||
int flags_on, flags_off, *flags;
|
||||
int any_failed, assign_error, pflag, nodefs, opt, mkglobal;
|
||||
char *t, *subscript_start;
|
||||
SHELL_VAR *var;
|
||||
FUNCTION_DEF *shell_fn;
|
||||
|
||||
flags_on = flags_off = any_failed = assign_error = pflag = nodefs = mkglobal = 0;
|
||||
reset_internal_getopt ();
|
||||
while ((opt = internal_getopt (list, DECLARE_OPTS)) != EOF)
|
||||
{
|
||||
flags = list_opttype == '+' ? &flags_off : &flags_on;
|
||||
|
||||
switch (opt)
|
||||
{
|
||||
case 'a':
|
||||
#if defined (ARRAY_VARS)
|
||||
*flags |= att_array;
|
||||
break;
|
||||
#else
|
||||
builtin_usage ();
|
||||
return (EX_USAGE);
|
||||
#endif
|
||||
case 'A':
|
||||
#if defined (ARRAY_VARS)
|
||||
*flags |= att_assoc;
|
||||
break;
|
||||
#else
|
||||
builtin_usage ();
|
||||
return (EX_USAGE);
|
||||
#endif
|
||||
case 'p':
|
||||
if (local_var == 0)
|
||||
pflag++;
|
||||
break;
|
||||
case 'F':
|
||||
nodefs++;
|
||||
*flags |= att_function;
|
||||
break;
|
||||
case 'f':
|
||||
*flags |= att_function;
|
||||
break;
|
||||
case 'g':
|
||||
if (flags == &flags_on)
|
||||
mkglobal = 1;
|
||||
break;
|
||||
case 'i':
|
||||
*flags |= att_integer;
|
||||
break;
|
||||
case 'r':
|
||||
*flags |= att_readonly;
|
||||
break;
|
||||
case 't':
|
||||
*flags |= att_trace;
|
||||
break;
|
||||
case 'x':
|
||||
*flags |= att_exported;
|
||||
array_needs_making = 1;
|
||||
break;
|
||||
#if defined (CASEMOD_ATTRS)
|
||||
# if defined (CASEMOD_CAPCASE)
|
||||
case 'c':
|
||||
*flags |= att_capcase;
|
||||
if (flags == &flags_on)
|
||||
flags_off |= att_uppercase|att_lowercase;
|
||||
break;
|
||||
# endif
|
||||
case 'l':
|
||||
*flags |= att_lowercase;
|
||||
if (flags == &flags_on)
|
||||
flags_off |= att_capcase|att_uppercase;
|
||||
break;
|
||||
case 'u':
|
||||
*flags |= att_uppercase;
|
||||
if (flags == &flags_on)
|
||||
flags_off |= att_capcase|att_lowercase;
|
||||
break;
|
||||
#endif /* CASEMOD_ATTRS */
|
||||
default:
|
||||
builtin_usage ();
|
||||
return (EX_USAGE);
|
||||
}
|
||||
}
|
||||
|
||||
list = loptend;
|
||||
|
||||
/* If there are no more arguments left, then we just want to show
|
||||
some variables. */
|
||||
if (list == 0) /* declare -[aAfFirtx] */
|
||||
{
|
||||
/* Show local variables defined at this context level if this is
|
||||
the `local' builtin. */
|
||||
if (local_var)
|
||||
{
|
||||
register SHELL_VAR **vlist;
|
||||
register int i;
|
||||
|
||||
vlist = all_local_variables ();
|
||||
|
||||
if (vlist)
|
||||
{
|
||||
for (i = 0; vlist[i]; i++)
|
||||
print_assignment (vlist[i]);
|
||||
|
||||
free (vlist);
|
||||
}
|
||||
}
|
||||
else if (pflag && (flags_on == 0 || flags_on == att_function))
|
||||
show_all_var_attributes (flags_on == 0, nodefs);
|
||||
else if (flags_on == 0)
|
||||
return (set_builtin ((WORD_LIST *)NULL));
|
||||
else
|
||||
set_or_show_attributes ((WORD_LIST *)NULL, flags_on, nodefs);
|
||||
|
||||
return (sh_chkwrite (EXECUTION_SUCCESS));
|
||||
}
|
||||
|
||||
if (pflag) /* declare -p [-aAfFirtx] name [name...] */
|
||||
{
|
||||
for (any_failed = 0; list; list = list->next)
|
||||
{
|
||||
pflag = show_name_attributes (list->word->word, nodefs);
|
||||
if (pflag)
|
||||
{
|
||||
sh_notfound (list->word->word);
|
||||
any_failed++;
|
||||
}
|
||||
}
|
||||
return (sh_chkwrite (any_failed ? EXECUTION_FAILURE : EXECUTION_SUCCESS));
|
||||
}
|
||||
|
||||
#define NEXT_VARIABLE() free (name); list = list->next; continue
|
||||
|
||||
/* There are arguments left, so we are making variables. */
|
||||
while (list) /* declare [-aAfFirx] name [name ...] */
|
||||
{
|
||||
char *value, *name;
|
||||
int offset, aflags;
|
||||
#if defined (ARRAY_VARS)
|
||||
int making_array_special, compound_array_assign, simple_array_assign;
|
||||
#endif
|
||||
|
||||
name = savestring (list->word->word);
|
||||
offset = assignment (name, 0);
|
||||
aflags = 0;
|
||||
|
||||
if (offset) /* declare [-aAfFirx] name=value */
|
||||
{
|
||||
name[offset] = '\0';
|
||||
value = name + offset + 1;
|
||||
if (name[offset - 1] == '+')
|
||||
{
|
||||
aflags |= ASS_APPEND;
|
||||
name[offset - 1] = '\0';
|
||||
}
|
||||
}
|
||||
else
|
||||
value = "";
|
||||
|
||||
#if defined (ARRAY_VARS)
|
||||
compound_array_assign = simple_array_assign = 0;
|
||||
subscript_start = (char *)NULL;
|
||||
if (t = strchr (name, '[')) /* ] */
|
||||
{
|
||||
/* If offset != 0 we have already validated any array reference */
|
||||
if (offset == 0 && valid_array_reference (name) == 0)
|
||||
{
|
||||
sh_invalidid (name);
|
||||
assign_error++;
|
||||
NEXT_VARIABLE ();
|
||||
}
|
||||
subscript_start = t;
|
||||
*t = '\0';
|
||||
making_array_special = 1;
|
||||
}
|
||||
else
|
||||
making_array_special = 0;
|
||||
#endif
|
||||
|
||||
/* If we're in posix mode or not looking for a shell function (since
|
||||
shell function names don't have to be valid identifiers when the
|
||||
shell's not in posix mode), check whether or not the argument is a
|
||||
valid, well-formed shell identifier. */
|
||||
if ((posixly_correct || (flags_on & att_function) == 0) && legal_identifier (name) == 0)
|
||||
{
|
||||
sh_invalidid (name);
|
||||
assign_error++;
|
||||
NEXT_VARIABLE ();
|
||||
}
|
||||
|
||||
/* If VARIABLE_CONTEXT has a non-zero value, then we are executing
|
||||
inside of a function. This means we should make local variables,
|
||||
not global ones. */
|
||||
|
||||
/* XXX - this has consequences when we're making a local copy of a
|
||||
variable that was in the temporary environment. Watch out
|
||||
for this. */
|
||||
if (variable_context && mkglobal == 0 && ((flags_on & att_function) == 0))
|
||||
{
|
||||
#if defined (ARRAY_VARS)
|
||||
if (flags_on & att_assoc)
|
||||
var = make_local_assoc_variable (name);
|
||||
else if ((flags_on & att_array) || making_array_special)
|
||||
var = make_local_array_variable (name);
|
||||
else
|
||||
#endif
|
||||
var = make_local_variable (name);
|
||||
if (var == 0)
|
||||
{
|
||||
any_failed++;
|
||||
NEXT_VARIABLE ();
|
||||
}
|
||||
}
|
||||
else
|
||||
var = (SHELL_VAR *)NULL;
|
||||
|
||||
/* If we are declaring a function, then complain about it in some way.
|
||||
We don't let people make functions by saying `typeset -f foo=bar'. */
|
||||
|
||||
/* There should be a way, however, to let people look at a particular
|
||||
function definition by saying `typeset -f foo'. */
|
||||
|
||||
if (flags_on & att_function)
|
||||
{
|
||||
if (offset) /* declare -f [-rix] foo=bar */
|
||||
{
|
||||
builtin_error (_("cannot use `-f' to make functions"));
|
||||
free (name);
|
||||
return (EXECUTION_FAILURE);
|
||||
}
|
||||
else /* declare -f [-rx] name [name...] */
|
||||
{
|
||||
var = find_function (name);
|
||||
|
||||
if (var)
|
||||
{
|
||||
if (readonly_p (var) && (flags_off & att_readonly))
|
||||
{
|
||||
builtin_error (_("%s: readonly function"), name);
|
||||
any_failed++;
|
||||
NEXT_VARIABLE ();
|
||||
}
|
||||
|
||||
/* declare -[Ff] name [name...] */
|
||||
if (flags_on == att_function && flags_off == 0)
|
||||
{
|
||||
#if defined (DEBUGGER)
|
||||
if (nodefs && debugging_mode)
|
||||
{
|
||||
shell_fn = find_function_def (var->name);
|
||||
if (shell_fn)
|
||||
printf ("%s %d %s\n", var->name, shell_fn->line, shell_fn->source_file);
|
||||
else
|
||||
printf ("%s\n", var->name);
|
||||
}
|
||||
else
|
||||
#endif /* DEBUGGER */
|
||||
{
|
||||
t = nodefs ? var->name
|
||||
: named_function_string (name, function_cell (var), FUNC_MULTILINE|FUNC_EXTERNAL);
|
||||
printf ("%s\n", t);
|
||||
any_failed = sh_chkwrite (any_failed);
|
||||
}
|
||||
}
|
||||
else /* declare -[fF] -[rx] name [name...] */
|
||||
{
|
||||
VSETATTR (var, flags_on);
|
||||
VUNSETATTR (var, flags_off);
|
||||
}
|
||||
}
|
||||
else
|
||||
any_failed++;
|
||||
NEXT_VARIABLE ();
|
||||
}
|
||||
}
|
||||
else /* declare -[aAirx] name [name...] */
|
||||
{
|
||||
/* Non-null if we just created or fetched a local variable. */
|
||||
if (var == 0)
|
||||
var = mkglobal ? find_global_variable (name) : find_variable (name);
|
||||
|
||||
if (var == 0)
|
||||
{
|
||||
#if defined (ARRAY_VARS)
|
||||
if (flags_on & att_assoc)
|
||||
var = make_new_assoc_variable (name);
|
||||
else if ((flags_on & att_array) || making_array_special)
|
||||
var = make_new_array_variable (name);
|
||||
else
|
||||
#endif
|
||||
|
||||
if (offset)
|
||||
var = bind_variable (name, "", 0);
|
||||
else
|
||||
{
|
||||
var = bind_variable (name, (char *)NULL, 0);
|
||||
VSETATTR (var, att_invisible);
|
||||
}
|
||||
}
|
||||
|
||||
/* Cannot use declare +r to turn off readonly attribute. */
|
||||
if (readonly_p (var) && (flags_off & att_readonly))
|
||||
{
|
||||
sh_readonly (name);
|
||||
any_failed++;
|
||||
NEXT_VARIABLE ();
|
||||
}
|
||||
|
||||
/* Cannot use declare to assign value to readonly or noassign
|
||||
variable. */
|
||||
if ((readonly_p (var) || noassign_p (var)) && offset)
|
||||
{
|
||||
if (readonly_p (var))
|
||||
sh_readonly (name);
|
||||
assign_error++;
|
||||
NEXT_VARIABLE ();
|
||||
}
|
||||
|
||||
#if defined (ARRAY_VARS)
|
||||
if ((making_array_special || (flags_on & (att_array|att_assoc)) || array_p (var) || assoc_p (var)) && offset)
|
||||
{
|
||||
int vlen;
|
||||
vlen = STRLEN (value);
|
||||
|
||||
if (value[0] == '(' && value[vlen-1] == ')')
|
||||
compound_array_assign = 1;
|
||||
else
|
||||
simple_array_assign = 1;
|
||||
}
|
||||
|
||||
/* Cannot use declare +a name or declare +A name to remove an
|
||||
array variable. */
|
||||
if (((flags_off & att_array) && array_p (var)) || ((flags_off & att_assoc) && assoc_p (var)))
|
||||
{
|
||||
builtin_error (_("%s: cannot destroy array variables in this way"), name);
|
||||
any_failed++;
|
||||
NEXT_VARIABLE ();
|
||||
}
|
||||
|
||||
if ((flags_on & att_array) && assoc_p (var))
|
||||
{
|
||||
builtin_error (_("%s: cannot convert associative to indexed array"), name);
|
||||
any_failed++;
|
||||
NEXT_VARIABLE ();
|
||||
}
|
||||
if ((flags_on & att_assoc) && array_p (var))
|
||||
{
|
||||
builtin_error (_("%s: cannot convert indexed to associative array"), name);
|
||||
any_failed++;
|
||||
NEXT_VARIABLE ();
|
||||
}
|
||||
|
||||
/* declare -A name[[n]] makes name an associative array variable. */
|
||||
if (flags_on & att_assoc)
|
||||
{
|
||||
if (assoc_p (var) == 0)
|
||||
var = convert_var_to_assoc (var);
|
||||
}
|
||||
/* declare -a name[[n]] or declare name[n] makes name an indexed
|
||||
array variable. */
|
||||
else if ((making_array_special || (flags_on & att_array)) && array_p (var) == 0 && assoc_p (var) == 0)
|
||||
var = convert_var_to_array (var);
|
||||
#endif /* ARRAY_VARS */
|
||||
|
||||
VSETATTR (var, flags_on);
|
||||
VUNSETATTR (var, flags_off);
|
||||
|
||||
#if defined (ARRAY_VARS)
|
||||
if (offset && compound_array_assign)
|
||||
assign_array_var_from_string (var, value, aflags);
|
||||
else if (simple_array_assign && subscript_start)
|
||||
{
|
||||
/* declare [-aA] name[N]=value */
|
||||
*subscript_start = '['; /* ] */
|
||||
var = assign_array_element (name, value, 0); /* XXX - not aflags */
|
||||
*subscript_start = '\0';
|
||||
}
|
||||
else if (simple_array_assign)
|
||||
{
|
||||
/* let bind_{array,assoc}_variable take care of this. */
|
||||
if (assoc_p (var))
|
||||
bind_assoc_variable (var, name, savestring ("0"), value, aflags);
|
||||
else
|
||||
bind_array_variable (name, 0, value, aflags);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
/* bind_variable_value duplicates the essential internals of
|
||||
bind_variable() */
|
||||
if (offset)
|
||||
bind_variable_value (var, value, aflags);
|
||||
|
||||
/* If we found this variable in the temporary environment, as with
|
||||
`var=value declare -x var', make sure it is treated identically
|
||||
to `var=value export var'. Do the same for `declare -r' and
|
||||
`readonly'. Preserve the attributes, except for att_tempvar. */
|
||||
/* XXX -- should this create a variable in the global scope, or
|
||||
modify the local variable flags? ksh93 has it modify the
|
||||
global scope.
|
||||
Need to handle case like in set_var_attribute where a temporary
|
||||
variable is in the same table as the function local vars. */
|
||||
if ((flags_on & (att_exported|att_readonly)) && tempvar_p (var))
|
||||
{
|
||||
SHELL_VAR *tv;
|
||||
char *tvalue;
|
||||
|
||||
tv = find_tempenv_variable (var->name);
|
||||
if (tv)
|
||||
{
|
||||
tvalue = var_isset (var) ? savestring (value_cell (var)) : savestring ("");
|
||||
tv = bind_variable (var->name, tvalue, 0);
|
||||
tv->attributes |= var->attributes & ~att_tempvar;
|
||||
if (tv->context > 0)
|
||||
VSETATTR (tv, att_propagate);
|
||||
free (tvalue);
|
||||
}
|
||||
VSETATTR (var, att_propagate);
|
||||
}
|
||||
}
|
||||
|
||||
stupidly_hack_special_variables (name);
|
||||
|
||||
NEXT_VARIABLE ();
|
||||
}
|
||||
|
||||
return (assign_error ? EX_BADASSIGN
|
||||
: ((any_failed == 0) ? EXECUTION_SUCCESS
|
||||
: EXECUTION_FAILURE));
|
||||
}
|
||||
@@ -1,352 +0,0 @@
|
||||
/* evalfile.c - read and evaluate commands from a file or file descriptor */
|
||||
|
||||
/* Copyright (C) 1996-2009 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Bash, the Bourne Again SHell.
|
||||
|
||||
Bash is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Bash is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Bash. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#if defined (HAVE_UNISTD_H)
|
||||
# include <unistd.h>
|
||||
#endif
|
||||
|
||||
#include "../bashtypes.h"
|
||||
#include "posixstat.h"
|
||||
#include "filecntl.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <signal.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "../bashansi.h"
|
||||
#include "../bashintl.h"
|
||||
|
||||
#include "../shell.h"
|
||||
#include "../jobs.h"
|
||||
#include "../builtins.h"
|
||||
#include "../flags.h"
|
||||
#include "../input.h"
|
||||
#include "../execute_cmd.h"
|
||||
#include "../trap.h"
|
||||
|
||||
#if defined (HISTORY)
|
||||
# include "../bashhist.h"
|
||||
#endif
|
||||
|
||||
#include <typemax.h>
|
||||
|
||||
#include "common.h"
|
||||
|
||||
#if !defined (errno)
|
||||
extern int errno;
|
||||
#endif
|
||||
|
||||
/* Flags for _evalfile() */
|
||||
#define FEVAL_ENOENTOK 0x001
|
||||
#define FEVAL_BUILTIN 0x002
|
||||
#define FEVAL_UNWINDPROT 0x004
|
||||
#define FEVAL_NONINT 0x008
|
||||
#define FEVAL_LONGJMP 0x010
|
||||
#define FEVAL_HISTORY 0x020
|
||||
#define FEVAL_CHECKBINARY 0x040
|
||||
#define FEVAL_REGFILE 0x080
|
||||
#define FEVAL_NOPUSHARGS 0x100
|
||||
|
||||
extern int posixly_correct;
|
||||
extern int indirection_level, subshell_environment;
|
||||
extern int return_catch_flag, return_catch_value;
|
||||
extern int last_command_exit_value;
|
||||
extern int executing_command_builtin;
|
||||
|
||||
/* How many `levels' of sourced files we have. */
|
||||
int sourcelevel = 0;
|
||||
|
||||
static int
|
||||
_evalfile (filename, flags)
|
||||
const char *filename;
|
||||
int flags;
|
||||
{
|
||||
volatile int old_interactive;
|
||||
procenv_t old_return_catch;
|
||||
int return_val, fd, result, pflags, i, nnull;
|
||||
ssize_t nr; /* return value from read(2) */
|
||||
char *string;
|
||||
struct stat finfo;
|
||||
size_t file_size;
|
||||
sh_vmsg_func_t *errfunc;
|
||||
#if defined (ARRAY_VARS)
|
||||
SHELL_VAR *funcname_v, *nfv, *bash_source_v, *bash_lineno_v;
|
||||
ARRAY *funcname_a, *bash_source_a, *bash_lineno_a;
|
||||
# if defined (DEBUGGER)
|
||||
SHELL_VAR *bash_argv_v, *bash_argc_v;
|
||||
ARRAY *bash_argv_a, *bash_argc_a;
|
||||
# endif
|
||||
char *t, tt[2];
|
||||
#endif
|
||||
|
||||
USE_VAR(pflags);
|
||||
|
||||
#if defined (ARRAY_VARS)
|
||||
GET_ARRAY_FROM_VAR ("FUNCNAME", funcname_v, funcname_a);
|
||||
GET_ARRAY_FROM_VAR ("BASH_SOURCE", bash_source_v, bash_source_a);
|
||||
GET_ARRAY_FROM_VAR ("BASH_LINENO", bash_lineno_v, bash_lineno_a);
|
||||
# if defined (DEBUGGER)
|
||||
GET_ARRAY_FROM_VAR ("BASH_ARGV", bash_argv_v, bash_argv_a);
|
||||
GET_ARRAY_FROM_VAR ("BASH_ARGC", bash_argc_v, bash_argc_a);
|
||||
# endif
|
||||
#endif
|
||||
|
||||
fd = open (filename, O_RDONLY);
|
||||
|
||||
if (fd < 0 || (fstat (fd, &finfo) == -1))
|
||||
{
|
||||
file_error_and_exit:
|
||||
if (((flags & FEVAL_ENOENTOK) == 0) || errno != ENOENT)
|
||||
file_error (filename);
|
||||
|
||||
if (flags & FEVAL_LONGJMP)
|
||||
{
|
||||
last_command_exit_value = 1;
|
||||
jump_to_top_level (EXITPROG);
|
||||
}
|
||||
|
||||
return ((flags & FEVAL_BUILTIN) ? EXECUTION_FAILURE
|
||||
: ((errno == ENOENT) ? 0 : -1));
|
||||
}
|
||||
|
||||
errfunc = ((flags & FEVAL_BUILTIN) ? builtin_error : internal_error);
|
||||
|
||||
if (S_ISDIR (finfo.st_mode))
|
||||
{
|
||||
(*errfunc) (_("%s: is a directory"), filename);
|
||||
return ((flags & FEVAL_BUILTIN) ? EXECUTION_FAILURE : -1);
|
||||
}
|
||||
else if ((flags & FEVAL_REGFILE) && S_ISREG (finfo.st_mode) == 0)
|
||||
{
|
||||
(*errfunc) (_("%s: not a regular file"), filename);
|
||||
return ((flags & FEVAL_BUILTIN) ? EXECUTION_FAILURE : -1);
|
||||
}
|
||||
|
||||
file_size = (size_t)finfo.st_size;
|
||||
/* Check for overflow with large files. */
|
||||
if (file_size != finfo.st_size || file_size + 1 < file_size)
|
||||
{
|
||||
(*errfunc) (_("%s: file is too large"), filename);
|
||||
return ((flags & FEVAL_BUILTIN) ? EXECUTION_FAILURE : -1);
|
||||
}
|
||||
|
||||
#if defined (__CYGWIN__) && defined (O_TEXT)
|
||||
setmode (fd, O_TEXT);
|
||||
#endif
|
||||
|
||||
if (S_ISREG (finfo.st_mode) && file_size <= SSIZE_MAX)
|
||||
{
|
||||
string = (char *)xmalloc (1 + file_size);
|
||||
nr = read (fd, string, file_size);
|
||||
if (nr >= 0)
|
||||
string[nr] = '\0';
|
||||
}
|
||||
else
|
||||
nr = zmapfd (fd, &string, 0);
|
||||
|
||||
return_val = errno;
|
||||
close (fd);
|
||||
errno = return_val;
|
||||
|
||||
if (nr < 0) /* XXX was != file_size, not < 0 */
|
||||
{
|
||||
free (string);
|
||||
goto file_error_and_exit;
|
||||
}
|
||||
|
||||
if (nr == 0)
|
||||
{
|
||||
free (string);
|
||||
return ((flags & FEVAL_BUILTIN) ? EXECUTION_SUCCESS : 1);
|
||||
}
|
||||
|
||||
if ((flags & FEVAL_CHECKBINARY) &&
|
||||
check_binary_file (string, (nr > 80) ? 80 : nr))
|
||||
{
|
||||
free (string);
|
||||
(*errfunc) (_("%s: cannot execute binary file"), filename);
|
||||
return ((flags & FEVAL_BUILTIN) ? EX_BINARY_FILE : -1);
|
||||
}
|
||||
|
||||
i = strlen (string);
|
||||
if (i < nr)
|
||||
{
|
||||
for (nnull = i = 0; i < nr; i++)
|
||||
if (string[i] == '\0')
|
||||
{
|
||||
memmove (string+i, string+i+1, nr - i);
|
||||
nr--;
|
||||
/* Even if the `check binary' flag is not set, we want to avoid
|
||||
sourcing files with more than 256 null characters -- that
|
||||
probably indicates a binary file. */
|
||||
if ((flags & FEVAL_BUILTIN) && ++nnull > 256)
|
||||
{
|
||||
free (string);
|
||||
(*errfunc) (_("%s: cannot execute binary file"), filename);
|
||||
return ((flags & FEVAL_BUILTIN) ? EX_BINARY_FILE : -1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (flags & FEVAL_UNWINDPROT)
|
||||
{
|
||||
begin_unwind_frame ("_evalfile");
|
||||
|
||||
unwind_protect_int (return_catch_flag);
|
||||
unwind_protect_jmp_buf (return_catch);
|
||||
if (flags & FEVAL_NONINT)
|
||||
unwind_protect_int (interactive);
|
||||
unwind_protect_int (sourcelevel);
|
||||
}
|
||||
else
|
||||
{
|
||||
COPY_PROCENV (return_catch, old_return_catch);
|
||||
if (flags & FEVAL_NONINT)
|
||||
old_interactive = interactive;
|
||||
}
|
||||
|
||||
if (flags & FEVAL_NONINT)
|
||||
interactive = 0;
|
||||
|
||||
return_catch_flag++;
|
||||
sourcelevel++;
|
||||
|
||||
#if defined (ARRAY_VARS)
|
||||
array_push (bash_source_a, (char *)filename);
|
||||
t = itos (executing_line_number ());
|
||||
array_push (bash_lineno_a, t);
|
||||
free (t);
|
||||
array_push (funcname_a, "source"); /* not exactly right */
|
||||
# if defined (DEBUGGER)
|
||||
/* Have to figure out a better way to do this when `source' is supplied
|
||||
arguments */
|
||||
if ((flags & FEVAL_NOPUSHARGS) == 0)
|
||||
{
|
||||
array_push (bash_argv_a, (char *)filename);
|
||||
tt[0] = '1'; tt[1] = '\0';
|
||||
array_push (bash_argc_a, tt);
|
||||
}
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* set the flags to be passed to parse_and_execute */
|
||||
pflags = SEVAL_RESETLINE;
|
||||
pflags |= (flags & FEVAL_HISTORY) ? 0 : SEVAL_NOHIST;
|
||||
|
||||
if (flags & FEVAL_BUILTIN)
|
||||
result = EXECUTION_SUCCESS;
|
||||
|
||||
return_val = setjmp (return_catch);
|
||||
|
||||
/* If `return' was seen outside of a function, but in the script, then
|
||||
force parse_and_execute () to clean up. */
|
||||
if (return_val)
|
||||
{
|
||||
parse_and_execute_cleanup ();
|
||||
result = return_catch_value;
|
||||
}
|
||||
else
|
||||
result = parse_and_execute (string, filename, pflags);
|
||||
|
||||
if (flags & FEVAL_UNWINDPROT)
|
||||
run_unwind_frame ("_evalfile");
|
||||
else
|
||||
{
|
||||
if (flags & FEVAL_NONINT)
|
||||
interactive = old_interactive;
|
||||
return_catch_flag--;
|
||||
sourcelevel--;
|
||||
COPY_PROCENV (old_return_catch, return_catch);
|
||||
}
|
||||
|
||||
#if defined (ARRAY_VARS)
|
||||
/* These two variables cannot be unset, and cannot be affected by the
|
||||
sourced file. */
|
||||
array_pop (bash_source_a);
|
||||
array_pop (bash_lineno_a);
|
||||
|
||||
/* FUNCNAME can be unset, and so can potentially be changed by the
|
||||
sourced file. */
|
||||
GET_ARRAY_FROM_VAR ("FUNCNAME", nfv, funcname_a);
|
||||
if (nfv == funcname_v)
|
||||
array_pop (funcname_a);
|
||||
# if defined (DEBUGGER)
|
||||
if ((flags & FEVAL_NOPUSHARGS) == 0)
|
||||
{
|
||||
array_pop (bash_argc_a);
|
||||
array_pop (bash_argv_a);
|
||||
}
|
||||
# endif
|
||||
#endif
|
||||
|
||||
return ((flags & FEVAL_BUILTIN) ? result : 1);
|
||||
}
|
||||
|
||||
int
|
||||
maybe_execute_file (fname, force_noninteractive)
|
||||
const char *fname;
|
||||
int force_noninteractive;
|
||||
{
|
||||
char *filename;
|
||||
int result, flags;
|
||||
|
||||
filename = bash_tilde_expand (fname, 0);
|
||||
flags = FEVAL_ENOENTOK;
|
||||
if (force_noninteractive)
|
||||
flags |= FEVAL_NONINT;
|
||||
result = _evalfile (filename, flags);
|
||||
free (filename);
|
||||
return result;
|
||||
}
|
||||
|
||||
#if defined (HISTORY)
|
||||
int
|
||||
fc_execute_file (filename)
|
||||
const char *filename;
|
||||
{
|
||||
int flags;
|
||||
|
||||
/* We want these commands to show up in the history list if
|
||||
remember_on_history is set. */
|
||||
flags = FEVAL_ENOENTOK|FEVAL_HISTORY|FEVAL_REGFILE;
|
||||
return (_evalfile (filename, flags));
|
||||
}
|
||||
#endif /* HISTORY */
|
||||
|
||||
int
|
||||
source_file (filename, sflags)
|
||||
const char *filename;
|
||||
int sflags;
|
||||
{
|
||||
int flags, rval;
|
||||
|
||||
flags = FEVAL_BUILTIN|FEVAL_UNWINDPROT|FEVAL_NONINT;
|
||||
if (sflags)
|
||||
flags |= FEVAL_NOPUSHARGS;
|
||||
/* POSIX shells exit if non-interactive and file error. */
|
||||
if (posixly_correct && interactive_shell == 0 && executing_command_builtin == 0)
|
||||
flags |= FEVAL_LONGJMP;
|
||||
rval = _evalfile (filename, flags);
|
||||
|
||||
run_return_trap ();
|
||||
return rval;
|
||||
}
|
||||
@@ -1,509 +0,0 @@
|
||||
/* evalstring.c - evaluate a string as one or more shell commands.
|
||||
|
||||
/* Copyright (C) 1996-2010 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Bash, the Bourne Again SHell.
|
||||
|
||||
Bash is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Bash is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Bash. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#if defined (HAVE_UNISTD_H)
|
||||
# ifdef _MINIX
|
||||
# include <sys/types.h>
|
||||
# endif
|
||||
# include <unistd.h>
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <signal.h>
|
||||
|
||||
#include <errno.h>
|
||||
|
||||
#include "filecntl.h"
|
||||
#include "../bashansi.h"
|
||||
|
||||
#include "../shell.h"
|
||||
#include "../jobs.h"
|
||||
#include "../builtins.h"
|
||||
#include "../flags.h"
|
||||
#include "../input.h"
|
||||
#include "../execute_cmd.h"
|
||||
#include "../redir.h"
|
||||
#include "../trap.h"
|
||||
#include "../bashintl.h"
|
||||
|
||||
#include <y.tab.h>
|
||||
|
||||
#if defined (HISTORY)
|
||||
# include "../bashhist.h"
|
||||
#endif
|
||||
|
||||
#include "common.h"
|
||||
#include "builtext.h"
|
||||
|
||||
#if !defined (errno)
|
||||
extern int errno;
|
||||
#endif
|
||||
|
||||
#define IS_BUILTIN(s) (builtin_address_internal(s, 0) != (struct builtin *)NULL)
|
||||
|
||||
extern int indirection_level, subshell_environment;
|
||||
extern int line_number;
|
||||
extern int current_token, shell_eof_token;
|
||||
extern int last_command_exit_value;
|
||||
extern int running_trap;
|
||||
extern int loop_level;
|
||||
extern int executing_list;
|
||||
extern int comsub_ignore_return;
|
||||
extern int posixly_correct;
|
||||
extern sh_builtin_func_t *this_shell_builtin;
|
||||
|
||||
int parse_and_execute_level = 0;
|
||||
|
||||
static int cat_file __P((REDIRECT *));
|
||||
|
||||
#define PE_TAG "parse_and_execute top"
|
||||
#define PS_TAG "parse_string top"
|
||||
|
||||
#if defined (HISTORY)
|
||||
static void
|
||||
set_history_remembering ()
|
||||
{
|
||||
remember_on_history = enable_history_list;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* How to force parse_and_execute () to clean up after itself. */
|
||||
void
|
||||
parse_and_execute_cleanup ()
|
||||
{
|
||||
if (running_trap)
|
||||
{
|
||||
run_trap_cleanup (running_trap - 1);
|
||||
unfreeze_jobs_list ();
|
||||
}
|
||||
|
||||
if (have_unwind_protects ())
|
||||
run_unwind_frame (PE_TAG);
|
||||
else
|
||||
parse_and_execute_level = 0; /* XXX */
|
||||
}
|
||||
|
||||
static void
|
||||
parse_prologue (string, flags, tag)
|
||||
char *string;
|
||||
int flags;
|
||||
char *tag;
|
||||
{
|
||||
char *orig_string;
|
||||
int x;
|
||||
|
||||
orig_string = string;
|
||||
/* Unwind protect this invocation of parse_and_execute (). */
|
||||
begin_unwind_frame (tag);
|
||||
unwind_protect_int (parse_and_execute_level);
|
||||
unwind_protect_jmp_buf (top_level);
|
||||
unwind_protect_int (indirection_level);
|
||||
unwind_protect_int (line_number);
|
||||
unwind_protect_int (loop_level);
|
||||
unwind_protect_int (executing_list);
|
||||
unwind_protect_int (comsub_ignore_return);
|
||||
if (flags & (SEVAL_NONINT|SEVAL_INTERACT))
|
||||
unwind_protect_int (interactive);
|
||||
|
||||
#if defined (HISTORY)
|
||||
if (parse_and_execute_level == 0)
|
||||
add_unwind_protect (set_history_remembering, (char *)NULL);
|
||||
else
|
||||
unwind_protect_int (remember_on_history); /* can be used in scripts */
|
||||
# if defined (BANG_HISTORY)
|
||||
if (interactive_shell)
|
||||
unwind_protect_int (history_expansion_inhibited);
|
||||
# endif /* BANG_HISTORY */
|
||||
#endif /* HISTORY */
|
||||
|
||||
if (interactive_shell)
|
||||
{
|
||||
x = get_current_prompt_level ();
|
||||
add_unwind_protect (set_current_prompt_level, x);
|
||||
}
|
||||
|
||||
add_unwind_protect (pop_stream, (char *)NULL);
|
||||
if (orig_string && ((flags & SEVAL_NOFREE) == 0))
|
||||
add_unwind_protect (xfree, orig_string);
|
||||
end_unwind_frame ();
|
||||
|
||||
if (flags & (SEVAL_NONINT|SEVAL_INTERACT))
|
||||
interactive = (flags & SEVAL_NONINT) ? 0 : 1;
|
||||
|
||||
#if defined (HISTORY)
|
||||
if (flags & SEVAL_NOHIST)
|
||||
bash_history_disable ();
|
||||
#endif /* HISTORY */
|
||||
}
|
||||
|
||||
/* Parse and execute the commands in STRING. Returns whatever
|
||||
execute_command () returns. This frees STRING. FLAGS is a
|
||||
flags word; look in common.h for the possible values. Actions
|
||||
are:
|
||||
(flags & SEVAL_NONINT) -> interactive = 0;
|
||||
(flags & SEVAL_INTERACT) -> interactive = 1;
|
||||
(flags & SEVAL_NOHIST) -> call bash_history_disable ()
|
||||
(flags & SEVAL_NOFREE) -> don't free STRING when finished
|
||||
(flags & SEVAL_RESETLINE) -> reset line_number to 1
|
||||
*/
|
||||
|
||||
int
|
||||
parse_and_execute (string, from_file, flags)
|
||||
char *string;
|
||||
const char *from_file;
|
||||
int flags;
|
||||
{
|
||||
int code, lreset;
|
||||
volatile int should_jump_to_top_level, last_result;
|
||||
COMMAND *volatile command;
|
||||
|
||||
parse_prologue (string, flags, PE_TAG);
|
||||
|
||||
parse_and_execute_level++;
|
||||
|
||||
lreset = flags & SEVAL_RESETLINE;
|
||||
|
||||
/* Reset the line number if the caller wants us to. If we don't reset the
|
||||
line number, we have to subtract one, because we will add one just
|
||||
before executing the next command (resetting the line number sets it to
|
||||
0; the first line number is 1). */
|
||||
push_stream (lreset);
|
||||
if (lreset == 0)
|
||||
line_number--;
|
||||
|
||||
indirection_level++;
|
||||
|
||||
code = should_jump_to_top_level = 0;
|
||||
last_result = EXECUTION_SUCCESS;
|
||||
|
||||
with_input_from_string (string, from_file);
|
||||
while (*(bash_input.location.string))
|
||||
{
|
||||
command = (COMMAND *)NULL;
|
||||
|
||||
if (interrupt_state)
|
||||
{
|
||||
last_result = EXECUTION_FAILURE;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Provide a location for functions which `longjmp (top_level)' to
|
||||
jump to. This prevents errors in substitution from restarting
|
||||
the reader loop directly, for example. */
|
||||
code = setjmp (top_level);
|
||||
|
||||
if (code)
|
||||
{
|
||||
should_jump_to_top_level = 0;
|
||||
switch (code)
|
||||
{
|
||||
case FORCE_EOF:
|
||||
case ERREXIT:
|
||||
case EXITPROG:
|
||||
if (command)
|
||||
run_unwind_frame ("pe_dispose");
|
||||
/* Remember to call longjmp (top_level) after the old
|
||||
value for it is restored. */
|
||||
should_jump_to_top_level = 1;
|
||||
goto out;
|
||||
|
||||
case DISCARD:
|
||||
if (command)
|
||||
run_unwind_frame ("pe_dispose");
|
||||
last_result = last_command_exit_value = EXECUTION_FAILURE; /* XXX */
|
||||
if (subshell_environment)
|
||||
{
|
||||
should_jump_to_top_level = 1;
|
||||
goto out;
|
||||
}
|
||||
else
|
||||
{
|
||||
#if 0
|
||||
dispose_command (command); /* pe_dispose does this */
|
||||
#endif
|
||||
continue;
|
||||
}
|
||||
|
||||
default:
|
||||
command_error ("parse_and_execute", CMDERR_BADJUMP, code, 0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (parse_command () == 0)
|
||||
{
|
||||
if ((flags & SEVAL_PARSEONLY) || (interactive_shell == 0 && read_but_dont_execute))
|
||||
{
|
||||
last_result = EXECUTION_SUCCESS;
|
||||
dispose_command (global_command);
|
||||
global_command = (COMMAND *)NULL;
|
||||
}
|
||||
else if (command = global_command)
|
||||
{
|
||||
struct fd_bitmap *bitmap;
|
||||
|
||||
bitmap = new_fd_bitmap (FD_BITMAP_SIZE);
|
||||
begin_unwind_frame ("pe_dispose");
|
||||
itrace("begin_unwind_frame: pe_dispose");
|
||||
add_unwind_protect (dispose_fd_bitmap, bitmap);
|
||||
add_unwind_protect (dispose_command, command); /* XXX */
|
||||
|
||||
global_command = (COMMAND *)NULL;
|
||||
|
||||
if ((subshell_environment & SUBSHELL_COMSUB) && comsub_ignore_return)
|
||||
command->flags |= CMD_IGNORE_RETURN;
|
||||
|
||||
#if defined (ONESHOT)
|
||||
/*
|
||||
* IF
|
||||
* we were invoked as `bash -c' (startup_state == 2) AND
|
||||
* parse_and_execute has not been called recursively AND
|
||||
* we're not running a trap AND
|
||||
* we have parsed the full command (string == '\0') AND
|
||||
* we're not going to run the exit trap AND
|
||||
* we have a simple command without redirections AND
|
||||
* the command is not being timed AND
|
||||
* the command's return status is not being inverted
|
||||
* THEN
|
||||
* tell the execution code that we don't need to fork
|
||||
*/
|
||||
if (startup_state == 2 && parse_and_execute_level == 1 &&
|
||||
running_trap == 0 &&
|
||||
*bash_input.location.string == '\0' &&
|
||||
command->type == cm_simple &&
|
||||
signal_is_trapped (EXIT_TRAP) == 0 &&
|
||||
command->redirects == 0 && command->value.Simple->redirects == 0 &&
|
||||
((command->flags & CMD_TIME_PIPELINE) == 0) &&
|
||||
((command->flags & CMD_INVERT_RETURN) == 0))
|
||||
{
|
||||
command->flags |= CMD_NO_FORK;
|
||||
command->value.Simple->flags |= CMD_NO_FORK;
|
||||
}
|
||||
#endif /* ONESHOT */
|
||||
|
||||
/* See if this is a candidate for $( <file ). */
|
||||
if (startup_state == 2 &&
|
||||
(subshell_environment & SUBSHELL_COMSUB) &&
|
||||
*bash_input.location.string == '\0' &&
|
||||
command->type == cm_simple && !command->redirects &&
|
||||
(command->flags & CMD_TIME_PIPELINE) == 0 &&
|
||||
command->value.Simple->words == 0 &&
|
||||
command->value.Simple->redirects &&
|
||||
command->value.Simple->redirects->next == 0 &&
|
||||
command->value.Simple->redirects->instruction == r_input_direction)
|
||||
{
|
||||
int r;
|
||||
r = cat_file (command->value.Simple->redirects);
|
||||
last_result = (r < 0) ? EXECUTION_FAILURE : EXECUTION_SUCCESS;
|
||||
}
|
||||
else
|
||||
last_result = execute_command_internal
|
||||
(command, 0, NO_PIPE, NO_PIPE, bitmap);
|
||||
|
||||
dispose_command (command);
|
||||
dispose_fd_bitmap (bitmap);
|
||||
discard_unwind_frame ("pe_dispose");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
last_result = EXECUTION_FAILURE;
|
||||
|
||||
if (interactive_shell == 0 && this_shell_builtin &&
|
||||
(this_shell_builtin == source_builtin || this_shell_builtin == eval_builtin) &&
|
||||
last_command_exit_value == EX_BADSYNTAX && posixly_correct)
|
||||
{
|
||||
should_jump_to_top_level = 1;
|
||||
code = ERREXIT;
|
||||
last_command_exit_value = EX_BADUSAGE;
|
||||
}
|
||||
|
||||
/* Since we are shell compatible, syntax errors in a script
|
||||
abort the execution of the script. Right? */
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
out:
|
||||
|
||||
run_unwind_frame (PE_TAG);
|
||||
|
||||
if (interrupt_state && parse_and_execute_level == 0)
|
||||
{
|
||||
/* An interrupt during non-interactive execution in an
|
||||
interactive shell (e.g. via $PROMPT_COMMAND) should
|
||||
not cause the shell to exit. */
|
||||
interactive = interactive_shell;
|
||||
throw_to_top_level ();
|
||||
}
|
||||
|
||||
if (should_jump_to_top_level)
|
||||
jump_to_top_level (code);
|
||||
|
||||
return (last_result);
|
||||
}
|
||||
|
||||
/* Parse a command contained in STRING according to FLAGS and return the
|
||||
number of characters consumed from the string. If non-NULL, set *ENDP
|
||||
to the position in the string where the parse ended. Used to validate
|
||||
command substitutions during parsing to obey Posix rules about finding
|
||||
the end of the command and balancing parens. */
|
||||
int
|
||||
parse_string (string, from_file, flags, endp)
|
||||
char *string;
|
||||
const char *from_file;
|
||||
int flags;
|
||||
char **endp;
|
||||
{
|
||||
int code, nc;
|
||||
volatile int should_jump_to_top_level;
|
||||
COMMAND *volatile command, *oglobal;
|
||||
char *ostring;
|
||||
|
||||
parse_prologue (string, flags, PS_TAG);
|
||||
|
||||
/* Reset the line number if the caller wants us to. If we don't reset the
|
||||
line number, we have to subtract one, because we will add one just
|
||||
before executing the next command (resetting the line number sets it to
|
||||
0; the first line number is 1). */
|
||||
push_stream (0);
|
||||
|
||||
code = should_jump_to_top_level = 0;
|
||||
oglobal = global_command;
|
||||
ostring = string;
|
||||
|
||||
with_input_from_string (string, from_file);
|
||||
while (*(bash_input.location.string))
|
||||
{
|
||||
command = (COMMAND *)NULL;
|
||||
|
||||
#if 0
|
||||
if (interrupt_state)
|
||||
break;
|
||||
#endif
|
||||
|
||||
/* Provide a location for functions which `longjmp (top_level)' to
|
||||
jump to. */
|
||||
code = setjmp (top_level);
|
||||
|
||||
if (code)
|
||||
{
|
||||
#if defined (DEBUG)
|
||||
itrace("parse_string: longjmp executed: code = %d", code);
|
||||
#endif
|
||||
should_jump_to_top_level = 0;
|
||||
switch (code)
|
||||
{
|
||||
case FORCE_EOF:
|
||||
case ERREXIT:
|
||||
case EXITPROG:
|
||||
case DISCARD: /* XXX */
|
||||
if (command)
|
||||
dispose_command (command);
|
||||
/* Remember to call longjmp (top_level) after the old
|
||||
value for it is restored. */
|
||||
should_jump_to_top_level = 1;
|
||||
goto out;
|
||||
|
||||
default:
|
||||
command_error ("parse_string", CMDERR_BADJUMP, code, 0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (parse_command () == 0)
|
||||
{
|
||||
dispose_command (global_command);
|
||||
global_command = (COMMAND *)NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((flags & SEVAL_NOLONGJMP) == 0)
|
||||
{
|
||||
should_jump_to_top_level = 1;
|
||||
code = DISCARD;
|
||||
}
|
||||
else
|
||||
reset_parser (); /* XXX - sets token_to_read */
|
||||
break;
|
||||
}
|
||||
|
||||
if (current_token == yacc_EOF || current_token == shell_eof_token)
|
||||
break;
|
||||
}
|
||||
|
||||
out:
|
||||
|
||||
global_command = oglobal;
|
||||
nc = bash_input.location.string - ostring;
|
||||
if (endp)
|
||||
*endp = bash_input.location.string;
|
||||
|
||||
run_unwind_frame (PS_TAG);
|
||||
|
||||
if (should_jump_to_top_level)
|
||||
jump_to_top_level (code);
|
||||
|
||||
return (nc);
|
||||
}
|
||||
|
||||
/* Handle a $( < file ) command substitution. This expands the filename,
|
||||
returning errors as appropriate, then just cats the file to the standard
|
||||
output. */
|
||||
static int
|
||||
cat_file (r)
|
||||
REDIRECT *r;
|
||||
{
|
||||
char *fn;
|
||||
int fd, rval;
|
||||
|
||||
if (r->instruction != r_input_direction)
|
||||
return -1;
|
||||
|
||||
/* Get the filename. */
|
||||
if (posixly_correct && !interactive_shell)
|
||||
disallow_filename_globbing++;
|
||||
fn = redirection_expand (r->redirectee.filename);
|
||||
if (posixly_correct && !interactive_shell)
|
||||
disallow_filename_globbing--;
|
||||
|
||||
if (fn == 0)
|
||||
{
|
||||
redirection_error (r, AMBIGUOUS_REDIRECT);
|
||||
return -1;
|
||||
}
|
||||
|
||||
fd = open(fn, O_RDONLY);
|
||||
if (fd < 0)
|
||||
{
|
||||
file_error (fn);
|
||||
free (fn);
|
||||
return -1;
|
||||
}
|
||||
|
||||
rval = zcatfd (fd, 1, fn);
|
||||
|
||||
free (fn);
|
||||
close (fd);
|
||||
|
||||
return (rval);
|
||||
}
|
||||
@@ -1,252 +0,0 @@
|
||||
This file is exec.def, from which is created exec.c.
|
||||
It implements the builtin "exec" in Bash.
|
||||
|
||||
Copyright (C) 1987-2010 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Bash, the Bourne Again SHell.
|
||||
|
||||
Bash is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Bash is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Bash. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
$PRODUCES exec.c
|
||||
|
||||
$BUILTIN exec
|
||||
$FUNCTION exec_builtin
|
||||
$SHORT_DOC exec [-cl] [-a name] [command [arguments ...]] [redirection ...]
|
||||
Replace the shell with the given command.
|
||||
|
||||
Execute COMMAND, replacing this shell with the specified program.
|
||||
ARGUMENTS become the arguments to COMMAND. If COMMAND is not specified,
|
||||
any redirections take effect in the current shell.
|
||||
|
||||
Options:
|
||||
-a name pass NAME as the zeroth argument to COMMAND
|
||||
-c execute COMMAND with an empty environment
|
||||
-l place a dash in the zeroth argument to COMMAND
|
||||
|
||||
If the command cannot be executed, a non-interactive shell exits, unless
|
||||
the shell option `execfail' is set.
|
||||
|
||||
Exit Status:
|
||||
Returns success unless COMMAND is not found or a redirection error occurs.
|
||||
$END
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include "../bashtypes.h"
|
||||
#include "posixstat.h"
|
||||
#include <signal.h>
|
||||
#include <errno.h>
|
||||
|
||||
#if defined (HAVE_UNISTD_H)
|
||||
# include <unistd.h>
|
||||
#endif
|
||||
|
||||
#include "../bashansi.h"
|
||||
#include "../bashintl.h"
|
||||
|
||||
#include "../shell.h"
|
||||
#include "../execute_cmd.h"
|
||||
#include "../findcmd.h"
|
||||
#if defined (JOB_CONTROL)
|
||||
# include "../jobs.h"
|
||||
#endif
|
||||
#include "../flags.h"
|
||||
#include "../trap.h"
|
||||
#if defined (HISTORY)
|
||||
# include "../bashhist.h"
|
||||
#endif
|
||||
#include "common.h"
|
||||
#include "bashgetopt.h"
|
||||
|
||||
/* Not all systems declare ERRNO in errno.h... and some systems #define it! */
|
||||
#if !defined (errno)
|
||||
extern int errno;
|
||||
#endif /* !errno */
|
||||
|
||||
extern int subshell_environment;
|
||||
extern REDIRECT *redirection_undo_list;
|
||||
extern char *exec_argv0;
|
||||
|
||||
int no_exit_on_failed_exec;
|
||||
|
||||
/* If the user wants this to look like a login shell, then
|
||||
prepend a `-' onto NAME and return the new name. */
|
||||
static char *
|
||||
mkdashname (name)
|
||||
char *name;
|
||||
{
|
||||
char *ret;
|
||||
|
||||
ret = (char *)xmalloc (2 + strlen (name));
|
||||
ret[0] = '-';
|
||||
strcpy (ret + 1, name);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int
|
||||
exec_builtin (list)
|
||||
WORD_LIST *list;
|
||||
{
|
||||
int exit_value = EXECUTION_FAILURE;
|
||||
int cleanenv, login, opt;
|
||||
char *argv0, *command, **args, **env, *newname, *com2;
|
||||
|
||||
cleanenv = login = 0;
|
||||
exec_argv0 = argv0 = (char *)NULL;
|
||||
|
||||
reset_internal_getopt ();
|
||||
while ((opt = internal_getopt (list, "cla:")) != -1)
|
||||
{
|
||||
switch (opt)
|
||||
{
|
||||
case 'c':
|
||||
cleanenv = 1;
|
||||
break;
|
||||
case 'l':
|
||||
login = 1;
|
||||
break;
|
||||
case 'a':
|
||||
argv0 = list_optarg;
|
||||
break;
|
||||
default:
|
||||
builtin_usage ();
|
||||
return (EX_USAGE);
|
||||
}
|
||||
}
|
||||
list = loptend;
|
||||
|
||||
/* First, let the redirections remain. */
|
||||
dispose_redirects (redirection_undo_list);
|
||||
redirection_undo_list = (REDIRECT *)NULL;
|
||||
|
||||
if (list == 0)
|
||||
return (EXECUTION_SUCCESS);
|
||||
|
||||
#if defined (RESTRICTED_SHELL)
|
||||
if (restricted)
|
||||
{
|
||||
sh_restricted ((char *)NULL);
|
||||
return (EXECUTION_FAILURE);
|
||||
}
|
||||
#endif /* RESTRICTED_SHELL */
|
||||
|
||||
args = strvec_from_word_list (list, 1, 0, (int *)NULL);
|
||||
|
||||
/* A command with a slash anywhere in its name is not looked up in $PATH. */
|
||||
command = absolute_program (args[0]) ? args[0] : search_for_command (args[0]);
|
||||
|
||||
if (command == 0)
|
||||
{
|
||||
if (file_isdir (args[0]))
|
||||
{
|
||||
#if defined (EISDIR)
|
||||
builtin_error (_("%s: cannot execute: %s"), args[0], strerror (EISDIR));
|
||||
#else
|
||||
builtin_error (_("%s: cannot execute: %s"), args[0], strerror (errno));
|
||||
#endif
|
||||
exit_value = EX_NOEXEC;
|
||||
}
|
||||
else
|
||||
{
|
||||
sh_notfound (args[0]);
|
||||
exit_value = EX_NOTFOUND; /* As per Posix.2, 3.14.6 */
|
||||
}
|
||||
goto failed_exec;
|
||||
}
|
||||
|
||||
com2 = full_pathname (command);
|
||||
if (com2)
|
||||
{
|
||||
if (command != args[0])
|
||||
free (command);
|
||||
command = com2;
|
||||
}
|
||||
|
||||
if (argv0)
|
||||
{
|
||||
free (args[0]);
|
||||
args[0] = login ? mkdashname (argv0) : savestring (argv0);
|
||||
exec_argv0 = savestring (args[0]);
|
||||
}
|
||||
else if (login)
|
||||
{
|
||||
newname = mkdashname (args[0]);
|
||||
free (args[0]);
|
||||
args[0] = newname;
|
||||
}
|
||||
|
||||
/* Decrement SHLVL by 1 so a new shell started here has the same value,
|
||||
preserving the appearance. After we do that, we need to change the
|
||||
exported environment to include the new value. */
|
||||
if (cleanenv == 0)
|
||||
adjust_shell_level (-1);
|
||||
|
||||
if (cleanenv)
|
||||
env = (char **)NULL;
|
||||
else
|
||||
{
|
||||
maybe_make_export_env ();
|
||||
env = export_env;
|
||||
}
|
||||
|
||||
#if defined (HISTORY)
|
||||
if (interactive_shell && subshell_environment == 0)
|
||||
maybe_save_shell_history ();
|
||||
#endif /* HISTORY */
|
||||
|
||||
restore_original_signals ();
|
||||
|
||||
#if defined (JOB_CONTROL)
|
||||
if (subshell_environment == 0)
|
||||
end_job_control ();
|
||||
#endif /* JOB_CONTROL */
|
||||
|
||||
exit_value = shell_execve (command, args, env);
|
||||
|
||||
/* We have to set this to NULL because shell_execve has called realloc()
|
||||
to stuff more items at the front of the array, which may have caused
|
||||
the memory to be freed by realloc(). We don't want to free it twice. */
|
||||
args = (char **)NULL;
|
||||
if (cleanenv == 0)
|
||||
adjust_shell_level (1);
|
||||
|
||||
if (exit_value == EX_NOTFOUND)
|
||||
goto failed_exec;
|
||||
else if (executable_file (command) == 0)
|
||||
{
|
||||
builtin_error (_("%s: cannot execute: %s"), command, strerror (errno));
|
||||
exit_value = EX_NOEXEC; /* As per Posix.2, 3.14.6 */
|
||||
}
|
||||
else
|
||||
file_error (command);
|
||||
|
||||
failed_exec:
|
||||
FREE (command);
|
||||
|
||||
if (subshell_environment || (interactive == 0 && no_exit_on_failed_exec == 0))
|
||||
exit_shell (exit_value);
|
||||
|
||||
if (args)
|
||||
strvec_dispose (args);
|
||||
|
||||
initialize_traps ();
|
||||
initialize_signals (1);
|
||||
|
||||
#if defined (JOB_CONTROL)
|
||||
if (interactive_shell || job_control)
|
||||
restart_job_control ();
|
||||
#endif /* JOB_CONTROL */
|
||||
|
||||
return (exit_value);
|
||||
}
|
||||
@@ -1,675 +0,0 @@
|
||||
This file is fc.def, from which is created fc.c.
|
||||
It implements the builtin "fc" in Bash.
|
||||
|
||||
Copyright (C) 1987-2009 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Bash, the Bourne Again SHell.
|
||||
|
||||
Bash is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Bash is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Bash. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
$PRODUCES fc.c
|
||||
|
||||
$BUILTIN fc
|
||||
$FUNCTION fc_builtin
|
||||
$DEPENDS_ON HISTORY
|
||||
$SHORT_DOC fc [-e ename] [-lnr] [first] [last] or fc -s [pat=rep] [command]
|
||||
Display or execute commands from the history list.
|
||||
|
||||
fc is used to list or edit and re-execute commands from the history list.
|
||||
FIRST and LAST can be numbers specifying the range, or FIRST can be a
|
||||
string, which means the most recent command beginning with that
|
||||
string.
|
||||
|
||||
Options:
|
||||
-e ENAME select which editor to use. Default is FCEDIT, then EDITOR,
|
||||
then vi
|
||||
-l list lines instead of editing
|
||||
-n omit line numbers when listing
|
||||
-r reverse the order of the lines (newest listed first)
|
||||
|
||||
With the `fc -s [pat=rep ...] [command]' format, COMMAND is
|
||||
re-executed after the substitution OLD=NEW is performed.
|
||||
|
||||
A useful alias to use with this is r='fc -s', so that typing `r cc'
|
||||
runs the last command beginning with `cc' and typing `r' re-executes
|
||||
the last command.
|
||||
|
||||
Exit Status:
|
||||
Returns success or status of executed command; non-zero if an error occurs.
|
||||
$END
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#if defined (HISTORY)
|
||||
#ifndef _MINIX
|
||||
# include <sys/param.h>
|
||||
#endif
|
||||
#include "../bashtypes.h"
|
||||
#include "posixstat.h"
|
||||
#if ! defined(_MINIX) && defined (HAVE_SYS_FILE_H)
|
||||
# include <sys/file.h>
|
||||
#endif
|
||||
|
||||
#if defined (HAVE_UNISTD_H)
|
||||
# include <unistd.h>
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <chartypes.h>
|
||||
|
||||
#include "../bashansi.h"
|
||||
#include "../bashintl.h"
|
||||
#include <errno.h>
|
||||
|
||||
#include "../shell.h"
|
||||
#include "../builtins.h"
|
||||
#include "../flags.h"
|
||||
#include "../bashhist.h"
|
||||
#include "maxpath.h"
|
||||
#include <readline/history.h>
|
||||
#include "bashgetopt.h"
|
||||
#include "common.h"
|
||||
|
||||
#if !defined (errno)
|
||||
extern int errno;
|
||||
#endif /* !errno */
|
||||
|
||||
extern int current_command_line_count, saved_command_line_count;
|
||||
extern int literal_history;
|
||||
extern int posixly_correct;
|
||||
extern int subshell_environment, interactive_shell;
|
||||
|
||||
extern int unlink __P((const char *));
|
||||
|
||||
extern FILE *sh_mktmpfp __P((char *, int, char **));
|
||||
|
||||
/* **************************************************************** */
|
||||
/* */
|
||||
/* The K*rn shell style fc command (Fix Command) */
|
||||
/* */
|
||||
/* **************************************************************** */
|
||||
|
||||
/* fc builtin command (fix command) for Bash for those who
|
||||
like K*rn-style history better than csh-style.
|
||||
|
||||
fc [-e ename] [-nlr] [first] [last]
|
||||
|
||||
FIRST and LAST can be numbers specifying the range, or FIRST can be
|
||||
a string, which means the most recent command beginning with that
|
||||
string.
|
||||
|
||||
-e ENAME selects which editor to use. Default is FCEDIT, then EDITOR,
|
||||
then the editor which corresponds to the current readline editing
|
||||
mode, then vi.
|
||||
|
||||
-l means list lines instead of editing.
|
||||
-n means no line numbers listed.
|
||||
-r means reverse the order of the lines (making it newest listed first).
|
||||
|
||||
fc -e - [pat=rep ...] [command]
|
||||
fc -s [pat=rep ...] [command]
|
||||
|
||||
Equivalent to !command:sg/pat/rep execpt there can be multiple PAT=REP's.
|
||||
*/
|
||||
|
||||
/* Data structure describing a list of global replacements to perform. */
|
||||
typedef struct repl {
|
||||
struct repl *next;
|
||||
char *pat;
|
||||
char *rep;
|
||||
} REPL;
|
||||
|
||||
/* Accessors for HIST_ENTRY lists that are called HLIST. */
|
||||
#define histline(i) (hlist[(i)]->line)
|
||||
#define histdata(i) (hlist[(i)]->data)
|
||||
|
||||
#define FREE_RLIST() \
|
||||
do { \
|
||||
for (rl = rlist; rl; ) { \
|
||||
REPL *r; \
|
||||
r = rl->next; \
|
||||
if (rl->pat) \
|
||||
free (rl->pat); \
|
||||
if (rl->rep) \
|
||||
free (rl->rep); \
|
||||
free (rl); \
|
||||
rl = r; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
static char *fc_dosubs __P((char *, REPL *));
|
||||
static char *fc_gethist __P((char *, HIST_ENTRY **));
|
||||
static int fc_gethnum __P((char *, HIST_ENTRY **));
|
||||
static int fc_number __P((WORD_LIST *));
|
||||
static void fc_replhist __P((char *));
|
||||
#ifdef INCLUDE_UNUSED
|
||||
static char *fc_readline __P((FILE *));
|
||||
static void fc_addhist __P((char *));
|
||||
#endif
|
||||
|
||||
/* String to execute on a file that we want to edit. */
|
||||
#define FC_EDIT_COMMAND "${FCEDIT:-${EDITOR:-vi}}"
|
||||
#if defined (STRICT_POSIX)
|
||||
# define POSIX_FC_EDIT_COMMAND "${FCEDIT:-ed}"
|
||||
#else
|
||||
# define POSIX_FC_EDIT_COMMAND "${FCEDIT:-${EDITOR:-ed}}"
|
||||
#endif
|
||||
|
||||
int
|
||||
fc_builtin (list)
|
||||
WORD_LIST *list;
|
||||
{
|
||||
register int i;
|
||||
register char *sep;
|
||||
int numbering, reverse, listing, execute;
|
||||
int histbeg, histend, last_hist, retval, opt, rh;
|
||||
FILE *stream;
|
||||
REPL *rlist, *rl;
|
||||
char *ename, *command, *newcom, *fcedit;
|
||||
HIST_ENTRY **hlist;
|
||||
char *fn;
|
||||
|
||||
numbering = 1;
|
||||
reverse = listing = execute = 0;
|
||||
ename = (char *)NULL;
|
||||
|
||||
/* Parse out the options and set which of the two forms we're in. */
|
||||
reset_internal_getopt ();
|
||||
lcurrent = list; /* XXX */
|
||||
while (fc_number (loptend = lcurrent) == 0 &&
|
||||
(opt = internal_getopt (list, ":e:lnrs")) != -1)
|
||||
{
|
||||
switch (opt)
|
||||
{
|
||||
case 'n':
|
||||
numbering = 0;
|
||||
break;
|
||||
|
||||
case 'l':
|
||||
listing = 1;
|
||||
break;
|
||||
|
||||
case 'r':
|
||||
reverse = 1;
|
||||
break;
|
||||
|
||||
case 's':
|
||||
execute = 1;
|
||||
break;
|
||||
|
||||
case 'e':
|
||||
ename = list_optarg;
|
||||
break;
|
||||
|
||||
default:
|
||||
builtin_usage ();
|
||||
return (EX_USAGE);
|
||||
}
|
||||
}
|
||||
|
||||
list = loptend;
|
||||
|
||||
if (ename && (*ename == '-') && (ename[1] == '\0'))
|
||||
execute = 1;
|
||||
|
||||
/* The "execute" form of the command (re-run, with possible string
|
||||
substitutions). */
|
||||
if (execute)
|
||||
{
|
||||
rlist = (REPL *)NULL;
|
||||
while (list && ((sep = (char *)strchr (list->word->word, '=')) != NULL))
|
||||
{
|
||||
*sep++ = '\0';
|
||||
rl = (REPL *)xmalloc (sizeof (REPL));
|
||||
rl->next = (REPL *)NULL;
|
||||
rl->pat = savestring (list->word->word);
|
||||
rl->rep = savestring (sep);
|
||||
|
||||
if (rlist == NULL)
|
||||
rlist = rl;
|
||||
else
|
||||
{
|
||||
rl->next = rlist;
|
||||
rlist = rl;
|
||||
}
|
||||
list = list->next;
|
||||
}
|
||||
|
||||
/* If we have a list of substitutions to do, then reverse it
|
||||
to get the replacements in the proper order. */
|
||||
|
||||
rlist = REVERSE_LIST (rlist, REPL *);
|
||||
|
||||
hlist = history_list ();
|
||||
|
||||
/* If we still have something in list, it is a command spec.
|
||||
Otherwise, we use the most recent command in time. */
|
||||
command = fc_gethist (list ? list->word->word : (char *)NULL, hlist);
|
||||
|
||||
if (command == NULL)
|
||||
{
|
||||
builtin_error (_("no command found"));
|
||||
if (rlist)
|
||||
FREE_RLIST ();
|
||||
|
||||
return (EXECUTION_FAILURE);
|
||||
}
|
||||
|
||||
if (rlist)
|
||||
{
|
||||
newcom = fc_dosubs (command, rlist);
|
||||
free (command);
|
||||
FREE_RLIST ();
|
||||
command = newcom;
|
||||
}
|
||||
|
||||
fprintf (stderr, "%s\n", command);
|
||||
fc_replhist (command); /* replace `fc -s' with command */
|
||||
/* Posix says that the re-executed commands should be entered into the
|
||||
history. */
|
||||
return (parse_and_execute (command, "fc", SEVAL_NOHIST));
|
||||
}
|
||||
|
||||
/* This is the second form of the command (the list-or-edit-and-rerun
|
||||
form). */
|
||||
hlist = history_list ();
|
||||
if (hlist == 0)
|
||||
return (EXECUTION_SUCCESS);
|
||||
for (i = 0; hlist[i]; i++);
|
||||
|
||||
/* With the Bash implementation of history, the current command line
|
||||
("fc blah..." and so on) is already part of the history list by
|
||||
the time we get to this point. This just skips over that command
|
||||
and makes the last command that this deals with be the last command
|
||||
the user entered before the fc. We need to check whether the
|
||||
line was actually added (HISTIGNORE may have caused it to not be),
|
||||
so we check hist_last_line_added. */
|
||||
|
||||
/* Even though command substitution through parse_and_execute turns off
|
||||
remember_on_history, command substitution in a shell when set -o history
|
||||
has been enabled (interactive or not) should use it in the last_hist
|
||||
calculation as if it were on. */
|
||||
rh = remember_on_history || ((subshell_environment & SUBSHELL_COMSUB) && enable_history_list);
|
||||
last_hist = i - rh - hist_last_line_added;
|
||||
|
||||
/* XXX */
|
||||
if (saved_command_line_count > 0 && i == last_hist && hlist[last_hist] == 0)
|
||||
while (last_hist >= 0 && hlist[last_hist] == 0)
|
||||
last_hist--;
|
||||
if (last_hist < 0)
|
||||
{
|
||||
sh_erange ((char *)NULL, _("history specification"));
|
||||
return (EXECUTION_FAILURE);
|
||||
}
|
||||
|
||||
if (list)
|
||||
{
|
||||
histbeg = fc_gethnum (list->word->word, hlist);
|
||||
list = list->next;
|
||||
|
||||
if (list)
|
||||
histend = fc_gethnum (list->word->word, hlist);
|
||||
else
|
||||
histend = listing ? last_hist : histbeg;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* The default for listing is the last 16 history items. */
|
||||
if (listing)
|
||||
{
|
||||
histend = last_hist;
|
||||
histbeg = histend - 16 + 1; /* +1 because loop below uses >= */
|
||||
if (histbeg < 0)
|
||||
histbeg = 0;
|
||||
}
|
||||
else
|
||||
/* For editing, it is the last history command. */
|
||||
histbeg = histend = last_hist;
|
||||
}
|
||||
|
||||
/* "When not listing, the fc command that caused the editing shall not be
|
||||
entered into the history list." */
|
||||
if (listing == 0 && hist_last_line_added)
|
||||
{
|
||||
bash_delete_last_history ();
|
||||
/* If we're editing a single command -- the last command in the
|
||||
history -- and we just removed the dummy command added by
|
||||
edit_and_execute_command (), we need to check whether or not we
|
||||
just removed the last command in the history and need to back
|
||||
the pointer up. remember_on_history is off because we're running
|
||||
in parse_and_execute(). */
|
||||
if (histbeg == histend && histend == last_hist && hlist[last_hist] == 0)
|
||||
last_hist = histbeg = --histend;
|
||||
}
|
||||
|
||||
/* We print error messages for line specifications out of range. */
|
||||
if ((histbeg < 0) || (histend < 0))
|
||||
{
|
||||
sh_erange ((char *)NULL, _("history specification"));
|
||||
return (EXECUTION_FAILURE);
|
||||
}
|
||||
|
||||
if (histend < histbeg)
|
||||
{
|
||||
i = histend;
|
||||
histend = histbeg;
|
||||
histbeg = i;
|
||||
|
||||
reverse = 1;
|
||||
}
|
||||
|
||||
if (listing)
|
||||
stream = stdout;
|
||||
else
|
||||
{
|
||||
numbering = 0;
|
||||
stream = sh_mktmpfp ("bash-fc", MT_USERANDOM|MT_USETMPDIR, &fn);
|
||||
if (stream == 0)
|
||||
{
|
||||
builtin_error (_("%s: cannot open temp file: %s"), fn ? fn : "", strerror (errno));
|
||||
FREE (fn);
|
||||
return (EXECUTION_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
for (i = reverse ? histend : histbeg; reverse ? i >= histbeg : i <= histend; reverse ? i-- : i++)
|
||||
{
|
||||
QUIT;
|
||||
if (numbering)
|
||||
fprintf (stream, "%d", i + history_base);
|
||||
if (listing)
|
||||
{
|
||||
if (posixly_correct)
|
||||
fputs ("\t", stream);
|
||||
else
|
||||
fprintf (stream, "\t%c", histdata (i) ? '*' : ' ');
|
||||
}
|
||||
fprintf (stream, "%s\n", histline (i));
|
||||
}
|
||||
|
||||
if (listing)
|
||||
return (sh_chkwrite (EXECUTION_SUCCESS));
|
||||
|
||||
fflush (stream);
|
||||
if (ferror (stream))
|
||||
{
|
||||
sh_wrerror ();
|
||||
fclose (stream);
|
||||
return (EXECUTION_FAILURE);
|
||||
}
|
||||
fclose (stream);
|
||||
|
||||
/* Now edit the file of commands. */
|
||||
if (ename)
|
||||
{
|
||||
command = (char *)xmalloc (strlen (ename) + strlen (fn) + 2);
|
||||
sprintf (command, "%s %s", ename, fn);
|
||||
}
|
||||
else
|
||||
{
|
||||
fcedit = posixly_correct ? POSIX_FC_EDIT_COMMAND : FC_EDIT_COMMAND;
|
||||
command = (char *)xmalloc (3 + strlen (fcedit) + strlen (fn));
|
||||
sprintf (command, "%s %s", fcedit, fn);
|
||||
}
|
||||
retval = parse_and_execute (command, "fc", SEVAL_NOHIST);
|
||||
if (retval != EXECUTION_SUCCESS)
|
||||
{
|
||||
unlink (fn);
|
||||
free (fn);
|
||||
return (EXECUTION_FAILURE);
|
||||
}
|
||||
|
||||
/* Make sure parse_and_execute doesn't turn this off, even though a
|
||||
call to parse_and_execute farther up the function call stack (e.g.,
|
||||
if this is called by vi_edit_and_execute_command) may have already
|
||||
called bash_history_disable. */
|
||||
remember_on_history = 1;
|
||||
|
||||
/* Turn on the `v' flag while fc_execute_file runs so the commands
|
||||
will be echoed as they are read by the parser. */
|
||||
begin_unwind_frame ("fc builtin");
|
||||
add_unwind_protect ((Function *)xfree, fn);
|
||||
add_unwind_protect (unlink, fn);
|
||||
unwind_protect_int (echo_input_at_read);
|
||||
echo_input_at_read = 1;
|
||||
|
||||
retval = fc_execute_file (fn);
|
||||
|
||||
run_unwind_frame ("fc builtin");
|
||||
|
||||
return (retval);
|
||||
}
|
||||
|
||||
/* Return 1 if LIST->word->word is a legal number for fc's use. */
|
||||
static int
|
||||
fc_number (list)
|
||||
WORD_LIST *list;
|
||||
{
|
||||
char *s;
|
||||
|
||||
if (list == 0)
|
||||
return 0;
|
||||
s = list->word->word;
|
||||
if (*s == '-')
|
||||
s++;
|
||||
return (legal_number (s, (intmax_t *)NULL));
|
||||
}
|
||||
|
||||
/* Return an absolute index into HLIST which corresponds to COMMAND. If
|
||||
COMMAND is a number, then it was specified in relative terms. If it
|
||||
is a string, then it is the start of a command line present in HLIST. */
|
||||
static int
|
||||
fc_gethnum (command, hlist)
|
||||
char *command;
|
||||
HIST_ENTRY **hlist;
|
||||
{
|
||||
int sign, n, clen, rh;
|
||||
register int i, j;
|
||||
register char *s;
|
||||
|
||||
sign = 1;
|
||||
/* Count history elements. */
|
||||
for (i = 0; hlist[i]; i++);
|
||||
|
||||
/* With the Bash implementation of history, the current command line
|
||||
("fc blah..." and so on) is already part of the history list by
|
||||
the time we get to this point. This just skips over that command
|
||||
and makes the last command that this deals with be the last command
|
||||
the user entered before the fc. We need to check whether the
|
||||
line was actually added (HISTIGNORE may have caused it to not be),
|
||||
so we check hist_last_line_added. This needs to agree with the
|
||||
calculation of last_hist in fc_builtin above. */
|
||||
/* Even though command substitution through parse_and_execute turns off
|
||||
remember_on_history, command substitution in a shell when set -o history
|
||||
has been enabled (interactive or not) should use it in the last_hist
|
||||
calculation as if it were on. */
|
||||
rh = remember_on_history || ((subshell_environment & SUBSHELL_COMSUB) && enable_history_list);
|
||||
i -= rh + hist_last_line_added;
|
||||
|
||||
/* No specification defaults to most recent command. */
|
||||
if (command == NULL)
|
||||
return (i);
|
||||
|
||||
/* Otherwise, there is a specification. It can be a number relative to
|
||||
the current position, or an absolute history number. */
|
||||
s = command;
|
||||
|
||||
/* Handle possible leading minus sign. */
|
||||
if (s && (*s == '-'))
|
||||
{
|
||||
sign = -1;
|
||||
s++;
|
||||
}
|
||||
|
||||
if (s && DIGIT(*s))
|
||||
{
|
||||
n = atoi (s);
|
||||
n *= sign;
|
||||
|
||||
/* If the value is negative or zero, then it is an offset from
|
||||
the current history item. */
|
||||
if (n < 0)
|
||||
{
|
||||
n += i + 1;
|
||||
return (n < 0 ? 0 : n);
|
||||
}
|
||||
else if (n == 0)
|
||||
return (i);
|
||||
else
|
||||
{
|
||||
n -= history_base;
|
||||
return (i < n ? i : n);
|
||||
}
|
||||
}
|
||||
|
||||
clen = strlen (command);
|
||||
for (j = i; j >= 0; j--)
|
||||
{
|
||||
if (STREQN (command, histline (j), clen))
|
||||
return (j);
|
||||
}
|
||||
return (-1);
|
||||
}
|
||||
|
||||
/* Locate the most recent history line which begins with
|
||||
COMMAND in HLIST, and return a malloc()'ed copy of it. */
|
||||
static char *
|
||||
fc_gethist (command, hlist)
|
||||
char *command;
|
||||
HIST_ENTRY **hlist;
|
||||
{
|
||||
int i;
|
||||
|
||||
if (hlist == 0)
|
||||
return ((char *)NULL);
|
||||
|
||||
i = fc_gethnum (command, hlist);
|
||||
|
||||
if (i >= 0)
|
||||
return (savestring (histline (i)));
|
||||
else
|
||||
return ((char *)NULL);
|
||||
}
|
||||
|
||||
#ifdef INCLUDE_UNUSED
|
||||
/* Read the edited history lines from STREAM and return them
|
||||
one at a time. This can read unlimited length lines. The
|
||||
caller should free the storage. */
|
||||
static char *
|
||||
fc_readline (stream)
|
||||
FILE *stream;
|
||||
{
|
||||
register int c;
|
||||
int line_len = 0, lindex = 0;
|
||||
char *line = (char *)NULL;
|
||||
|
||||
while ((c = getc (stream)) != EOF)
|
||||
{
|
||||
if ((lindex + 2) >= line_len)
|
||||
line = (char *)xrealloc (line, (line_len += 128));
|
||||
|
||||
if (c == '\n')
|
||||
{
|
||||
line[lindex++] = '\n';
|
||||
line[lindex++] = '\0';
|
||||
return (line);
|
||||
}
|
||||
else
|
||||
line[lindex++] = c;
|
||||
}
|
||||
|
||||
if (!lindex)
|
||||
{
|
||||
if (line)
|
||||
free (line);
|
||||
|
||||
return ((char *)NULL);
|
||||
}
|
||||
|
||||
if (lindex + 2 >= line_len)
|
||||
line = (char *)xrealloc (line, lindex + 3);
|
||||
|
||||
line[lindex++] = '\n'; /* Finish with newline if none in file */
|
||||
line[lindex++] = '\0';
|
||||
return (line);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Perform the SUBS on COMMAND.
|
||||
SUBS is a list of substitutions, and COMMAND is a simple string.
|
||||
Return a pointer to a malloc'ed string which contains the substituted
|
||||
command. */
|
||||
static char *
|
||||
fc_dosubs (command, subs)
|
||||
char *command;
|
||||
REPL *subs;
|
||||
{
|
||||
register char *new, *t;
|
||||
register REPL *r;
|
||||
|
||||
for (new = savestring (command), r = subs; r; r = r->next)
|
||||
{
|
||||
t = strsub (new, r->pat, r->rep, 1);
|
||||
free (new);
|
||||
new = t;
|
||||
}
|
||||
return (new);
|
||||
}
|
||||
|
||||
/* Use `command' to replace the last entry in the history list, which,
|
||||
by this time, is `fc blah...'. The intent is that the new command
|
||||
become the history entry, and that `fc' should never appear in the
|
||||
history list. This way you can do `r' to your heart's content. */
|
||||
static void
|
||||
fc_replhist (command)
|
||||
char *command;
|
||||
{
|
||||
int n;
|
||||
|
||||
if (command == 0 || *command == '\0')
|
||||
return;
|
||||
|
||||
n = strlen (command);
|
||||
if (command[n - 1] == '\n')
|
||||
command[n - 1] = '\0';
|
||||
|
||||
if (command && *command)
|
||||
{
|
||||
bash_delete_last_history ();
|
||||
maybe_add_history (command); /* Obeys HISTCONTROL setting. */
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef INCLUDE_UNUSED
|
||||
/* Add LINE to the history, after removing a single trailing newline. */
|
||||
static void
|
||||
fc_addhist (line)
|
||||
char *line;
|
||||
{
|
||||
register int n;
|
||||
|
||||
if (line == 0 || *line == 0)
|
||||
return;
|
||||
|
||||
n = strlen (line);
|
||||
|
||||
if (line[n - 1] == '\n')
|
||||
line[n - 1] = '\0';
|
||||
|
||||
if (line && *line)
|
||||
maybe_add_history (line); /* Obeys HISTCONTROL setting. */
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* HISTORY */
|
||||
@@ -1,282 +0,0 @@
|
||||
This file is hash.def, from which is created hash.c.
|
||||
It implements the builtin "hash" in Bash.
|
||||
|
||||
Copyright (C) 1987-2009 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Bash, the Bourne Again SHell.
|
||||
|
||||
Bash is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Bash is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Bash. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
$PRODUCES hash.c
|
||||
|
||||
$BUILTIN hash
|
||||
$FUNCTION hash_builtin
|
||||
$SHORT_DOC hash [-lr] [-p pathname] [-dt] [name ...]
|
||||
Remember or display program locations.
|
||||
|
||||
Determine and remember the full pathname of each command NAME. If
|
||||
no arguments are given, information about remembered commands is displayed.
|
||||
|
||||
Options:
|
||||
-d forget the remembered location of each NAME
|
||||
-l display in a format that may be reused as input
|
||||
-p pathname use PATHNAME is the full pathname of NAME
|
||||
-r forget all remembered locations
|
||||
-t print the remembered location of each NAME, preceding
|
||||
each location with the corresponding NAME if multiple
|
||||
NAMEs are given
|
||||
Arguments:
|
||||
NAME Each NAME is searched for in $PATH and added to the list
|
||||
of remembered commands.
|
||||
|
||||
Exit Status:
|
||||
Returns success unless NAME is not found or an invalid option is given.
|
||||
$END
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "../bashtypes.h"
|
||||
|
||||
#if defined (HAVE_UNISTD_H)
|
||||
# include <unistd.h>
|
||||
#endif
|
||||
|
||||
#include <errno.h>
|
||||
|
||||
#include "../bashansi.h"
|
||||
#include "../bashintl.h"
|
||||
|
||||
#include "../shell.h"
|
||||
#include "../builtins.h"
|
||||
#include "../flags.h"
|
||||
#include "../findcmd.h"
|
||||
#include "../hashcmd.h"
|
||||
#include "common.h"
|
||||
#include "bashgetopt.h"
|
||||
|
||||
extern int posixly_correct;
|
||||
extern int dot_found_in_search;
|
||||
extern char *this_command_name;
|
||||
|
||||
static int add_hashed_command __P((char *, int));
|
||||
static int print_hash_info __P((BUCKET_CONTENTS *));
|
||||
static int print_portable_hash_info __P((BUCKET_CONTENTS *));
|
||||
static int print_hashed_commands __P((int));
|
||||
static int list_hashed_filename_targets __P((WORD_LIST *, int));
|
||||
|
||||
/* Print statistics on the current state of hashed commands. If LIST is
|
||||
not empty, then rehash (or hash in the first place) the specified
|
||||
commands. */
|
||||
int
|
||||
hash_builtin (list)
|
||||
WORD_LIST *list;
|
||||
{
|
||||
int expunge_hash_table, list_targets, list_portably, delete, opt;
|
||||
char *w, *pathname;
|
||||
|
||||
if (hashing_enabled == 0)
|
||||
{
|
||||
builtin_error (_("hashing disabled"));
|
||||
return (EXECUTION_FAILURE);
|
||||
}
|
||||
|
||||
expunge_hash_table = list_targets = list_portably = delete = 0;
|
||||
pathname = (char *)NULL;
|
||||
reset_internal_getopt ();
|
||||
while ((opt = internal_getopt (list, "dlp:rt")) != -1)
|
||||
{
|
||||
switch (opt)
|
||||
{
|
||||
case 'd':
|
||||
delete = 1;
|
||||
break;
|
||||
case 'l':
|
||||
list_portably = 1;
|
||||
break;
|
||||
case 'p':
|
||||
pathname = list_optarg;
|
||||
break;
|
||||
case 'r':
|
||||
expunge_hash_table = 1;
|
||||
break;
|
||||
case 't':
|
||||
list_targets = 1;
|
||||
break;
|
||||
default:
|
||||
builtin_usage ();
|
||||
return (EX_USAGE);
|
||||
}
|
||||
}
|
||||
list = loptend;
|
||||
|
||||
/* hash -t requires at least one argument. */
|
||||
if (list == 0 && list_targets)
|
||||
{
|
||||
sh_needarg ("-t");
|
||||
return (EXECUTION_FAILURE);
|
||||
}
|
||||
|
||||
/* We want hash -r to be silent, but hash -- to print hashing info, so
|
||||
we test expunge_hash_table. */
|
||||
if (list == 0 && expunge_hash_table == 0)
|
||||
{
|
||||
opt = print_hashed_commands (list_portably);
|
||||
if (opt == 0 && posixly_correct == 0)
|
||||
printf (_("%s: hash table empty\n"), this_command_name);
|
||||
|
||||
return (EXECUTION_SUCCESS);
|
||||
}
|
||||
|
||||
if (expunge_hash_table)
|
||||
phash_flush ();
|
||||
|
||||
/* If someone runs `hash -r -t xyz' he will be disappointed. */
|
||||
if (list_targets)
|
||||
return (list_hashed_filename_targets (list, list_portably));
|
||||
|
||||
#if defined (RESTRICTED_SHELL)
|
||||
if (restricted && pathname && strchr (pathname, '/'))
|
||||
{
|
||||
sh_restricted (pathname);
|
||||
return (EXECUTION_FAILURE);
|
||||
}
|
||||
#endif
|
||||
|
||||
for (opt = EXECUTION_SUCCESS; list; list = list->next)
|
||||
{
|
||||
/* Add, remove or rehash the specified commands. */
|
||||
w = list->word->word;
|
||||
if (absolute_program (w))
|
||||
continue;
|
||||
else if (pathname)
|
||||
{
|
||||
if (is_directory (pathname))
|
||||
{
|
||||
#ifdef EISDIR
|
||||
builtin_error ("%s: %s", pathname, strerror (EISDIR));
|
||||
#else
|
||||
builtin_error (_("%s: is a directory"), pathname);
|
||||
#endif
|
||||
opt = EXECUTION_FAILURE;
|
||||
}
|
||||
else
|
||||
phash_insert (w, pathname, 0, 0);
|
||||
}
|
||||
else if (delete)
|
||||
{
|
||||
if (phash_remove (w))
|
||||
{
|
||||
sh_notfound (w);
|
||||
opt = EXECUTION_FAILURE;
|
||||
}
|
||||
}
|
||||
else if (add_hashed_command (w, 0))
|
||||
opt = EXECUTION_FAILURE;
|
||||
}
|
||||
|
||||
fflush (stdout);
|
||||
return (opt);
|
||||
}
|
||||
|
||||
static int
|
||||
add_hashed_command (w, quiet)
|
||||
char *w;
|
||||
int quiet;
|
||||
{
|
||||
int rv;
|
||||
char *full_path;
|
||||
|
||||
rv = 0;
|
||||
if (find_function (w) == 0 && find_shell_builtin (w) == 0)
|
||||
{
|
||||
phash_remove (w);
|
||||
full_path = find_user_command (w);
|
||||
if (full_path && executable_file (full_path))
|
||||
phash_insert (w, full_path, dot_found_in_search, 0);
|
||||
else
|
||||
{
|
||||
if (quiet == 0)
|
||||
sh_notfound (w);
|
||||
rv++;
|
||||
}
|
||||
FREE (full_path);
|
||||
}
|
||||
return (rv);
|
||||
}
|
||||
|
||||
/* Print information about current hashed info. */
|
||||
static int
|
||||
print_hash_info (item)
|
||||
BUCKET_CONTENTS *item;
|
||||
{
|
||||
printf ("%4d\t%s\n", item->times_found, pathdata(item)->path);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
print_portable_hash_info (item)
|
||||
BUCKET_CONTENTS *item;
|
||||
{
|
||||
printf ("builtin hash -p %s %s\n", pathdata(item)->path, item->key);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
print_hashed_commands (fmt)
|
||||
int fmt;
|
||||
{
|
||||
if (hashed_filenames == 0 || HASH_ENTRIES (hashed_filenames) == 0)
|
||||
return (0);
|
||||
|
||||
if (fmt == 0)
|
||||
printf (_("hits\tcommand\n"));
|
||||
hash_walk (hashed_filenames, fmt ? print_portable_hash_info : print_hash_info);
|
||||
return (1);
|
||||
}
|
||||
|
||||
static int
|
||||
list_hashed_filename_targets (list, fmt)
|
||||
WORD_LIST *list;
|
||||
int fmt;
|
||||
{
|
||||
int all_found, multiple;
|
||||
char *target;
|
||||
WORD_LIST *l;
|
||||
|
||||
all_found = 1;
|
||||
multiple = list->next != 0;
|
||||
|
||||
for (l = list; l; l = l->next)
|
||||
{
|
||||
target = phash_search (l->word->word);
|
||||
if (target == 0)
|
||||
{
|
||||
all_found = 0;
|
||||
sh_notfound (l->word->word);
|
||||
continue;
|
||||
}
|
||||
if (fmt)
|
||||
printf ("builtin hash -p %s %s\n", target, l->word->word);
|
||||
else
|
||||
{
|
||||
if (multiple)
|
||||
printf ("%s\t", l->word->word);
|
||||
printf ("%s\n", target);
|
||||
}
|
||||
}
|
||||
|
||||
return (all_found ? EXECUTION_SUCCESS : EXECUTION_FAILURE);
|
||||
}
|
||||
@@ -1,263 +0,0 @@
|
||||
This file is kill.def, from which is created kill.c.
|
||||
It implements the builtin "kill" in Bash.
|
||||
|
||||
Copyright (C) 1987-2009 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Bash, the Bourne Again SHell.
|
||||
|
||||
Bash is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Bash is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Bash. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
$PRODUCES kill.c
|
||||
|
||||
$BUILTIN kill
|
||||
$FUNCTION kill_builtin
|
||||
$SHORT_DOC kill [-s sigspec | -n signum | -sigspec] pid | jobspec ... or kill -l [sigspec]
|
||||
Send a signal to a job.
|
||||
|
||||
Send the processes identified by PID or JOBSPEC the signal named by
|
||||
SIGSPEC or SIGNUM. If neither SIGSPEC nor SIGNUM is present, then
|
||||
SIGTERM is assumed.
|
||||
|
||||
Options:
|
||||
-s sig SIG is a signal name
|
||||
-n sig SIG is a signal number
|
||||
-l list the signal names; if arguments follow `-l' they are
|
||||
assumed to be signal numbers for which names should be listed
|
||||
|
||||
Kill is a shell builtin for two reasons: it allows job IDs to be used
|
||||
instead of process IDs, and allows processes to be killed if the limit
|
||||
on processes that you can create is reached.
|
||||
|
||||
Exit Status:
|
||||
Returns success unless an invalid option is given or an error occurs.
|
||||
$END
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#if defined (HAVE_UNISTD_H)
|
||||
# ifdef _MINIX
|
||||
# include <sys/types.h>
|
||||
# endif
|
||||
# include <unistd.h>
|
||||
#endif
|
||||
|
||||
#include "../bashansi.h"
|
||||
#include "../bashintl.h"
|
||||
|
||||
#include "../shell.h"
|
||||
#include "../trap.h"
|
||||
#include "../jobs.h"
|
||||
#include "common.h"
|
||||
|
||||
/* Not all systems declare ERRNO in errno.h... and some systems #define it! */
|
||||
#if !defined (errno)
|
||||
extern int errno;
|
||||
#endif /* !errno */
|
||||
|
||||
extern int posixly_correct;
|
||||
|
||||
static void kill_error __P((pid_t, int));
|
||||
|
||||
#if !defined (CONTINUE_AFTER_KILL_ERROR)
|
||||
# define CONTINUE_OR_FAIL return (EXECUTION_FAILURE)
|
||||
#else
|
||||
# define CONTINUE_OR_FAIL goto continue_killing
|
||||
#endif /* CONTINUE_AFTER_KILL_ERROR */
|
||||
|
||||
/* Here is the kill builtin. We only have it so that people can type
|
||||
kill -KILL %1? No, if you fill up the process table this way you
|
||||
can still kill some. */
|
||||
int
|
||||
kill_builtin (list)
|
||||
WORD_LIST *list;
|
||||
{
|
||||
int sig, any_succeeded, listing, saw_signal, dflags;
|
||||
char *sigspec, *word;
|
||||
pid_t pid;
|
||||
intmax_t pid_value;
|
||||
|
||||
if (list == 0)
|
||||
{
|
||||
builtin_usage ();
|
||||
return (EXECUTION_FAILURE);
|
||||
}
|
||||
|
||||
any_succeeded = listing = saw_signal = 0;
|
||||
sig = SIGTERM;
|
||||
sigspec = "TERM";
|
||||
|
||||
dflags = DSIG_NOCASE | ((posixly_correct == 0) ? DSIG_SIGPREFIX : 0);
|
||||
/* Process options. */
|
||||
while (list)
|
||||
{
|
||||
word = list->word->word;
|
||||
|
||||
if (ISOPTION (word, 'l'))
|
||||
{
|
||||
listing++;
|
||||
list = list->next;
|
||||
}
|
||||
else if (ISOPTION (word, 's') || ISOPTION (word, 'n'))
|
||||
{
|
||||
list = list->next;
|
||||
if (list)
|
||||
{
|
||||
sigspec = list->word->word;
|
||||
if (sigspec[0] == '0' && sigspec[1] == '\0')
|
||||
sig = 0;
|
||||
else
|
||||
sig = decode_signal (sigspec, dflags);
|
||||
list = list->next;
|
||||
saw_signal++;
|
||||
}
|
||||
else
|
||||
{
|
||||
sh_needarg (word);
|
||||
return (EXECUTION_FAILURE);
|
||||
}
|
||||
}
|
||||
else if (ISOPTION (word, '-'))
|
||||
{
|
||||
list = list->next;
|
||||
break;
|
||||
}
|
||||
else if (ISOPTION (word, '?'))
|
||||
{
|
||||
builtin_usage ();
|
||||
return (EXECUTION_SUCCESS);
|
||||
}
|
||||
/* If this is a signal specification then process it. We only process
|
||||
the first one seen; other arguments may signify process groups (e.g,
|
||||
-num == process group num). */
|
||||
else if (*word == '-' && saw_signal == 0)
|
||||
{
|
||||
sigspec = word + 1;
|
||||
sig = decode_signal (sigspec, dflags);
|
||||
saw_signal++;
|
||||
list = list->next;
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
|
||||
if (listing)
|
||||
return (display_signal_list (list, 0));
|
||||
|
||||
/* OK, we are killing processes. */
|
||||
if (sig == NO_SIG)
|
||||
{
|
||||
sh_invalidsig (sigspec);
|
||||
return (EXECUTION_FAILURE);
|
||||
}
|
||||
|
||||
if (list == 0)
|
||||
{
|
||||
builtin_usage ();
|
||||
return (EXECUTION_FAILURE);
|
||||
}
|
||||
|
||||
while (list)
|
||||
{
|
||||
word = list->word->word;
|
||||
|
||||
if (*word == '-')
|
||||
word++;
|
||||
|
||||
/* Use the entire argument in case of minus sign presence. */
|
||||
if (*word && legal_number (list->word->word, &pid_value) && (pid_value == (pid_t)pid_value))
|
||||
{
|
||||
pid = (pid_t) pid_value;
|
||||
|
||||
if (kill_pid (pid, sig, pid < -1) < 0)
|
||||
{
|
||||
if (errno == EINVAL)
|
||||
sh_invalidsig (sigspec);
|
||||
else
|
||||
kill_error (pid, errno);
|
||||
CONTINUE_OR_FAIL;
|
||||
}
|
||||
else
|
||||
any_succeeded++;
|
||||
}
|
||||
#if defined (JOB_CONTROL)
|
||||
else if (*list->word->word && *list->word->word != '%')
|
||||
{
|
||||
builtin_error (_("%s: arguments must be process or job IDs"), list->word->word);
|
||||
CONTINUE_OR_FAIL;
|
||||
}
|
||||
else if (*word)
|
||||
/* Posix.2 says you can kill without job control active (4.32.4) */
|
||||
{ /* Must be a job spec. Check it out. */
|
||||
int job;
|
||||
sigset_t set, oset;
|
||||
JOB *j;
|
||||
|
||||
BLOCK_CHILD (set, oset);
|
||||
job = get_job_spec (list);
|
||||
|
||||
if (INVALID_JOB (job))
|
||||
{
|
||||
if (job != DUP_JOB)
|
||||
sh_badjob (list->word->word);
|
||||
UNBLOCK_CHILD (oset);
|
||||
CONTINUE_OR_FAIL;
|
||||
}
|
||||
|
||||
j = get_job_by_jid (job);
|
||||
/* Job spec used. Kill the process group. If the job was started
|
||||
without job control, then its pgrp == shell_pgrp, so we have
|
||||
to be careful. We take the pid of the first job in the pipeline
|
||||
in that case. */
|
||||
pid = IS_JOBCONTROL (job) ? j->pgrp : j->pipe->pid;
|
||||
|
||||
UNBLOCK_CHILD (oset);
|
||||
|
||||
if (kill_pid (pid, sig, 1) < 0)
|
||||
{
|
||||
if (errno == EINVAL)
|
||||
sh_invalidsig (sigspec);
|
||||
else
|
||||
kill_error (pid, errno);
|
||||
CONTINUE_OR_FAIL;
|
||||
}
|
||||
else
|
||||
any_succeeded++;
|
||||
}
|
||||
#endif /* !JOB_CONTROL */
|
||||
else
|
||||
{
|
||||
sh_badpid (list->word->word);
|
||||
CONTINUE_OR_FAIL;
|
||||
}
|
||||
continue_killing:
|
||||
list = list->next;
|
||||
}
|
||||
|
||||
return (any_succeeded ? EXECUTION_SUCCESS : EXECUTION_FAILURE);
|
||||
}
|
||||
|
||||
static void
|
||||
kill_error (pid, e)
|
||||
pid_t pid;
|
||||
int e;
|
||||
{
|
||||
char *x;
|
||||
|
||||
x = strerror (e);
|
||||
if (x == 0)
|
||||
x = _("Unknown error");
|
||||
builtin_error ("(%ld) - %s", (long)pid, x);
|
||||
}
|
||||
@@ -1,357 +0,0 @@
|
||||
This file is mapfile.def, from which is created mapfile.c.
|
||||
It implements the builtin "mapfile" in Bash.
|
||||
|
||||
Copyright (C) 2005-2006 Rocky Bernstein for Free Software Foundation, Inc.
|
||||
Copyright (C) 2008-2010 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Bash, the Bourne Again SHell.
|
||||
|
||||
Bash is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Bash is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Bash. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
$PRODUCES mapfile.c
|
||||
|
||||
$BUILTIN mapfile
|
||||
$FUNCTION mapfile_builtin
|
||||
$SHORT_DOC mapfile [-n count] [-O origin] [-s count] [-t] [-u fd] [-C callback] [-c quantum] [array]
|
||||
Read lines from the standard input into an indexed array variable.
|
||||
|
||||
Read lines from the standard input into the indexed array variable ARRAY, or
|
||||
from file descriptor FD if the -u option is supplied. The variable MAPFILE
|
||||
is the default ARRAY.
|
||||
|
||||
Options:
|
||||
-n count Copy at most COUNT lines. If COUNT is 0, all lines are copied.
|
||||
-O origin Begin assigning to ARRAY at index ORIGIN. The default index is 0.
|
||||
-s count Discard the first COUNT lines read.
|
||||
-t Remove a trailing newline from each line read.
|
||||
-u fd Read lines from file descriptor FD instead of the standard input.
|
||||
-C callback Evaluate CALLBACK each time QUANTUM lines are read.
|
||||
-c quantum Specify the number of lines read between each call to CALLBACK.
|
||||
|
||||
Arguments:
|
||||
ARRAY Array variable name to use for file data.
|
||||
|
||||
If -C is supplied without -c, the default quantum is 5000. When
|
||||
CALLBACK is evaluated, it is supplied the index of the next array
|
||||
element to be assigned as an additional argument.
|
||||
|
||||
If not supplied with an explicit origin, mapfile will clear ARRAY before
|
||||
assigning to it.
|
||||
|
||||
Exit Status:
|
||||
Returns success unless an invalid option is given or ARRAY is readonly or
|
||||
not an indexed array.
|
||||
$END
|
||||
|
||||
$BUILTIN readarray
|
||||
$FUNCTION mapfile_builtin
|
||||
$SHORT_DOC readarray [-n count] [-O origin] [-s count] [-t] [-u fd] [-C callback] [-c quantum] [array]
|
||||
Read lines from a file into an array variable.
|
||||
|
||||
A synonym for `mapfile'.
|
||||
$END
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include "builtins.h"
|
||||
#include "posixstat.h"
|
||||
|
||||
#if defined (HAVE_UNISTD_H)
|
||||
# include <unistd.h>
|
||||
#endif
|
||||
|
||||
#include "bashansi.h"
|
||||
#include "bashintl.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "../bashintl.h"
|
||||
#include "../shell.h"
|
||||
#include "common.h"
|
||||
#include "bashgetopt.h"
|
||||
|
||||
#if !defined (errno)
|
||||
extern int errno;
|
||||
#endif
|
||||
|
||||
#if defined (ARRAY_VARS)
|
||||
|
||||
static int run_callback __P((const char *, unsigned int, const char *));
|
||||
|
||||
#define DEFAULT_ARRAY_NAME "MAPFILE"
|
||||
#define DEFAULT_VARIABLE_NAME "MAPLINE" /* not used right now */
|
||||
|
||||
/* The value specifying how frequently `mapfile' calls the callback. */
|
||||
#define DEFAULT_QUANTUM 5000
|
||||
|
||||
/* Values for FLAGS */
|
||||
#define MAPF_CLEARARRAY 0x01
|
||||
#define MAPF_CHOP 0x02
|
||||
|
||||
static int
|
||||
run_callback (callback, curindex, curline)
|
||||
const char *callback;
|
||||
unsigned int curindex;
|
||||
const char *curline;
|
||||
{
|
||||
unsigned int execlen;
|
||||
char *execstr, *qline;
|
||||
int flags;
|
||||
|
||||
qline = sh_single_quote (curline);
|
||||
execlen = strlen (callback) + strlen (qline) + 10;
|
||||
/* 1 for each space between %s and %d,
|
||||
another 1 for the last nul char for C string. */
|
||||
execlen += 3;
|
||||
execstr = xmalloc (execlen);
|
||||
|
||||
flags = SEVAL_NOHIST;
|
||||
#if 0
|
||||
if (interactive)
|
||||
flags |= SEVAL_INTERACT;
|
||||
#endif
|
||||
snprintf (execstr, execlen, "%s %d %s", callback, curindex, qline);
|
||||
free (qline);
|
||||
return parse_and_execute (execstr, NULL, flags);
|
||||
}
|
||||
|
||||
static void
|
||||
do_chop(line)
|
||||
char * line;
|
||||
{
|
||||
int length;
|
||||
|
||||
length = strlen (line);
|
||||
if (length && line[length-1] == '\n')
|
||||
line[length-1] = '\0';
|
||||
}
|
||||
|
||||
static int
|
||||
mapfile (fd, line_count_goal, origin, nskip, callback_quantum, callback, array_name, flags)
|
||||
int fd;
|
||||
long line_count_goal, origin, nskip, callback_quantum;
|
||||
char *callback, *array_name;
|
||||
int flags;
|
||||
{
|
||||
char *line;
|
||||
size_t line_length;
|
||||
unsigned int array_index, line_count;
|
||||
SHELL_VAR *entry;
|
||||
int unbuffered_read;
|
||||
|
||||
line = NULL;
|
||||
line_length = 0;
|
||||
unbuffered_read = 0;
|
||||
|
||||
/* The following check should be done before reading any lines. Doing it
|
||||
here allows us to call bind_array_element instead of bind_array_variable
|
||||
and skip the variable lookup on every call. */
|
||||
entry = find_or_make_array_variable (array_name, 1);
|
||||
if (entry == 0 || readonly_p (entry) || noassign_p (entry))
|
||||
{
|
||||
if (entry && readonly_p (entry))
|
||||
err_readonly (array_name);
|
||||
|
||||
return (EXECUTION_FAILURE);
|
||||
}
|
||||
else if (array_p (entry) == 0)
|
||||
{
|
||||
builtin_error (_("%s: not an indexed array"), array_name);
|
||||
return (EXECUTION_FAILURE);
|
||||
}
|
||||
|
||||
if (flags & MAPF_CLEARARRAY)
|
||||
array_flush (array_cell (entry));
|
||||
|
||||
#ifndef __CYGWIN__
|
||||
unbuffered_read = (lseek (fd, 0L, SEEK_CUR) < 0) && (errno == ESPIPE);
|
||||
#else
|
||||
unbuffered_read = 1;
|
||||
#endif
|
||||
|
||||
zreset ();
|
||||
|
||||
/* Skip any lines at beginning of file? */
|
||||
for (line_count = 0; line_count < nskip; line_count++)
|
||||
if (zgetline (fd, &line, &line_length, unbuffered_read) < 0)
|
||||
break;
|
||||
|
||||
line = 0;
|
||||
line_length = 0;
|
||||
|
||||
/* Reset the buffer for bash own stream */
|
||||
interrupt_immediately++;
|
||||
for (array_index = origin, line_count = 1;
|
||||
zgetline (fd, &line, &line_length, unbuffered_read) != -1;
|
||||
array_index++, line_count++)
|
||||
{
|
||||
/* Have we exceeded # of lines to store? */
|
||||
if (line_count_goal != 0 && line_count > line_count_goal)
|
||||
break;
|
||||
|
||||
/* Remove trailing newlines? */
|
||||
if (flags & MAPF_CHOP)
|
||||
do_chop (line);
|
||||
|
||||
/* Has a callback been registered and if so is it time to call it? */
|
||||
if (callback && line_count && (line_count % callback_quantum) == 0)
|
||||
{
|
||||
run_callback (callback, array_index, line);
|
||||
|
||||
/* Reset the buffer for bash own stream. */
|
||||
if (unbuffered_read == 0)
|
||||
zsyncfd (fd);
|
||||
}
|
||||
|
||||
bind_array_element (entry, array_index, line, 0);
|
||||
}
|
||||
|
||||
xfree (line);
|
||||
|
||||
if (unbuffered_read == 0)
|
||||
zsyncfd (fd);
|
||||
|
||||
interrupt_immediately--;
|
||||
return EXECUTION_SUCCESS;
|
||||
}
|
||||
|
||||
int
|
||||
mapfile_builtin (list)
|
||||
WORD_LIST *list;
|
||||
{
|
||||
int opt, code, fd, clear_array, flags;
|
||||
intmax_t intval;
|
||||
long lines, origin, nskip, callback_quantum;
|
||||
char *array_name, *callback;
|
||||
|
||||
clear_array = 1;
|
||||
fd = 0;
|
||||
lines = origin = nskip = 0;
|
||||
flags = MAPF_CLEARARRAY;
|
||||
callback_quantum = DEFAULT_QUANTUM;
|
||||
callback = 0;
|
||||
|
||||
reset_internal_getopt ();
|
||||
while ((opt = internal_getopt (list, "u:n:O:tC:c:s:")) != -1)
|
||||
{
|
||||
switch (opt)
|
||||
{
|
||||
case 'u':
|
||||
code = legal_number (list_optarg, &intval);
|
||||
if (code == 0 || intval < 0 || intval != (int)intval)
|
||||
{
|
||||
builtin_error (_("%s: invalid file descriptor specification"), list_optarg);
|
||||
return (EXECUTION_FAILURE);
|
||||
}
|
||||
else
|
||||
fd = intval;
|
||||
|
||||
if (sh_validfd (fd) == 0)
|
||||
{
|
||||
builtin_error (_("%d: invalid file descriptor: %s"), fd, strerror (errno));
|
||||
return (EXECUTION_FAILURE);
|
||||
}
|
||||
break;
|
||||
|
||||
case 'n':
|
||||
code = legal_number (list_optarg, &intval);
|
||||
if (code == 0 || intval < 0 || intval != (unsigned)intval)
|
||||
{
|
||||
builtin_error (_("%s: invalid line count"), list_optarg);
|
||||
return (EXECUTION_FAILURE);
|
||||
}
|
||||
else
|
||||
lines = intval;
|
||||
break;
|
||||
|
||||
case 'O':
|
||||
code = legal_number (list_optarg, &intval);
|
||||
if (code == 0 || intval < 0 || intval != (unsigned)intval)
|
||||
{
|
||||
builtin_error (_("%s: invalid array origin"), list_optarg);
|
||||
return (EXECUTION_FAILURE);
|
||||
}
|
||||
else
|
||||
origin = intval;
|
||||
flags &= ~MAPF_CLEARARRAY;
|
||||
break;
|
||||
case 't':
|
||||
flags |= MAPF_CHOP;
|
||||
break;
|
||||
case 'C':
|
||||
callback = list_optarg;
|
||||
break;
|
||||
case 'c':
|
||||
code = legal_number (list_optarg, &intval);
|
||||
if (code == 0 || intval <= 0 || intval != (unsigned)intval)
|
||||
{
|
||||
builtin_error (_("%s: invalid callback quantum"), list_optarg);
|
||||
return (EXECUTION_FAILURE);
|
||||
}
|
||||
else
|
||||
callback_quantum = intval;
|
||||
break;
|
||||
case 's':
|
||||
code = legal_number (list_optarg, &intval);
|
||||
if (code == 0 || intval < 0 || intval != (unsigned)intval)
|
||||
{
|
||||
builtin_error (_("%s: invalid line count"), list_optarg);
|
||||
return (EXECUTION_FAILURE);
|
||||
}
|
||||
else
|
||||
nskip = intval;
|
||||
break;
|
||||
default:
|
||||
builtin_usage ();
|
||||
return (EX_USAGE);
|
||||
}
|
||||
}
|
||||
list = loptend;
|
||||
|
||||
if (list == 0)
|
||||
array_name = DEFAULT_ARRAY_NAME;
|
||||
else if (list->word == 0 || list->word->word == 0)
|
||||
{
|
||||
builtin_error ("internal error: getting variable name");
|
||||
return (EXECUTION_FAILURE);
|
||||
}
|
||||
else if (list->word->word[0] == '\0')
|
||||
{
|
||||
builtin_error (_("empty array variable name"));
|
||||
return (EX_USAGE);
|
||||
}
|
||||
else
|
||||
array_name = list->word->word;
|
||||
|
||||
if (legal_identifier (array_name) == 0 && valid_array_reference (array_name) == 0)
|
||||
{
|
||||
sh_invalidid (array_name);
|
||||
return (EXECUTION_FAILURE);
|
||||
}
|
||||
|
||||
return mapfile (fd, lines, origin, nskip, callback_quantum, callback, array_name, flags);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
int
|
||||
mapfile_builtin (list)
|
||||
WORD_LIST *list;
|
||||
{
|
||||
builtin_error (_("array variable support required"));
|
||||
return (EXECUTION_FAILURE);
|
||||
}
|
||||
|
||||
#endif /* ARRAY_VARS */
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,985 +0,0 @@
|
||||
This file is read.def, from which is created read.c.
|
||||
It implements the builtin "read" in Bash.
|
||||
|
||||
Copyright (C) 1987-2009 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Bash, the Bourne Again SHell.
|
||||
|
||||
Bash is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Bash is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Bash. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
$PRODUCES read.c
|
||||
|
||||
$BUILTIN read
|
||||
$FUNCTION read_builtin
|
||||
$SHORT_DOC read [-ers] [-a array] [-d delim] [-i text] [-n nchars] [-N nchars] [-p prompt] [-t timeout] [-u fd] [name ...]
|
||||
Read a line from the standard input and split it into fields.
|
||||
|
||||
Reads a single line from the standard input, or from file descriptor FD
|
||||
if the -u option is supplied. The line is split into fields as with word
|
||||
splitting, and the first word is assigned to the first NAME, the second
|
||||
word to the second NAME, and so on, with any leftover words assigned to
|
||||
the last NAME. Only the characters found in $IFS are recognized as word
|
||||
delimiters.
|
||||
|
||||
If no NAMEs are supplied, the line read is stored in the REPLY variable.
|
||||
|
||||
Options:
|
||||
-a array assign the words read to sequential indices of the array
|
||||
variable ARRAY, starting at zero
|
||||
-d delim continue until the first character of DELIM is read, rather
|
||||
than newline
|
||||
-e use Readline to obtain the line in an interactive shell
|
||||
-i text Use TEXT as the initial text for Readline
|
||||
-n nchars return after reading NCHARS characters rather than waiting
|
||||
for a newline, but honor a delimiter if fewer than NCHARS
|
||||
characters are read before the delimiter
|
||||
-N nchars return only after reading exactly NCHARS characters, unless
|
||||
EOF is encountered or read times out, ignoring any delimiter
|
||||
-p prompt output the string PROMPT without a trailing newline before
|
||||
attempting to read
|
||||
-r do not allow backslashes to escape any characters
|
||||
-s do not echo input coming from a terminal
|
||||
-t timeout time out and return failure if a complete line of input is
|
||||
not read withint TIMEOUT seconds. The value of the TMOUT
|
||||
variable is the default timeout. TIMEOUT may be a
|
||||
fractional number. If TIMEOUT is 0, read returns success only
|
||||
if input is available on the specified file descriptor. The
|
||||
exit status is greater than 128 if the timeout is exceeded
|
||||
-u fd read from file descriptor FD instead of the standard input
|
||||
|
||||
Exit Status:
|
||||
The return code is zero, unless end-of-file is encountered, read times out,
|
||||
or an invalid file descriptor is supplied as the argument to -u.
|
||||
$END
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include "bashtypes.h"
|
||||
#include "posixstat.h"
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "bashansi.h"
|
||||
|
||||
#if defined (HAVE_UNISTD_H)
|
||||
# include <unistd.h>
|
||||
#endif
|
||||
|
||||
#include <signal.h>
|
||||
#include <errno.h>
|
||||
|
||||
#ifdef __CYGWIN__
|
||||
# include <fcntl.h>
|
||||
# include <io.h>
|
||||
#endif
|
||||
|
||||
#include "../bashintl.h"
|
||||
|
||||
#include "../shell.h"
|
||||
#include "common.h"
|
||||
#include "bashgetopt.h"
|
||||
|
||||
#include <shtty.h>
|
||||
|
||||
#if defined (READLINE)
|
||||
#include "../bashline.h"
|
||||
#include <readline/readline.h>
|
||||
#endif
|
||||
|
||||
#if defined (BUFFERED_INPUT)
|
||||
# include "input.h"
|
||||
#endif
|
||||
|
||||
#if !defined(errno)
|
||||
extern int errno;
|
||||
#endif
|
||||
|
||||
struct ttsave
|
||||
{
|
||||
int fd;
|
||||
TTYSTRUCT *attrs;
|
||||
};
|
||||
|
||||
#if defined (READLINE)
|
||||
static void reset_attempted_completion_function __P((char *));
|
||||
static int set_itext __P((void));
|
||||
static char *edit_line __P((char *, char *));
|
||||
static void set_eol_delim __P((int));
|
||||
static void reset_eol_delim __P((char *));
|
||||
#endif
|
||||
static SHELL_VAR *bind_read_variable __P((char *, char *));
|
||||
#if defined (HANDLE_MULTIBYTE)
|
||||
static int read_mbchar __P((int, char *, int, int, int));
|
||||
#endif
|
||||
static void ttyrestore __P((struct ttsave *));
|
||||
|
||||
static sighandler sigalrm __P((int));
|
||||
static void reset_alarm __P((void));
|
||||
|
||||
static procenv_t alrmbuf;
|
||||
static SigHandler *old_alrm;
|
||||
static unsigned char delim;
|
||||
|
||||
static sighandler
|
||||
sigalrm (s)
|
||||
int s;
|
||||
{
|
||||
longjmp (alrmbuf, 1);
|
||||
}
|
||||
|
||||
static void
|
||||
reset_alarm ()
|
||||
{
|
||||
set_signal_handler (SIGALRM, old_alrm);
|
||||
falarm (0, 0);
|
||||
}
|
||||
|
||||
/* Read the value of the shell variables whose names follow.
|
||||
The reading is done from the current input stream, whatever
|
||||
that may be. Successive words of the input line are assigned
|
||||
to the variables mentioned in LIST. The last variable in LIST
|
||||
gets the remainder of the words on the line. If no variables
|
||||
are mentioned in LIST, then the default variable is $REPLY. */
|
||||
int
|
||||
read_builtin (list)
|
||||
WORD_LIST *list;
|
||||
{
|
||||
register char *varname;
|
||||
int size, i, nr, pass_next, saw_escape, eof, opt, retval, code, print_ps2;
|
||||
int input_is_tty, input_is_pipe, unbuffered_read, skip_ctlesc, skip_ctlnul;
|
||||
int raw, edit, nchars, silent, have_timeout, ignore_delim, fd;
|
||||
unsigned int tmsec, tmusec;
|
||||
long ival, uval;
|
||||
intmax_t intval;
|
||||
char c;
|
||||
char *input_string, *orig_input_string, *ifs_chars, *prompt, *arrayname;
|
||||
char *e, *t, *t1, *ps2, *tofree;
|
||||
struct stat tsb;
|
||||
SHELL_VAR *var;
|
||||
TTYSTRUCT ttattrs, ttset;
|
||||
struct ttsave termsave;
|
||||
#if defined (ARRAY_VARS)
|
||||
WORD_LIST *alist;
|
||||
#endif
|
||||
#if defined (READLINE)
|
||||
char *rlbuf, *itext;
|
||||
int rlind;
|
||||
#endif
|
||||
|
||||
USE_VAR(size);
|
||||
USE_VAR(i);
|
||||
USE_VAR(pass_next);
|
||||
USE_VAR(print_ps2);
|
||||
USE_VAR(saw_escape);
|
||||
USE_VAR(input_is_pipe);
|
||||
/* USE_VAR(raw); */
|
||||
USE_VAR(edit);
|
||||
USE_VAR(tmsec);
|
||||
USE_VAR(tmusec);
|
||||
USE_VAR(nchars);
|
||||
USE_VAR(silent);
|
||||
USE_VAR(ifs_chars);
|
||||
USE_VAR(prompt);
|
||||
USE_VAR(arrayname);
|
||||
#if defined (READLINE)
|
||||
USE_VAR(rlbuf);
|
||||
USE_VAR(rlind);
|
||||
USE_VAR(itext);
|
||||
#endif
|
||||
USE_VAR(list);
|
||||
USE_VAR(ps2);
|
||||
|
||||
i = 0; /* Index into the string that we are reading. */
|
||||
raw = edit = 0; /* Not reading raw input by default. */
|
||||
silent = 0;
|
||||
arrayname = prompt = (char *)NULL;
|
||||
fd = 0; /* file descriptor to read from */
|
||||
|
||||
#if defined (READLINE)
|
||||
rlbuf = itext = (char *)0;
|
||||
rlind = 0;
|
||||
#endif
|
||||
|
||||
tmsec = tmusec = 0; /* no timeout */
|
||||
nr = nchars = input_is_tty = input_is_pipe = unbuffered_read = have_timeout = 0;
|
||||
delim = '\n'; /* read until newline */
|
||||
ignore_delim = 0;
|
||||
|
||||
reset_internal_getopt ();
|
||||
while ((opt = internal_getopt (list, "ersa:d:i:n:p:t:u:N:")) != -1)
|
||||
{
|
||||
switch (opt)
|
||||
{
|
||||
case 'r':
|
||||
raw = 1;
|
||||
break;
|
||||
case 'p':
|
||||
prompt = list_optarg;
|
||||
break;
|
||||
case 's':
|
||||
silent = 1;
|
||||
break;
|
||||
case 'e':
|
||||
#if defined (READLINE)
|
||||
edit = 1;
|
||||
#endif
|
||||
break;
|
||||
case 'i':
|
||||
#if defined (READLINE)
|
||||
itext = list_optarg;
|
||||
#endif
|
||||
break;
|
||||
#if defined (ARRAY_VARS)
|
||||
case 'a':
|
||||
arrayname = list_optarg;
|
||||
break;
|
||||
#endif
|
||||
case 't':
|
||||
code = uconvert (list_optarg, &ival, &uval);
|
||||
if (code == 0 || ival < 0 || uval < 0)
|
||||
{
|
||||
builtin_error (_("%s: invalid timeout specification"), list_optarg);
|
||||
return (EXECUTION_FAILURE);
|
||||
}
|
||||
else
|
||||
{
|
||||
have_timeout = 1;
|
||||
tmsec = ival;
|
||||
tmusec = uval;
|
||||
}
|
||||
break;
|
||||
case 'N':
|
||||
ignore_delim = 1;
|
||||
delim = -1;
|
||||
case 'n':
|
||||
code = legal_number (list_optarg, &intval);
|
||||
if (code == 0 || intval < 0 || intval != (int)intval)
|
||||
{
|
||||
sh_invalidnum (list_optarg);
|
||||
return (EXECUTION_FAILURE);
|
||||
}
|
||||
else
|
||||
nchars = intval;
|
||||
break;
|
||||
case 'u':
|
||||
code = legal_number (list_optarg, &intval);
|
||||
if (code == 0 || intval < 0 || intval != (int)intval)
|
||||
{
|
||||
builtin_error (_("%s: invalid file descriptor specification"), list_optarg);
|
||||
return (EXECUTION_FAILURE);
|
||||
}
|
||||
else
|
||||
fd = intval;
|
||||
if (sh_validfd (fd) == 0)
|
||||
{
|
||||
builtin_error (_("%d: invalid file descriptor: %s"), fd, strerror (errno));
|
||||
return (EXECUTION_FAILURE);
|
||||
}
|
||||
break;
|
||||
case 'd':
|
||||
delim = *list_optarg;
|
||||
break;
|
||||
default:
|
||||
builtin_usage ();
|
||||
return (EX_USAGE);
|
||||
}
|
||||
}
|
||||
list = loptend;
|
||||
|
||||
/* `read -t 0 var' tests whether input is available with select/FIONREAD,
|
||||
and fails if those are unavailable */
|
||||
if (have_timeout && tmsec == 0 && tmusec == 0)
|
||||
#if 0
|
||||
return (EXECUTION_FAILURE);
|
||||
#else
|
||||
return (input_avail (fd) ? EXECUTION_SUCCESS : EXECUTION_FAILURE);
|
||||
#endif
|
||||
|
||||
/* If we're asked to ignore the delimiter, make sure we do. */
|
||||
if (ignore_delim)
|
||||
delim = -1;
|
||||
|
||||
/* IF IFS is unset, we use the default of " \t\n". */
|
||||
ifs_chars = getifs ();
|
||||
if (ifs_chars == 0) /* XXX - shouldn't happen */
|
||||
ifs_chars = "";
|
||||
/* If we want to read exactly NCHARS chars, don't split on IFS */
|
||||
if (ignore_delim)
|
||||
ifs_chars = "";
|
||||
for (skip_ctlesc = skip_ctlnul = 0, e = ifs_chars; *e; e++)
|
||||
skip_ctlesc |= *e == CTLESC, skip_ctlnul |= *e == CTLNUL;
|
||||
|
||||
input_string = (char *)xmalloc (size = 112); /* XXX was 128 */
|
||||
input_string[0] = '\0';
|
||||
|
||||
/* $TMOUT, if set, is the default timeout for read. */
|
||||
if (have_timeout == 0 && (e = get_string_value ("TMOUT")))
|
||||
{
|
||||
code = uconvert (e, &ival, &uval);
|
||||
if (code == 0 || ival < 0 || uval < 0)
|
||||
tmsec = tmusec = 0;
|
||||
else
|
||||
{
|
||||
tmsec = ival;
|
||||
tmusec = uval;
|
||||
}
|
||||
}
|
||||
|
||||
begin_unwind_frame ("read_builtin");
|
||||
|
||||
#if defined (BUFFERED_INPUT)
|
||||
if (interactive == 0 && default_buffered_input >= 0 && fd_is_bash_input (fd))
|
||||
sync_buffered_stream (default_buffered_input);
|
||||
#endif
|
||||
|
||||
input_is_tty = isatty (fd);
|
||||
if (input_is_tty == 0)
|
||||
#ifndef __CYGWIN__
|
||||
input_is_pipe = (lseek (fd, 0L, SEEK_CUR) < 0) && (errno == ESPIPE);
|
||||
#else
|
||||
input_is_pipe = 1;
|
||||
#endif
|
||||
|
||||
/* If the -p, -e or -s flags were given, but input is not coming from the
|
||||
terminal, turn them off. */
|
||||
if ((prompt || edit || silent) && input_is_tty == 0)
|
||||
{
|
||||
prompt = (char *)NULL;
|
||||
#if defined (READLINE)
|
||||
itext = (char *)NULL;
|
||||
#endif
|
||||
edit = silent = 0;
|
||||
}
|
||||
|
||||
#if defined (READLINE)
|
||||
if (edit)
|
||||
add_unwind_protect (xfree, rlbuf);
|
||||
#endif
|
||||
|
||||
pass_next = 0; /* Non-zero signifies last char was backslash. */
|
||||
saw_escape = 0; /* Non-zero signifies that we saw an escape char */
|
||||
|
||||
if (tmsec > 0 || tmusec > 0)
|
||||
{
|
||||
/* Turn off the timeout if stdin is a regular file (e.g. from
|
||||
input redirection). */
|
||||
if ((fstat (fd, &tsb) < 0) || S_ISREG (tsb.st_mode))
|
||||
tmsec = tmusec = 0;
|
||||
}
|
||||
|
||||
if (tmsec > 0 || tmusec > 0)
|
||||
{
|
||||
code = setjmp (alrmbuf);
|
||||
if (code)
|
||||
{
|
||||
/* Tricky. The top of the unwind-protect stack is the free of
|
||||
input_string. We want to run all the rest and use input_string,
|
||||
so we have to remove it from the stack. */
|
||||
remove_unwind_protect ();
|
||||
run_unwind_frame ("read_builtin");
|
||||
input_string[i] = '\0'; /* make sure it's terminated */
|
||||
retval = 128+SIGALRM;
|
||||
goto assign_vars;
|
||||
}
|
||||
old_alrm = set_signal_handler (SIGALRM, sigalrm);
|
||||
add_unwind_protect (reset_alarm, (char *)NULL);
|
||||
#if defined (READLINE)
|
||||
if (edit)
|
||||
add_unwind_protect (reset_attempted_completion_function, (char *)NULL);
|
||||
#endif
|
||||
falarm (tmsec, tmusec);
|
||||
}
|
||||
|
||||
/* If we've been asked to read only NCHARS chars, or we're using some
|
||||
character other than newline to terminate the line, do the right
|
||||
thing to readline or the tty. */
|
||||
if (nchars > 0 || delim != '\n')
|
||||
{
|
||||
#if defined (READLINE)
|
||||
if (edit)
|
||||
{
|
||||
if (nchars > 0)
|
||||
{
|
||||
unwind_protect_int (rl_num_chars_to_read);
|
||||
rl_num_chars_to_read = nchars;
|
||||
}
|
||||
if (delim != '\n')
|
||||
{
|
||||
set_eol_delim (delim);
|
||||
add_unwind_protect (reset_eol_delim, (char *)NULL);
|
||||
}
|
||||
}
|
||||
else
|
||||
#endif
|
||||
if (input_is_tty)
|
||||
{
|
||||
/* ttsave() */
|
||||
termsave.fd = fd;
|
||||
ttgetattr (fd, &ttattrs);
|
||||
termsave.attrs = &ttattrs;
|
||||
|
||||
ttset = ttattrs;
|
||||
i = silent ? ttfd_cbreak (fd, &ttset) : ttfd_onechar (fd, &ttset);
|
||||
if (i < 0)
|
||||
sh_ttyerror (1);
|
||||
add_unwind_protect ((Function *)ttyrestore, (char *)&termsave);
|
||||
}
|
||||
}
|
||||
else if (silent) /* turn off echo but leave term in canonical mode */
|
||||
{
|
||||
/* ttsave (); */
|
||||
termsave.fd = fd;
|
||||
ttgetattr (fd, &ttattrs);
|
||||
termsave.attrs = &ttattrs;
|
||||
|
||||
ttset = ttattrs;
|
||||
i = ttfd_noecho (fd, &ttset); /* ttnoecho (); */
|
||||
if (i < 0)
|
||||
sh_ttyerror (1);
|
||||
|
||||
add_unwind_protect ((Function *)ttyrestore, (char *)&termsave);
|
||||
}
|
||||
|
||||
/* This *must* be the top unwind-protect on the stack, so the manipulation
|
||||
of the unwind-protect stack after the realloc() works right. */
|
||||
add_unwind_protect (xfree, input_string);
|
||||
interrupt_immediately++;
|
||||
terminate_immediately++;
|
||||
|
||||
unbuffered_read = (nchars > 0) || (delim != '\n') || input_is_pipe;
|
||||
|
||||
if (prompt && edit == 0)
|
||||
{
|
||||
fprintf (stderr, "%s", prompt);
|
||||
fflush (stderr);
|
||||
}
|
||||
|
||||
#if defined (__CYGWIN__) && defined (O_TEXT)
|
||||
setmode (0, O_TEXT);
|
||||
#endif
|
||||
|
||||
ps2 = 0;
|
||||
for (print_ps2 = eof = retval = 0;;)
|
||||
{
|
||||
#if defined (READLINE)
|
||||
if (edit)
|
||||
{
|
||||
if (rlbuf && rlbuf[rlind] == '\0')
|
||||
{
|
||||
xfree (rlbuf);
|
||||
rlbuf = (char *)0;
|
||||
}
|
||||
if (rlbuf == 0)
|
||||
{
|
||||
rlbuf = edit_line (prompt ? prompt : "", itext);
|
||||
rlind = 0;
|
||||
}
|
||||
if (rlbuf == 0)
|
||||
{
|
||||
eof = 1;
|
||||
break;
|
||||
}
|
||||
c = rlbuf[rlind++];
|
||||
}
|
||||
else
|
||||
{
|
||||
#endif
|
||||
|
||||
if (print_ps2)
|
||||
{
|
||||
if (ps2 == 0)
|
||||
ps2 = get_string_value ("PS2");
|
||||
fprintf (stderr, "%s", ps2 ? ps2 : "");
|
||||
fflush (stderr);
|
||||
print_ps2 = 0;
|
||||
}
|
||||
|
||||
if (unbuffered_read)
|
||||
retval = zread (fd, &c, 1);
|
||||
else
|
||||
retval = zreadc (fd, &c);
|
||||
|
||||
if (retval <= 0)
|
||||
{
|
||||
eof = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
#if defined (READLINE)
|
||||
}
|
||||
#endif
|
||||
|
||||
if (i + 4 >= size) /* XXX was i + 2; use i + 4 for multibyte/read_mbchar */
|
||||
{
|
||||
input_string = (char *)xrealloc (input_string, size += 128);
|
||||
remove_unwind_protect ();
|
||||
add_unwind_protect (xfree, input_string);
|
||||
}
|
||||
|
||||
/* If the next character is to be accepted verbatim, a backslash
|
||||
newline pair still disappears from the input. */
|
||||
if (pass_next)
|
||||
{
|
||||
pass_next = 0;
|
||||
if (c == '\n')
|
||||
{
|
||||
i--; /* back up over the CTLESC */
|
||||
if (interactive && input_is_tty && raw == 0)
|
||||
print_ps2 = 1;
|
||||
}
|
||||
else
|
||||
goto add_char;
|
||||
continue;
|
||||
}
|
||||
|
||||
/* This may cause problems if IFS contains CTLESC */
|
||||
if (c == '\\' && raw == 0)
|
||||
{
|
||||
pass_next++;
|
||||
if (skip_ctlesc == 0)
|
||||
{
|
||||
saw_escape++;
|
||||
input_string[i++] = CTLESC;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
if ((unsigned char)c == delim)
|
||||
break;
|
||||
|
||||
if ((skip_ctlesc == 0 && c == CTLESC) || (skip_ctlnul == 0 && c == CTLNUL))
|
||||
{
|
||||
saw_escape++;
|
||||
input_string[i++] = CTLESC;
|
||||
}
|
||||
|
||||
add_char:
|
||||
input_string[i++] = c;
|
||||
|
||||
#if defined (HANDLE_MULTIBYTE)
|
||||
if (nchars > 0 && MB_CUR_MAX > 1)
|
||||
{
|
||||
input_string[i] = '\0'; /* for simplicity and debugging */
|
||||
i += read_mbchar (fd, input_string, i, c, unbuffered_read);
|
||||
}
|
||||
#endif
|
||||
|
||||
nr++;
|
||||
|
||||
if (nchars > 0 && nr >= nchars)
|
||||
break;
|
||||
}
|
||||
input_string[i] = '\0';
|
||||
|
||||
#if 1
|
||||
if (retval < 0)
|
||||
{
|
||||
builtin_error (_("read error: %d: %s"), fd, strerror (errno));
|
||||
run_unwind_frame ("read_builtin");
|
||||
return (EXECUTION_FAILURE);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (tmsec > 0 || tmusec > 0)
|
||||
reset_alarm ();
|
||||
|
||||
if (nchars > 0 || delim != '\n')
|
||||
{
|
||||
#if defined (READLINE)
|
||||
if (edit)
|
||||
{
|
||||
if (nchars > 0)
|
||||
rl_num_chars_to_read = 0;
|
||||
if (delim != '\n')
|
||||
reset_eol_delim ((char *)NULL);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
if (input_is_tty)
|
||||
ttyrestore (&termsave);
|
||||
}
|
||||
else if (silent)
|
||||
ttyrestore (&termsave);
|
||||
|
||||
if (unbuffered_read == 0)
|
||||
zsyncfd (fd);
|
||||
|
||||
discard_unwind_frame ("read_builtin");
|
||||
|
||||
retval = eof ? EXECUTION_FAILURE : EXECUTION_SUCCESS;
|
||||
|
||||
assign_vars:
|
||||
|
||||
interrupt_immediately--;
|
||||
terminate_immediately--;
|
||||
|
||||
#if defined (ARRAY_VARS)
|
||||
/* If -a was given, take the string read, break it into a list of words,
|
||||
an assign them to `arrayname' in turn. */
|
||||
if (arrayname)
|
||||
{
|
||||
if (legal_identifier (arrayname) == 0)
|
||||
{
|
||||
sh_invalidid (arrayname);
|
||||
xfree (input_string);
|
||||
return (EXECUTION_FAILURE);
|
||||
}
|
||||
|
||||
var = find_or_make_array_variable (arrayname, 1);
|
||||
if (var == 0)
|
||||
{
|
||||
xfree (input_string);
|
||||
return EXECUTION_FAILURE; /* readonly or noassign */
|
||||
}
|
||||
array_flush (array_cell (var));
|
||||
|
||||
alist = list_string (input_string, ifs_chars, 0);
|
||||
if (alist)
|
||||
{
|
||||
if (saw_escape)
|
||||
dequote_list (alist);
|
||||
else
|
||||
word_list_remove_quoted_nulls (alist);
|
||||
assign_array_var_from_word_list (var, alist, 0);
|
||||
dispose_words (alist);
|
||||
}
|
||||
xfree (input_string);
|
||||
return (retval);
|
||||
}
|
||||
#endif /* ARRAY_VARS */
|
||||
|
||||
/* If there are no variables, save the text of the line read to the
|
||||
variable $REPLY. ksh93 strips leading and trailing IFS whitespace,
|
||||
so that `read x ; echo "$x"' and `read ; echo "$REPLY"' behave the
|
||||
same way, but I believe that the difference in behaviors is useful
|
||||
enough to not do it. Without the bash behavior, there is no way
|
||||
to read a line completely without interpretation or modification
|
||||
unless you mess with $IFS (e.g., setting it to the empty string).
|
||||
If you disagree, change the occurrences of `#if 0' to `#if 1' below. */
|
||||
if (list == 0)
|
||||
{
|
||||
#if 0
|
||||
orig_input_string = input_string;
|
||||
for (t = input_string; ifs_chars && *ifs_chars && spctabnl(*t) && isifs(*t); t++)
|
||||
;
|
||||
input_string = t;
|
||||
input_string = strip_trailing_ifs_whitespace (input_string, ifs_chars, saw_escape);
|
||||
#endif
|
||||
|
||||
if (saw_escape)
|
||||
{
|
||||
t = dequote_string (input_string);
|
||||
var = bind_variable ("REPLY", t, 0);
|
||||
free (t);
|
||||
}
|
||||
else
|
||||
var = bind_variable ("REPLY", input_string, 0);
|
||||
VUNSETATTR (var, att_invisible);
|
||||
|
||||
free (input_string);
|
||||
return (retval);
|
||||
}
|
||||
|
||||
/* This code implements the Posix.2 spec for splitting the words
|
||||
read and assigning them to variables. */
|
||||
orig_input_string = input_string;
|
||||
|
||||
/* Remove IFS white space at the beginning of the input string. If
|
||||
$IFS is null, no field splitting is performed. */
|
||||
for (t = input_string; ifs_chars && *ifs_chars && spctabnl(*t) && isifs(*t); t++)
|
||||
;
|
||||
input_string = t;
|
||||
for (; list->next; list = list->next)
|
||||
{
|
||||
varname = list->word->word;
|
||||
#if defined (ARRAY_VARS)
|
||||
if (legal_identifier (varname) == 0 && valid_array_reference (varname) == 0)
|
||||
#else
|
||||
if (legal_identifier (varname) == 0)
|
||||
#endif
|
||||
{
|
||||
sh_invalidid (varname);
|
||||
xfree (orig_input_string);
|
||||
return (EXECUTION_FAILURE);
|
||||
}
|
||||
|
||||
/* If there are more variables than words read from the input,
|
||||
the remaining variables are set to the empty string. */
|
||||
if (*input_string)
|
||||
{
|
||||
/* This call updates INPUT_STRING. */
|
||||
t = get_word_from_string (&input_string, ifs_chars, &e);
|
||||
if (t)
|
||||
*e = '\0';
|
||||
/* Don't bother to remove the CTLESC unless we added one
|
||||
somewhere while reading the string. */
|
||||
if (t && saw_escape)
|
||||
{
|
||||
t1 = dequote_string (t);
|
||||
var = bind_read_variable (varname, t1);
|
||||
xfree (t1);
|
||||
}
|
||||
else
|
||||
var = bind_read_variable (varname, t);
|
||||
}
|
||||
else
|
||||
{
|
||||
t = (char *)0;
|
||||
var = bind_read_variable (varname, "");
|
||||
}
|
||||
|
||||
FREE (t);
|
||||
if (var == 0)
|
||||
{
|
||||
xfree (orig_input_string);
|
||||
return (EXECUTION_FAILURE);
|
||||
}
|
||||
|
||||
stupidly_hack_special_variables (varname);
|
||||
VUNSETATTR (var, att_invisible);
|
||||
}
|
||||
|
||||
/* Now assign the rest of the line to the last variable argument. */
|
||||
#if defined (ARRAY_VARS)
|
||||
if (legal_identifier (list->word->word) == 0 && valid_array_reference (list->word->word) == 0)
|
||||
#else
|
||||
if (legal_identifier (list->word->word) == 0)
|
||||
#endif
|
||||
{
|
||||
sh_invalidid (list->word->word);
|
||||
xfree (orig_input_string);
|
||||
return (EXECUTION_FAILURE);
|
||||
}
|
||||
|
||||
#if 0
|
||||
/* This has to be done this way rather than using string_list
|
||||
and list_string because Posix.2 says that the last variable gets the
|
||||
remaining words and their intervening separators. */
|
||||
input_string = strip_trailing_ifs_whitespace (input_string, ifs_chars, saw_escape);
|
||||
#else
|
||||
/* Check whether or not the number of fields is exactly the same as the
|
||||
number of variables. */
|
||||
tofree = NULL;
|
||||
if (*input_string)
|
||||
{
|
||||
t1 = input_string;
|
||||
t = get_word_from_string (&input_string, ifs_chars, &e);
|
||||
if (*input_string == 0)
|
||||
tofree = input_string = t;
|
||||
else
|
||||
{
|
||||
input_string = strip_trailing_ifs_whitespace (t1, ifs_chars, saw_escape);
|
||||
tofree = t;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (saw_escape)
|
||||
{
|
||||
t = dequote_string (input_string);
|
||||
var = bind_read_variable (list->word->word, t);
|
||||
xfree (t);
|
||||
}
|
||||
else
|
||||
var = bind_read_variable (list->word->word, input_string);
|
||||
stupidly_hack_special_variables (list->word->word);
|
||||
FREE (tofree);
|
||||
|
||||
if (var)
|
||||
VUNSETATTR (var, att_invisible);
|
||||
xfree (orig_input_string);
|
||||
|
||||
return (retval);
|
||||
}
|
||||
|
||||
static SHELL_VAR *
|
||||
bind_read_variable (name, value)
|
||||
char *name, *value;
|
||||
{
|
||||
#if defined (ARRAY_VARS)
|
||||
if (valid_array_reference (name) == 0)
|
||||
return (bind_variable (name, value, 0));
|
||||
else
|
||||
return (assign_array_element (name, value, 0));
|
||||
#else /* !ARRAY_VARS */
|
||||
return bind_variable (name, value, 0);
|
||||
#endif /* !ARRAY_VARS */
|
||||
}
|
||||
|
||||
#if defined (HANDLE_MULTIBYTE)
|
||||
static int
|
||||
read_mbchar (fd, string, ind, ch, unbuffered)
|
||||
int fd;
|
||||
char *string;
|
||||
int ind, ch, unbuffered;
|
||||
{
|
||||
char mbchar[MB_LEN_MAX + 1];
|
||||
int i, n, r;
|
||||
char c;
|
||||
size_t ret;
|
||||
mbstate_t ps, ps_back;
|
||||
wchar_t wc;
|
||||
|
||||
memset (&ps, '\0', sizeof (mbstate_t));
|
||||
memset (&ps_back, '\0', sizeof (mbstate_t));
|
||||
|
||||
mbchar[0] = ch;
|
||||
i = 1;
|
||||
for (n = 0; n <= MB_LEN_MAX; n++)
|
||||
{
|
||||
ps_back = ps;
|
||||
ret = mbrtowc (&wc, mbchar, i, &ps);
|
||||
if (ret == (size_t)-2)
|
||||
{
|
||||
ps = ps_back;
|
||||
if (unbuffered)
|
||||
r = zread (fd, &c, 1);
|
||||
else
|
||||
r = zreadc (fd, &c);
|
||||
if (r < 0)
|
||||
goto mbchar_return;
|
||||
mbchar[i++] = c;
|
||||
continue;
|
||||
}
|
||||
else if (ret == (size_t)-1 || ret == (size_t)0 || ret > (size_t)0)
|
||||
break;
|
||||
}
|
||||
|
||||
mbchar_return:
|
||||
if (i > 1) /* read a multibyte char */
|
||||
/* mbchar[0] is already string[ind-1] */
|
||||
for (r = 1; r < i; r++)
|
||||
string[ind+r-1] = mbchar[r];
|
||||
return i - 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
static void
|
||||
ttyrestore (ttp)
|
||||
struct ttsave *ttp;
|
||||
{
|
||||
ttsetattr (ttp->fd, ttp->attrs);
|
||||
}
|
||||
|
||||
#if defined (READLINE)
|
||||
static rl_completion_func_t *old_attempted_completion_function = 0;
|
||||
static rl_hook_func_t *old_startup_hook;
|
||||
static char *deftext;
|
||||
|
||||
static void
|
||||
reset_attempted_completion_function (cp)
|
||||
char *cp;
|
||||
{
|
||||
if (rl_attempted_completion_function == 0 && old_attempted_completion_function)
|
||||
rl_attempted_completion_function = old_attempted_completion_function;
|
||||
}
|
||||
|
||||
static int
|
||||
set_itext ()
|
||||
{
|
||||
int r1, r2;
|
||||
|
||||
r1 = r2 = 0;
|
||||
if (old_startup_hook)
|
||||
r1 = (*old_startup_hook) ();
|
||||
if (deftext)
|
||||
{
|
||||
r2 = rl_insert_text (deftext);
|
||||
deftext = (char *)NULL;
|
||||
rl_startup_hook = old_startup_hook;
|
||||
old_startup_hook = (rl_hook_func_t *)NULL;
|
||||
}
|
||||
return (r1 || r2);
|
||||
}
|
||||
|
||||
static char *
|
||||
edit_line (p, itext)
|
||||
char *p;
|
||||
char *itext;
|
||||
{
|
||||
char *ret;
|
||||
int len;
|
||||
|
||||
if (bash_readline_initialized == 0)
|
||||
initialize_readline ();
|
||||
|
||||
old_attempted_completion_function = rl_attempted_completion_function;
|
||||
rl_attempted_completion_function = (rl_completion_func_t *)NULL;
|
||||
if (itext)
|
||||
{
|
||||
old_startup_hook = rl_startup_hook;
|
||||
rl_startup_hook = set_itext;
|
||||
deftext = itext;
|
||||
}
|
||||
ret = readline (p);
|
||||
rl_attempted_completion_function = old_attempted_completion_function;
|
||||
old_attempted_completion_function = (rl_completion_func_t *)NULL;
|
||||
|
||||
if (ret == 0)
|
||||
return ret;
|
||||
len = strlen (ret);
|
||||
ret = (char *)xrealloc (ret, len + 2);
|
||||
ret[len++] = delim;
|
||||
ret[len] = '\0';
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int old_delim_ctype;
|
||||
static rl_command_func_t *old_delim_func;
|
||||
static int old_newline_ctype;
|
||||
static rl_command_func_t *old_newline_func;
|
||||
|
||||
static unsigned char delim_char;
|
||||
|
||||
static void
|
||||
set_eol_delim (c)
|
||||
int c;
|
||||
{
|
||||
Keymap cmap;
|
||||
|
||||
if (bash_readline_initialized == 0)
|
||||
initialize_readline ();
|
||||
cmap = rl_get_keymap ();
|
||||
|
||||
/* Change newline to self-insert */
|
||||
old_newline_ctype = cmap[RETURN].type;
|
||||
old_newline_func = cmap[RETURN].function;
|
||||
cmap[RETURN].type = ISFUNC;
|
||||
cmap[RETURN].function = rl_insert;
|
||||
|
||||
/* Bind the delimiter character to accept-line. */
|
||||
old_delim_ctype = cmap[c].type;
|
||||
old_delim_func = cmap[c].function;
|
||||
cmap[c].type = ISFUNC;
|
||||
cmap[c].function = rl_newline;
|
||||
|
||||
delim_char = c;
|
||||
}
|
||||
|
||||
static void
|
||||
reset_eol_delim (cp)
|
||||
char *cp;
|
||||
{
|
||||
Keymap cmap;
|
||||
|
||||
cmap = rl_get_keymap ();
|
||||
|
||||
cmap[RETURN].type = old_newline_ctype;
|
||||
cmap[RETURN].function = old_newline_func;
|
||||
|
||||
cmap[delim_char].type = old_delim_ctype;
|
||||
cmap[delim_char].function = old_delim_func;
|
||||
}
|
||||
#endif
|
||||
@@ -1,514 +0,0 @@
|
||||
This file is setattr.def, from which is created setattr.c.
|
||||
It implements the builtins "export" and "readonly", in Bash.
|
||||
|
||||
Copyright (C) 1987-2010 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Bash, the Bourne Again SHell.
|
||||
|
||||
Bash is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Bash is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Bash. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
$PRODUCES setattr.c
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#if defined (HAVE_UNISTD_H)
|
||||
# ifdef _MINIX
|
||||
# include <sys/types.h>
|
||||
# endif
|
||||
# include <unistd.h>
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include "../bashansi.h"
|
||||
#include "../bashintl.h"
|
||||
|
||||
#include "../shell.h"
|
||||
#include "common.h"
|
||||
#include "bashgetopt.h"
|
||||
|
||||
extern int posixly_correct;
|
||||
extern int array_needs_making;
|
||||
extern char *this_command_name;
|
||||
extern sh_builtin_func_t *this_shell_builtin;
|
||||
|
||||
#ifdef ARRAY_VARS
|
||||
extern int declare_builtin __P((WORD_LIST *));
|
||||
#endif
|
||||
|
||||
#define READONLY_OR_EXPORT \
|
||||
(this_shell_builtin == readonly_builtin || this_shell_builtin == export_builtin)
|
||||
|
||||
$BUILTIN export
|
||||
$FUNCTION export_builtin
|
||||
$SHORT_DOC export [-fn] [name[=value] ...] or export -p
|
||||
Set export attribute for shell variables.
|
||||
|
||||
Marks each NAME for automatic export to the environment of subsequently
|
||||
executed commands. If VALUE is supplied, assign VALUE before exporting.
|
||||
|
||||
Options:
|
||||
-f refer to shell functions
|
||||
-n remove the export property from each NAME
|
||||
-p display a list of all exported variables and functions
|
||||
|
||||
An argument of `--' disables further option processing.
|
||||
|
||||
Exit Status:
|
||||
Returns success unless an invalid option is given or NAME is invalid.
|
||||
$END
|
||||
|
||||
/* For each variable name in LIST, make that variable appear in the
|
||||
environment passed to simple commands. If there is no LIST, then
|
||||
print all such variables. An argument of `-n' says to remove the
|
||||
exported attribute from variables named in LIST. An argument of
|
||||
-f indicates that the names present in LIST refer to functions. */
|
||||
int
|
||||
export_builtin (list)
|
||||
register WORD_LIST *list;
|
||||
{
|
||||
return (set_or_show_attributes (list, att_exported, 0));
|
||||
}
|
||||
|
||||
$BUILTIN readonly
|
||||
$FUNCTION readonly_builtin
|
||||
$SHORT_DOC readonly [-af] [name[=value] ...] or readonly -p
|
||||
Mark shell variables as unchangeable.
|
||||
|
||||
Mark each NAME as read-only; the values of these NAMEs may not be
|
||||
changed by subsequent assignment. If VALUE is supplied, assign VALUE
|
||||
before marking as read-only.
|
||||
|
||||
Options:
|
||||
-a refer to indexed array variables
|
||||
-A refer to associative array variables
|
||||
-f refer to shell functions
|
||||
-p display a list of all readonly variables and functions
|
||||
|
||||
An argument of `--' disables further option processing.
|
||||
|
||||
Exit Status:
|
||||
Returns success unless an invalid option is given or NAME is invalid.
|
||||
$END
|
||||
|
||||
/* For each variable name in LIST, make that variable readonly. Given an
|
||||
empty LIST, print out all existing readonly variables. */
|
||||
int
|
||||
readonly_builtin (list)
|
||||
register WORD_LIST *list;
|
||||
{
|
||||
return (set_or_show_attributes (list, att_readonly, 0));
|
||||
}
|
||||
|
||||
#if defined (ARRAY_VARS)
|
||||
# define ATTROPTS "aAfnp"
|
||||
#else
|
||||
# define ATTROPTS "fnp"
|
||||
#endif
|
||||
|
||||
/* For each variable name in LIST, make that variable have the specified
|
||||
ATTRIBUTE. An arg of `-n' says to remove the attribute from the the
|
||||
remaining names in LIST (doesn't work for readonly). */
|
||||
int
|
||||
set_or_show_attributes (list, attribute, nodefs)
|
||||
register WORD_LIST *list;
|
||||
int attribute, nodefs;
|
||||
{
|
||||
register SHELL_VAR *var;
|
||||
int assign, undo, any_failed, assign_error, opt;
|
||||
int functions_only, arrays_only, assoc_only;
|
||||
int aflags;
|
||||
char *name;
|
||||
#if defined (ARRAY_VARS)
|
||||
WORD_LIST *nlist, *tlist;
|
||||
WORD_DESC *w;
|
||||
#endif
|
||||
|
||||
functions_only = arrays_only = assoc_only = 0;
|
||||
undo = any_failed = assign_error = 0;
|
||||
/* Read arguments from the front of the list. */
|
||||
reset_internal_getopt ();
|
||||
while ((opt = internal_getopt (list, ATTROPTS)) != -1)
|
||||
{
|
||||
switch (opt)
|
||||
{
|
||||
case 'n':
|
||||
undo = 1;
|
||||
break;
|
||||
case 'f':
|
||||
functions_only = 1;
|
||||
break;
|
||||
#if defined (ARRAY_VARS)
|
||||
case 'a':
|
||||
arrays_only = 1;
|
||||
break;
|
||||
case 'A':
|
||||
assoc_only = 1;
|
||||
break;
|
||||
#endif
|
||||
case 'p':
|
||||
break;
|
||||
default:
|
||||
builtin_usage ();
|
||||
return (EX_USAGE);
|
||||
}
|
||||
}
|
||||
list = loptend;
|
||||
|
||||
if (list)
|
||||
{
|
||||
if (attribute & att_exported)
|
||||
array_needs_making = 1;
|
||||
|
||||
/* Cannot undo readonly status, silently disallowed. */
|
||||
if (undo && (attribute & att_readonly))
|
||||
attribute &= ~att_readonly;
|
||||
|
||||
while (list)
|
||||
{
|
||||
name = list->word->word;
|
||||
|
||||
if (functions_only) /* xxx -f name */
|
||||
{
|
||||
var = find_function (name);
|
||||
if (var == 0)
|
||||
{
|
||||
builtin_error (_("%s: not a function"), name);
|
||||
any_failed++;
|
||||
}
|
||||
else
|
||||
SETVARATTR (var, attribute, undo);
|
||||
|
||||
list = list->next;
|
||||
continue;
|
||||
}
|
||||
|
||||
/* xxx [-np] name[=value] */
|
||||
assign = assignment (name, 0);
|
||||
|
||||
aflags = 0;
|
||||
if (assign)
|
||||
{
|
||||
name[assign] = '\0';
|
||||
if (name[assign - 1] == '+')
|
||||
{
|
||||
aflags |= ASS_APPEND;
|
||||
name[assign - 1] = '\0';
|
||||
}
|
||||
}
|
||||
|
||||
if (legal_identifier (name) == 0)
|
||||
{
|
||||
sh_invalidid (name);
|
||||
if (assign)
|
||||
assign_error++;
|
||||
else
|
||||
any_failed++;
|
||||
list = list->next;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (assign) /* xxx [-np] name=value */
|
||||
{
|
||||
name[assign] = '=';
|
||||
if (aflags & ASS_APPEND)
|
||||
name[assign - 1] = '+';
|
||||
#if defined (ARRAY_VARS)
|
||||
/* Let's try something here. Turn readonly -a xxx=yyy into
|
||||
declare -ra xxx=yyy and see what that gets us. */
|
||||
if (arrays_only || assoc_only)
|
||||
{
|
||||
tlist = list->next;
|
||||
list->next = (WORD_LIST *)NULL;
|
||||
w = arrays_only ? make_word ("-ra") : make_word ("-rA");
|
||||
nlist = make_word_list (w, list);
|
||||
opt = declare_builtin (nlist);
|
||||
if (opt != EXECUTION_SUCCESS)
|
||||
assign_error++;
|
||||
list->next = tlist;
|
||||
dispose_word (w);
|
||||
free (nlist);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
/* This word has already been expanded once with command
|
||||
and parameter expansion. Call do_assignment_no_expand (),
|
||||
which does not do command or parameter substitution. If
|
||||
the assignment is not performed correctly, flag an error. */
|
||||
if (do_assignment_no_expand (name) == 0)
|
||||
assign_error++;
|
||||
name[assign] = '\0';
|
||||
if (aflags & ASS_APPEND)
|
||||
name[assign - 1] = '\0';
|
||||
}
|
||||
|
||||
set_var_attribute (name, attribute, undo);
|
||||
list = list->next;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
SHELL_VAR **variable_list;
|
||||
register int i;
|
||||
|
||||
if ((attribute & att_function) || functions_only)
|
||||
{
|
||||
variable_list = all_shell_functions ();
|
||||
if (attribute != att_function)
|
||||
attribute &= ~att_function; /* so declare -xf works, for example */
|
||||
}
|
||||
else
|
||||
variable_list = all_shell_variables ();
|
||||
|
||||
#if defined (ARRAY_VARS)
|
||||
if (attribute & att_array)
|
||||
{
|
||||
arrays_only++;
|
||||
if (attribute != att_array)
|
||||
attribute &= ~att_array;
|
||||
}
|
||||
else if (attribute & att_assoc)
|
||||
{
|
||||
assoc_only++;
|
||||
if (attribute != att_assoc)
|
||||
attribute &= ~att_assoc;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (variable_list)
|
||||
{
|
||||
for (i = 0; var = variable_list[i]; i++)
|
||||
{
|
||||
#if defined (ARRAY_VARS)
|
||||
if (arrays_only && array_p (var) == 0)
|
||||
continue;
|
||||
else if (assoc_only && assoc_p (var) == 0)
|
||||
continue;
|
||||
#endif
|
||||
if ((var->attributes & attribute))
|
||||
{
|
||||
show_var_attributes (var, READONLY_OR_EXPORT, nodefs);
|
||||
if (any_failed = sh_chkwrite (any_failed))
|
||||
break;
|
||||
}
|
||||
}
|
||||
free (variable_list);
|
||||
}
|
||||
}
|
||||
|
||||
return (assign_error ? EX_BADASSIGN
|
||||
: ((any_failed == 0) ? EXECUTION_SUCCESS
|
||||
: EXECUTION_FAILURE));
|
||||
}
|
||||
|
||||
/* Show all variable variables (v == 1) or functions (v == 0) with
|
||||
attributes. */
|
||||
int
|
||||
show_all_var_attributes (v, nodefs)
|
||||
int v, nodefs;
|
||||
{
|
||||
SHELL_VAR **variable_list, *var;
|
||||
int any_failed;
|
||||
register int i;
|
||||
|
||||
variable_list = v ? all_shell_variables () : all_shell_functions ();
|
||||
if (variable_list == 0)
|
||||
return (EXECUTION_SUCCESS);
|
||||
|
||||
for (i = any_failed = 0; var = variable_list[i]; i++)
|
||||
{
|
||||
show_var_attributes (var, READONLY_OR_EXPORT, nodefs);
|
||||
if (any_failed = sh_chkwrite (any_failed))
|
||||
break;
|
||||
}
|
||||
free (variable_list);
|
||||
return (any_failed == 0 ? EXECUTION_SUCCESS : EXECUTION_FAILURE);
|
||||
}
|
||||
|
||||
/* Show the attributes for shell variable VAR. If NODEFS is non-zero,
|
||||
don't show function definitions along with the name. If PATTR is
|
||||
non-zero, it indicates we're being called from `export' or `readonly'.
|
||||
In POSIX mode, this prints the name of the calling builtin (`export'
|
||||
or `readonly') instead of `declare', and doesn't print function defs
|
||||
when called by `export' or `readonly'. */
|
||||
int
|
||||
show_var_attributes (var, pattr, nodefs)
|
||||
SHELL_VAR *var;
|
||||
int pattr, nodefs;
|
||||
{
|
||||
char flags[16], *x;
|
||||
int i;
|
||||
|
||||
i = 0;
|
||||
|
||||
/* pattr == 0 means we are called from `declare'. */
|
||||
if (pattr == 0 || posixly_correct == 0)
|
||||
{
|
||||
#if defined (ARRAY_VARS)
|
||||
if (array_p (var))
|
||||
flags[i++] = 'a';
|
||||
|
||||
if (assoc_p (var))
|
||||
flags[i++] = 'A';
|
||||
#endif
|
||||
|
||||
if (function_p (var))
|
||||
flags[i++] = 'f';
|
||||
|
||||
if (integer_p (var))
|
||||
flags[i++] = 'i';
|
||||
|
||||
if (readonly_p (var))
|
||||
flags[i++] = 'r';
|
||||
|
||||
if (trace_p (var))
|
||||
flags[i++] = 't';
|
||||
|
||||
if (exported_p (var))
|
||||
flags[i++] = 'x';
|
||||
|
||||
if (capcase_p (var))
|
||||
flags[i++] = 'c';
|
||||
|
||||
if (lowercase_p (var))
|
||||
flags[i++] = 'l';
|
||||
|
||||
if (uppercase_p (var))
|
||||
flags[i++] = 'u';
|
||||
}
|
||||
else
|
||||
{
|
||||
#if defined (ARRAY_VARS)
|
||||
if (array_p (var))
|
||||
flags[i++] = 'a';
|
||||
|
||||
if (assoc_p (var))
|
||||
flags[i++] = 'A';
|
||||
#endif
|
||||
|
||||
if (function_p (var))
|
||||
flags[i++] = 'f';
|
||||
}
|
||||
|
||||
flags[i] = '\0';
|
||||
|
||||
/* If we're printing functions with definitions, print the function def
|
||||
first, then the attributes, instead of printing output that can't be
|
||||
reused as input to recreate the current state. */
|
||||
if (function_p (var) && nodefs == 0 && (pattr == 0 || posixly_correct == 0))
|
||||
{
|
||||
printf ("%s\n", named_function_string (var->name, function_cell (var), FUNC_MULTILINE|FUNC_EXTERNAL));
|
||||
nodefs++;
|
||||
if (pattr == 0 && i == 1 && flags[0] == 'f')
|
||||
return 0; /* don't print `declare -f name' */
|
||||
}
|
||||
|
||||
if (pattr == 0 || posixly_correct == 0)
|
||||
printf ("declare -%s ", i ? flags : "-");
|
||||
else if (i)
|
||||
printf ("%s -%s ", this_command_name, flags);
|
||||
else
|
||||
printf ("%s ", this_command_name);
|
||||
|
||||
#if defined (ARRAY_VARS)
|
||||
if (array_p (var))
|
||||
print_array_assignment (var, 1);
|
||||
else if (assoc_p (var))
|
||||
print_assoc_assignment (var, 1);
|
||||
else
|
||||
#endif
|
||||
/* force `readonly' and `export' to not print out function definitions
|
||||
when in POSIX mode. */
|
||||
if (nodefs || (function_p (var) && pattr != 0 && posixly_correct))
|
||||
printf ("%s\n", var->name);
|
||||
else if (function_p (var))
|
||||
printf ("%s\n", named_function_string (var->name, function_cell (var), FUNC_MULTILINE|FUNC_EXTERNAL));
|
||||
else if (invisible_p (var) || var_isset (var) == 0)
|
||||
printf ("%s\n", var->name);
|
||||
else
|
||||
{
|
||||
x = sh_double_quote (value_cell (var));
|
||||
printf ("%s=%s\n", var->name, x);
|
||||
free (x);
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
show_name_attributes (name, nodefs)
|
||||
char *name;
|
||||
int nodefs;
|
||||
{
|
||||
SHELL_VAR *var;
|
||||
|
||||
var = find_variable_internal (name, 1);
|
||||
|
||||
if (var && invisible_p (var) == 0)
|
||||
{
|
||||
show_var_attributes (var, READONLY_OR_EXPORT, nodefs);
|
||||
return (0);
|
||||
}
|
||||
else
|
||||
return (1);
|
||||
}
|
||||
|
||||
void
|
||||
set_var_attribute (name, attribute, undo)
|
||||
char *name;
|
||||
int attribute, undo;
|
||||
{
|
||||
SHELL_VAR *var, *tv;
|
||||
char *tvalue;
|
||||
|
||||
if (undo)
|
||||
var = find_variable (name);
|
||||
else
|
||||
{
|
||||
tv = find_tempenv_variable (name);
|
||||
/* XXX -- need to handle case where tv is a temp variable in a
|
||||
function-scope context, since function_env has been merged into
|
||||
the local variables table. */
|
||||
if (tv && tempvar_p (tv))
|
||||
{
|
||||
tvalue = var_isset (tv) ? savestring (value_cell (tv)) : savestring ("");
|
||||
|
||||
var = bind_variable (tv->name, tvalue, 0);
|
||||
var->attributes |= tv->attributes & ~att_tempvar;
|
||||
VSETATTR (tv, att_propagate);
|
||||
if (var->context != 0)
|
||||
VSETATTR (var, att_propagate);
|
||||
SETVARATTR (tv, attribute, undo); /* XXX */
|
||||
|
||||
stupidly_hack_special_variables (tv->name);
|
||||
|
||||
free (tvalue);
|
||||
}
|
||||
else
|
||||
{
|
||||
var = find_variable_internal (name, 0);
|
||||
if (var == 0)
|
||||
{
|
||||
var = bind_variable (name, (char *)NULL, 0);
|
||||
VSETATTR (var, att_invisible);
|
||||
}
|
||||
else if (var->context != 0)
|
||||
VSETATTR (var, att_propagate);
|
||||
}
|
||||
}
|
||||
|
||||
if (var)
|
||||
SETVARATTR (var, attribute, undo);
|
||||
|
||||
if (var && (exported_p (var) || (attribute & att_exported)))
|
||||
array_needs_making++; /* XXX */
|
||||
}
|
||||
@@ -1,717 +0,0 @@
|
||||
This file is shopt.def, from which is created shopt.c.
|
||||
It implements the Bash `shopt' builtin.
|
||||
|
||||
Copyright (C) 1994-2010 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Bash, the Bourne Again SHell.
|
||||
|
||||
Bash is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Bash is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Bash. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
$PRODUCES shopt.c
|
||||
|
||||
$BUILTIN shopt
|
||||
$FUNCTION shopt_builtin
|
||||
$SHORT_DOC shopt [-pqsu] [-o] [optname ...]
|
||||
Set and unset shell options.
|
||||
|
||||
Change the setting of each shell option OPTNAME. Without any option
|
||||
arguments, list all shell options with an indication of whether or not each
|
||||
is set.
|
||||
|
||||
Options:
|
||||
-o restrict OPTNAMEs to those defined for use with `set -o'
|
||||
-p print each shell option with an indication of its status
|
||||
-q suppress output
|
||||
-s enable (set) each OPTNAME
|
||||
-u disable (unset) each OPTNAME
|
||||
|
||||
Exit Status:
|
||||
Returns success if OPTNAME is enabled; fails if an invalid option is
|
||||
given or OPTNAME is disabled.
|
||||
$END
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#if defined (HAVE_UNISTD_H)
|
||||
# ifdef _MINIX
|
||||
# include <sys/types.h>
|
||||
# endif
|
||||
# include <unistd.h>
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "version.h"
|
||||
|
||||
#include "../bashintl.h"
|
||||
|
||||
#include "../shell.h"
|
||||
#include "../flags.h"
|
||||
#include "common.h"
|
||||
#include "bashgetopt.h"
|
||||
|
||||
#if defined (HISTORY)
|
||||
# include "../bashhist.h"
|
||||
#endif
|
||||
|
||||
#define UNSETOPT 0
|
||||
#define SETOPT 1
|
||||
|
||||
#define OPTFMT "%-15s\t%s\n"
|
||||
|
||||
extern int allow_null_glob_expansion, fail_glob_expansion, glob_dot_filenames;
|
||||
extern int cdable_vars, mail_warning, source_uses_path;
|
||||
extern int no_exit_on_failed_exec, print_shift_error;
|
||||
extern int check_hashed_filenames, promptvars;
|
||||
extern int cdspelling, expand_aliases;
|
||||
extern int extended_quote;
|
||||
extern int check_window_size;
|
||||
extern int glob_ignore_case, match_ignore_case;
|
||||
extern int hup_on_exit;
|
||||
extern int xpg_echo;
|
||||
extern int gnu_error_format;
|
||||
extern int check_jobs_at_exit;
|
||||
extern int autocd;
|
||||
extern int glob_star;
|
||||
|
||||
#if defined (EXTENDED_GLOB)
|
||||
extern int extended_glob;
|
||||
#endif
|
||||
|
||||
#if defined (READLINE)
|
||||
extern int hist_verify, history_reediting, perform_hostname_completion;
|
||||
extern int no_empty_command_completion;
|
||||
extern int force_fignore;
|
||||
extern int dircomplete_spelling;
|
||||
|
||||
extern int enable_hostname_completion __P((int));
|
||||
#endif
|
||||
|
||||
#if defined (PROGRAMMABLE_COMPLETION)
|
||||
extern int prog_completion_enabled;
|
||||
#endif
|
||||
|
||||
#if defined (RESTRICTED_SHELL)
|
||||
extern char *shell_name;
|
||||
#endif
|
||||
|
||||
#if defined (DEBUGGER)
|
||||
extern int debugging_mode;
|
||||
#endif
|
||||
|
||||
static void shopt_error __P((char *));
|
||||
|
||||
static int set_shellopts_after_change __P((char *, int));
|
||||
static int shopt_enable_hostname_completion __P((char *, int));
|
||||
static int set_compatibility_level __P((char *, int));
|
||||
|
||||
#if defined (RESTRICTED_SHELL)
|
||||
static int set_restricted_shell __P((char *, int));
|
||||
#endif
|
||||
|
||||
static int shopt_login_shell;
|
||||
static int shopt_compat31;
|
||||
static int shopt_compat32;
|
||||
static int shopt_compat40;
|
||||
static int shopt_compat41;
|
||||
|
||||
typedef int shopt_set_func_t __P((char *, int));
|
||||
|
||||
static struct {
|
||||
char *name;
|
||||
int *value;
|
||||
shopt_set_func_t *set_func;
|
||||
} shopt_vars[] = {
|
||||
{ "autocd", &autocd, (shopt_set_func_t *)NULL },
|
||||
{ "cdable_vars", &cdable_vars, (shopt_set_func_t *)NULL },
|
||||
{ "cdspell", &cdspelling, (shopt_set_func_t *)NULL },
|
||||
{ "checkhash", &check_hashed_filenames, (shopt_set_func_t *)NULL },
|
||||
#if defined (JOB_CONTROL)
|
||||
{ "checkjobs", &check_jobs_at_exit, (shopt_set_func_t *)NULL },
|
||||
#endif
|
||||
{ "checkwinsize", &check_window_size, (shopt_set_func_t *)NULL },
|
||||
#if defined (HISTORY)
|
||||
{ "cmdhist", &command_oriented_history, (shopt_set_func_t *)NULL },
|
||||
#endif
|
||||
{ "compat31", &shopt_compat31, set_compatibility_level },
|
||||
{ "compat32", &shopt_compat32, set_compatibility_level },
|
||||
{ "compat40", &shopt_compat40, set_compatibility_level },
|
||||
{ "compat41", &shopt_compat41, set_compatibility_level },
|
||||
#if defined (READLINE)
|
||||
{ "dirspell", &dircomplete_spelling, (shopt_set_func_t *)NULL },
|
||||
#endif
|
||||
{ "dotglob", &glob_dot_filenames, (shopt_set_func_t *)NULL },
|
||||
{ "execfail", &no_exit_on_failed_exec, (shopt_set_func_t *)NULL },
|
||||
{ "expand_aliases", &expand_aliases, (shopt_set_func_t *)NULL },
|
||||
#if defined (DEBUGGER)
|
||||
{ "extdebug", &debugging_mode, (shopt_set_func_t *)NULL },
|
||||
#endif
|
||||
#if defined (EXTENDED_GLOB)
|
||||
{ "extglob", &extended_glob, (shopt_set_func_t *)NULL },
|
||||
#endif
|
||||
{ "extquote", &extended_quote, (shopt_set_func_t *)NULL },
|
||||
{ "failglob", &fail_glob_expansion, (shopt_set_func_t *)NULL },
|
||||
#if defined (READLINE)
|
||||
{ "force_fignore", &force_fignore, (shopt_set_func_t *)NULL },
|
||||
#endif
|
||||
{ "globstar", &glob_star, (shopt_set_func_t *)NULL },
|
||||
{ "gnu_errfmt", &gnu_error_format, (shopt_set_func_t *)NULL },
|
||||
#if defined (HISTORY)
|
||||
{ "histappend", &force_append_history, (shopt_set_func_t *)NULL },
|
||||
#endif
|
||||
#if defined (READLINE)
|
||||
{ "histreedit", &history_reediting, (shopt_set_func_t *)NULL },
|
||||
{ "histverify", &hist_verify, (shopt_set_func_t *)NULL },
|
||||
{ "hostcomplete", &perform_hostname_completion, shopt_enable_hostname_completion },
|
||||
#endif
|
||||
{ "huponexit", &hup_on_exit, (shopt_set_func_t *)NULL },
|
||||
{ "interactive_comments", &interactive_comments, set_shellopts_after_change },
|
||||
#if defined (HISTORY)
|
||||
{ "lithist", &literal_history, (shopt_set_func_t *)NULL },
|
||||
#endif
|
||||
{ "login_shell", &shopt_login_shell, set_login_shell },
|
||||
{ "mailwarn", &mail_warning, (shopt_set_func_t *)NULL },
|
||||
#if defined (READLINE)
|
||||
{ "no_empty_cmd_completion", &no_empty_command_completion, (shopt_set_func_t *)NULL },
|
||||
#endif
|
||||
{ "nocaseglob", &glob_ignore_case, (shopt_set_func_t *)NULL },
|
||||
{ "nocasematch", &match_ignore_case, (shopt_set_func_t *)NULL },
|
||||
{ "nullglob", &allow_null_glob_expansion, (shopt_set_func_t *)NULL },
|
||||
#if defined (PROGRAMMABLE_COMPLETION)
|
||||
{ "progcomp", &prog_completion_enabled, (shopt_set_func_t *)NULL },
|
||||
#endif
|
||||
{ "promptvars", &promptvars, (shopt_set_func_t *)NULL },
|
||||
#if defined (RESTRICTED_SHELL)
|
||||
{ "restricted_shell", &restricted_shell, set_restricted_shell },
|
||||
#endif
|
||||
{ "shift_verbose", &print_shift_error, (shopt_set_func_t *)NULL },
|
||||
{ "sourcepath", &source_uses_path, (shopt_set_func_t *)NULL },
|
||||
{ "xpg_echo", &xpg_echo, (shopt_set_func_t *)NULL },
|
||||
{ (char *)0, (int *)0, (shopt_set_func_t *)NULL }
|
||||
};
|
||||
|
||||
#define N_SHOPT_OPTIONS (sizeof (shopt_vars) / sizeof (shopt_vars[0]))
|
||||
|
||||
#define GET_SHOPT_OPTION_VALUE(i) (*shopt_vars[i].value)
|
||||
|
||||
static const char * const on = "on";
|
||||
static const char * const off = "off";
|
||||
|
||||
static int find_shopt __P((char *));
|
||||
static int toggle_shopts __P((int, WORD_LIST *, int));
|
||||
static void print_shopt __P((char *, int, int));
|
||||
static int list_shopts __P((WORD_LIST *, int));
|
||||
static int list_some_shopts __P((int, int));
|
||||
static int list_shopt_o_options __P((WORD_LIST *, int));
|
||||
static int list_some_o_options __P((int, int));
|
||||
static int set_shopt_o_options __P((int, WORD_LIST *, int));
|
||||
|
||||
#define SFLAG 0x01
|
||||
#define UFLAG 0x02
|
||||
#define QFLAG 0x04
|
||||
#define OFLAG 0x08
|
||||
#define PFLAG 0x10
|
||||
|
||||
int
|
||||
shopt_builtin (list)
|
||||
WORD_LIST *list;
|
||||
{
|
||||
int opt, flags, rval;
|
||||
|
||||
flags = 0;
|
||||
reset_internal_getopt ();
|
||||
while ((opt = internal_getopt (list, "psuoq")) != -1)
|
||||
{
|
||||
switch (opt)
|
||||
{
|
||||
case 's':
|
||||
flags |= SFLAG;
|
||||
break;
|
||||
case 'u':
|
||||
flags |= UFLAG;
|
||||
break;
|
||||
case 'q':
|
||||
flags |= QFLAG;
|
||||
break;
|
||||
case 'o':
|
||||
flags |= OFLAG;
|
||||
break;
|
||||
case 'p':
|
||||
flags |= PFLAG;
|
||||
break;
|
||||
default:
|
||||
builtin_usage ();
|
||||
return (EX_USAGE);
|
||||
}
|
||||
}
|
||||
list = loptend;
|
||||
|
||||
if ((flags & (SFLAG|UFLAG)) == (SFLAG|UFLAG))
|
||||
{
|
||||
builtin_error (_("cannot set and unset shell options simultaneously"));
|
||||
return (EXECUTION_FAILURE);
|
||||
}
|
||||
|
||||
rval = EXECUTION_SUCCESS;
|
||||
if ((flags & OFLAG) && ((flags & (SFLAG|UFLAG)) == 0)) /* shopt -o */
|
||||
rval = list_shopt_o_options (list, flags);
|
||||
else if (list && (flags & OFLAG)) /* shopt -so args */
|
||||
rval = set_shopt_o_options ((flags & SFLAG) ? FLAG_ON : FLAG_OFF, list, flags & QFLAG);
|
||||
else if (flags & OFLAG) /* shopt -so */
|
||||
rval = list_some_o_options ((flags & SFLAG) ? 1 : 0, flags);
|
||||
else if (list && (flags & (SFLAG|UFLAG))) /* shopt -su args */
|
||||
rval = toggle_shopts ((flags & SFLAG) ? SETOPT : UNSETOPT, list, flags & QFLAG);
|
||||
else if ((flags & (SFLAG|UFLAG)) == 0) /* shopt [args] */
|
||||
rval = list_shopts (list, flags);
|
||||
else /* shopt -su */
|
||||
rval = list_some_shopts ((flags & SFLAG) ? SETOPT : UNSETOPT, flags);
|
||||
return (rval);
|
||||
}
|
||||
|
||||
/* Reset the options managed by `shopt' to the values they would have at
|
||||
shell startup. */
|
||||
void
|
||||
reset_shopt_options ()
|
||||
{
|
||||
allow_null_glob_expansion = glob_dot_filenames = 0;
|
||||
cdable_vars = mail_warning = 0;
|
||||
no_exit_on_failed_exec = print_shift_error = 0;
|
||||
check_hashed_filenames = cdspelling = expand_aliases = check_window_size = 0;
|
||||
|
||||
source_uses_path = promptvars = 1;
|
||||
|
||||
#if defined (EXTENDED_GLOB)
|
||||
extended_glob = 0;
|
||||
#endif
|
||||
|
||||
#if defined (HISTORY)
|
||||
literal_history = force_append_history = 0;
|
||||
command_oriented_history = 1;
|
||||
#endif
|
||||
|
||||
#if defined (READLINE)
|
||||
hist_verify = history_reediting = 0;
|
||||
perform_hostname_completion = 1;
|
||||
#endif
|
||||
|
||||
shopt_login_shell = login_shell;
|
||||
}
|
||||
|
||||
static int
|
||||
find_shopt (name)
|
||||
char *name;
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; shopt_vars[i].name; i++)
|
||||
if (STREQ (name, shopt_vars[i].name))
|
||||
return i;
|
||||
return -1;
|
||||
}
|
||||
|
||||
static void
|
||||
shopt_error (s)
|
||||
char *s;
|
||||
{
|
||||
builtin_error (_("%s: invalid shell option name"), s);
|
||||
}
|
||||
|
||||
static int
|
||||
toggle_shopts (mode, list, quiet)
|
||||
int mode;
|
||||
WORD_LIST *list;
|
||||
int quiet;
|
||||
{
|
||||
WORD_LIST *l;
|
||||
int ind, rval;
|
||||
|
||||
for (l = list, rval = EXECUTION_SUCCESS; l; l = l->next)
|
||||
{
|
||||
ind = find_shopt (l->word->word);
|
||||
if (ind < 0)
|
||||
{
|
||||
shopt_error (l->word->word);
|
||||
rval = EXECUTION_FAILURE;
|
||||
}
|
||||
else
|
||||
{
|
||||
*shopt_vars[ind].value = mode; /* 1 for set, 0 for unset */
|
||||
if (shopt_vars[ind].set_func)
|
||||
(*shopt_vars[ind].set_func) (shopt_vars[ind].name, mode);
|
||||
}
|
||||
}
|
||||
|
||||
set_bashopts ();
|
||||
return (rval);
|
||||
}
|
||||
|
||||
static void
|
||||
print_shopt (name, val, flags)
|
||||
char *name;
|
||||
int val, flags;
|
||||
{
|
||||
if (flags & PFLAG)
|
||||
printf ("shopt %s %s\n", val ? "-s" : "-u", name);
|
||||
else
|
||||
printf (OPTFMT, name, val ? on : off);
|
||||
}
|
||||
|
||||
/* List the values of all or any of the `shopt' options. Returns 0 if
|
||||
all were listed or all variables queried were on; 1 otherwise. */
|
||||
static int
|
||||
list_shopts (list, flags)
|
||||
WORD_LIST *list;
|
||||
int flags;
|
||||
{
|
||||
WORD_LIST *l;
|
||||
int i, val, rval;
|
||||
|
||||
if (list == 0)
|
||||
{
|
||||
for (i = 0; shopt_vars[i].name; i++)
|
||||
{
|
||||
val = *shopt_vars[i].value;
|
||||
if ((flags & QFLAG) == 0)
|
||||
print_shopt (shopt_vars[i].name, val, flags);
|
||||
}
|
||||
return (sh_chkwrite (EXECUTION_SUCCESS));
|
||||
}
|
||||
|
||||
for (l = list, rval = EXECUTION_SUCCESS; l; l = l->next)
|
||||
{
|
||||
i = find_shopt (l->word->word);
|
||||
if (i < 0)
|
||||
{
|
||||
shopt_error (l->word->word);
|
||||
rval = EXECUTION_FAILURE;
|
||||
continue;
|
||||
}
|
||||
val = *shopt_vars[i].value;
|
||||
if (val == 0)
|
||||
rval = EXECUTION_FAILURE;
|
||||
if ((flags & QFLAG) == 0)
|
||||
print_shopt (l->word->word, val, flags);
|
||||
}
|
||||
|
||||
return (sh_chkwrite (rval));
|
||||
}
|
||||
|
||||
static int
|
||||
list_some_shopts (mode, flags)
|
||||
int mode, flags;
|
||||
{
|
||||
int val, i;
|
||||
|
||||
for (i = 0; shopt_vars[i].name; i++)
|
||||
{
|
||||
val = *shopt_vars[i].value;
|
||||
if (((flags & QFLAG) == 0) && mode == val)
|
||||
print_shopt (shopt_vars[i].name, val, flags);
|
||||
}
|
||||
return (sh_chkwrite (EXECUTION_SUCCESS));
|
||||
}
|
||||
|
||||
static int
|
||||
list_shopt_o_options (list, flags)
|
||||
WORD_LIST *list;
|
||||
int flags;
|
||||
{
|
||||
WORD_LIST *l;
|
||||
int val, rval;
|
||||
|
||||
if (list == 0)
|
||||
{
|
||||
if ((flags & QFLAG) == 0)
|
||||
list_minus_o_opts (-1, (flags & PFLAG));
|
||||
return (sh_chkwrite (EXECUTION_SUCCESS));
|
||||
}
|
||||
|
||||
for (l = list, rval = EXECUTION_SUCCESS; l; l = l->next)
|
||||
{
|
||||
val = minus_o_option_value (l->word->word);
|
||||
if (val == -1)
|
||||
{
|
||||
sh_invalidoptname (l->word->word);
|
||||
rval = EXECUTION_FAILURE;
|
||||
continue;
|
||||
}
|
||||
if (val == 0)
|
||||
rval = EXECUTION_FAILURE;
|
||||
if ((flags & QFLAG) == 0)
|
||||
{
|
||||
if (flags & PFLAG)
|
||||
printf ("set %co %s\n", val ? '-' : '+', l->word->word);
|
||||
else
|
||||
printf (OPTFMT, l->word->word, val ? on : off);
|
||||
}
|
||||
}
|
||||
return (sh_chkwrite (rval));
|
||||
}
|
||||
|
||||
static int
|
||||
list_some_o_options (mode, flags)
|
||||
int mode, flags;
|
||||
{
|
||||
if ((flags & QFLAG) == 0)
|
||||
list_minus_o_opts (mode, (flags & PFLAG));
|
||||
return (sh_chkwrite (EXECUTION_SUCCESS));
|
||||
}
|
||||
|
||||
static int
|
||||
set_shopt_o_options (mode, list, quiet)
|
||||
int mode;
|
||||
WORD_LIST *list;
|
||||
int quiet;
|
||||
{
|
||||
WORD_LIST *l;
|
||||
int rval;
|
||||
|
||||
for (l = list, rval = EXECUTION_SUCCESS; l; l = l->next)
|
||||
{
|
||||
if (set_minus_o_option (mode, l->word->word) == EXECUTION_FAILURE)
|
||||
rval = EXECUTION_FAILURE;
|
||||
}
|
||||
set_shellopts ();
|
||||
return rval;
|
||||
}
|
||||
|
||||
/* If we set or unset interactive_comments with shopt, make sure the
|
||||
change is reflected in $SHELLOPTS. */
|
||||
static int
|
||||
set_shellopts_after_change (option_name, mode)
|
||||
char *option_name;
|
||||
int mode;
|
||||
{
|
||||
set_shellopts ();
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
shopt_enable_hostname_completion (option_name, mode)
|
||||
char *option_name;
|
||||
int mode;
|
||||
{
|
||||
return (enable_hostname_completion (mode));
|
||||
}
|
||||
|
||||
static int
|
||||
set_compatibility_level (option_name, mode)
|
||||
char *option_name;
|
||||
int mode;
|
||||
{
|
||||
/* Need to change logic here as we add more compatibility levels */
|
||||
|
||||
/* First, check option_name so we can turn off other compat options when
|
||||
one is set. */
|
||||
if (mode && option_name[6] == '3' && option_name[7] == '1')
|
||||
shopt_compat32 = shopt_compat40 = 0;
|
||||
else if (mode && option_name[6] == '3' && option_name[7] == '2')
|
||||
shopt_compat31 = shopt_compat40 = 0;
|
||||
else if (mode && option_name[6] == '4' && option_name[7] == '0')
|
||||
shopt_compat31 = shopt_compat32 = 0;
|
||||
|
||||
/* Then set shell_compatibility_level based on what remains */
|
||||
if (shopt_compat31)
|
||||
shell_compatibility_level = 31;
|
||||
else if (shopt_compat32)
|
||||
shell_compatibility_level = 32;
|
||||
else if (shopt_compat40)
|
||||
shell_compatibility_level = 40;
|
||||
else
|
||||
shell_compatibility_level = DEFAULT_COMPAT_LEVEL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if defined (RESTRICTED_SHELL)
|
||||
/* Don't allow the value of restricted_shell to be modified. */
|
||||
|
||||
static int
|
||||
set_restricted_shell (option_name, mode)
|
||||
char *option_name;
|
||||
int mode;
|
||||
{
|
||||
static int save_restricted = -1;
|
||||
|
||||
if (save_restricted == -1)
|
||||
save_restricted = shell_is_restricted (shell_name);
|
||||
|
||||
restricted_shell = save_restricted;
|
||||
return (0);
|
||||
}
|
||||
#endif /* RESTRICTED_SHELL */
|
||||
|
||||
/* Not static so shell.c can call it to initialize shopt_login_shell */
|
||||
int
|
||||
set_login_shell (option_name, mode)
|
||||
char *option_name;
|
||||
int mode;
|
||||
{
|
||||
shopt_login_shell = login_shell != 0;
|
||||
return (0);
|
||||
}
|
||||
|
||||
char **
|
||||
get_shopt_options ()
|
||||
{
|
||||
char **ret;
|
||||
int n, i;
|
||||
|
||||
n = sizeof (shopt_vars) / sizeof (shopt_vars[0]);
|
||||
ret = strvec_create (n + 1);
|
||||
for (i = 0; shopt_vars[i].name; i++)
|
||||
ret[i] = savestring (shopt_vars[i].name);
|
||||
ret[i] = (char *)NULL;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* External interface for other parts of the shell. NAME is a string option;
|
||||
* MODE is 0 if we want to unset an option; 1 if we want to set an option.
|
||||
* REUSABLE is 1 if we want to print output in a form that may be reused.
|
||||
*/
|
||||
int
|
||||
shopt_setopt (name, mode)
|
||||
char *name;
|
||||
int mode;
|
||||
{
|
||||
WORD_LIST *wl;
|
||||
int r;
|
||||
|
||||
wl = add_string_to_list (name, (WORD_LIST *)NULL);
|
||||
r = toggle_shopts (mode, wl, 0);
|
||||
dispose_words (wl);
|
||||
return r;
|
||||
}
|
||||
|
||||
int
|
||||
shopt_listopt (name, reusable)
|
||||
char *name;
|
||||
int reusable;
|
||||
{
|
||||
int i;
|
||||
|
||||
if (name == 0)
|
||||
return (list_shopts ((WORD_LIST *)NULL, reusable ? PFLAG : 0));
|
||||
|
||||
i = find_shopt (name);
|
||||
if (i < 0)
|
||||
{
|
||||
shopt_error (name);
|
||||
return (EXECUTION_FAILURE);
|
||||
}
|
||||
|
||||
print_shopt (name, *shopt_vars[i].value, reusable ? PFLAG : 0);
|
||||
return (sh_chkwrite (EXECUTION_SUCCESS));
|
||||
}
|
||||
|
||||
void
|
||||
set_bashopts ()
|
||||
{
|
||||
char *value;
|
||||
char tflag[N_SHOPT_OPTIONS];
|
||||
int vsize, i, vptr, *ip, exported;
|
||||
SHELL_VAR *v;
|
||||
|
||||
for (vsize = i = 0; shopt_vars[i].name; i++)
|
||||
{
|
||||
tflag[i] = 0;
|
||||
if (GET_SHOPT_OPTION_VALUE (i))
|
||||
{
|
||||
vsize += strlen (shopt_vars[i].name) + 1;
|
||||
tflag[i] = 1;
|
||||
}
|
||||
}
|
||||
|
||||
value = (char *)xmalloc (vsize + 1);
|
||||
|
||||
for (i = vptr = 0; shopt_vars[i].name; i++)
|
||||
{
|
||||
if (tflag[i])
|
||||
{
|
||||
strcpy (value + vptr, shopt_vars[i].name);
|
||||
vptr += strlen (shopt_vars[i].name);
|
||||
value[vptr++] = ':';
|
||||
}
|
||||
}
|
||||
|
||||
if (vptr)
|
||||
vptr--; /* cut off trailing colon */
|
||||
value[vptr] = '\0';
|
||||
|
||||
v = find_variable ("BASHOPTS");
|
||||
|
||||
/* Turn off the read-only attribute so we can bind the new value, and
|
||||
note whether or not the variable was exported. */
|
||||
if (v)
|
||||
{
|
||||
VUNSETATTR (v, att_readonly);
|
||||
exported = exported_p (v);
|
||||
}
|
||||
else
|
||||
exported = 0;
|
||||
|
||||
v = bind_variable ("BASHOPTS", value, 0);
|
||||
|
||||
/* Turn the read-only attribute back on, and turn off the export attribute
|
||||
if it was set implicitly by mark_modified_vars and SHELLOPTS was not
|
||||
exported before we bound the new value. */
|
||||
VSETATTR (v, att_readonly);
|
||||
if (mark_modified_vars && exported == 0 && exported_p (v))
|
||||
VUNSETATTR (v, att_exported);
|
||||
|
||||
free (value);
|
||||
}
|
||||
|
||||
void
|
||||
parse_bashopts (value)
|
||||
char *value;
|
||||
{
|
||||
char *vname;
|
||||
int vptr, ind;
|
||||
|
||||
vptr = 0;
|
||||
while (vname = extract_colon_unit (value, &vptr))
|
||||
{
|
||||
ind = find_shopt (vname);
|
||||
if (ind >= 0)
|
||||
*shopt_vars[ind].value = 1;
|
||||
free (vname);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
initialize_bashopts (no_bashopts)
|
||||
int no_bashopts;
|
||||
{
|
||||
char *temp;
|
||||
SHELL_VAR *var;
|
||||
|
||||
if (no_bashopts == 0)
|
||||
{
|
||||
var = find_variable ("BASHOPTS");
|
||||
/* set up any shell options we may have inherited. */
|
||||
if (var && imported_p (var))
|
||||
{
|
||||
temp = (array_p (var) || assoc_p (var)) ? (char *)NULL : savestring (value_cell (var));
|
||||
if (temp)
|
||||
{
|
||||
parse_bashopts (temp);
|
||||
free (temp);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Set up the $BASHOPTS variable. */
|
||||
set_bashopts ();
|
||||
}
|
||||
@@ -1,196 +0,0 @@
|
||||
This file is source.def, from which is created source.c.
|
||||
It implements the builtins "." and "source" in Bash.
|
||||
|
||||
Copyright (C) 1987-2009 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Bash, the Bourne Again SHell.
|
||||
|
||||
Bash is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Bash is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Bash. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
$PRODUCES source.c
|
||||
|
||||
$BUILTIN source
|
||||
$FUNCTION source_builtin
|
||||
$SHORT_DOC source filename [arguments]
|
||||
Execute commands from a file in the current shell.
|
||||
|
||||
Read and execute commands from FILENAME in the current shell. The
|
||||
entries in $PATH are used to find the directory containing FILENAME.
|
||||
If any ARGUMENTS are supplied, they become the positional parameters
|
||||
when FILENAME is executed.
|
||||
|
||||
Exit Status:
|
||||
Returns the status of the last command executed in FILENAME; fails if
|
||||
FILENAME cannot be read.
|
||||
$END
|
||||
|
||||
$BUILTIN .
|
||||
$DOCNAME dot
|
||||
$FUNCTION source_builtin
|
||||
$SHORT_DOC . filename [arguments]
|
||||
Execute commands from a file in the current shell.
|
||||
|
||||
Read and execute commands from FILENAME in the current shell. The
|
||||
entries in $PATH are used to find the directory containing FILENAME.
|
||||
If any ARGUMENTS are supplied, they become the positional parameters
|
||||
when FILENAME is executed.
|
||||
|
||||
Exit Status:
|
||||
Returns the status of the last command executed in FILENAME; fails if
|
||||
FILENAME cannot be read.
|
||||
$END
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include "../bashtypes.h"
|
||||
#include "posixstat.h"
|
||||
#include "filecntl.h"
|
||||
#if ! defined(_MINIX) && defined (HAVE_SYS_FILE_H)
|
||||
# include <sys/file.h>
|
||||
#endif
|
||||
#include <errno.h>
|
||||
|
||||
#if defined (HAVE_UNISTD_H)
|
||||
# include <unistd.h>
|
||||
#endif
|
||||
|
||||
#include "../bashansi.h"
|
||||
#include "../bashintl.h"
|
||||
|
||||
#include "../shell.h"
|
||||
#include "../flags.h"
|
||||
#include "../findcmd.h"
|
||||
#include "common.h"
|
||||
#include "bashgetopt.h"
|
||||
#include "../trap.h"
|
||||
|
||||
#if !defined (errno)
|
||||
extern int errno;
|
||||
#endif /* !errno */
|
||||
|
||||
extern int posixly_correct;
|
||||
extern int last_command_exit_value;
|
||||
|
||||
static void maybe_pop_dollar_vars __P((void));
|
||||
|
||||
/* If non-zero, `.' uses $PATH to look up the script to be sourced. */
|
||||
int source_uses_path = 1;
|
||||
|
||||
/* If non-zero, `.' looks in the current directory if the filename argument
|
||||
is not found in the $PATH. */
|
||||
int source_searches_cwd = 1;
|
||||
|
||||
/* If this . script is supplied arguments, we save the dollar vars and
|
||||
replace them with the script arguments for the duration of the script's
|
||||
execution. If the script does not change the dollar vars, we restore
|
||||
what we saved. If the dollar vars are changed in the script, and we are
|
||||
not executing a shell function, we leave the new values alone and free
|
||||
the saved values. */
|
||||
static void
|
||||
maybe_pop_dollar_vars ()
|
||||
{
|
||||
if (variable_context == 0 && (dollar_vars_changed () & ARGS_SETBLTIN))
|
||||
dispose_saved_dollar_vars ();
|
||||
else
|
||||
pop_dollar_vars ();
|
||||
if (debugging_mode)
|
||||
pop_args (); /* restore BASH_ARGC and BASH_ARGV */
|
||||
set_dollar_vars_unchanged ();
|
||||
}
|
||||
|
||||
/* Read and execute commands from the file passed as argument. Guess what.
|
||||
This cannot be done in a subshell, since things like variable assignments
|
||||
take place in there. So, I open the file, place it into a large string,
|
||||
close the file, and then execute the string. */
|
||||
int
|
||||
source_builtin (list)
|
||||
WORD_LIST *list;
|
||||
{
|
||||
int result;
|
||||
char *filename, *debug_trap;
|
||||
|
||||
if (no_options (list))
|
||||
return (EX_USAGE);
|
||||
list = loptend;
|
||||
|
||||
if (list == 0)
|
||||
{
|
||||
builtin_error (_("filename argument required"));
|
||||
builtin_usage ();
|
||||
return (EX_USAGE);
|
||||
}
|
||||
|
||||
#if defined (RESTRICTED_SHELL)
|
||||
if (restricted && strchr (list->word->word, '/'))
|
||||
{
|
||||
sh_restricted (list->word->word);
|
||||
return (EXECUTION_FAILURE);
|
||||
}
|
||||
#endif
|
||||
|
||||
filename = (char *)NULL;
|
||||
/* XXX -- should this be absolute_pathname? */
|
||||
if (posixly_correct && strchr (list->word->word, '/'))
|
||||
filename = savestring (list->word->word);
|
||||
else if (absolute_pathname (list->word->word))
|
||||
filename = savestring (list->word->word);
|
||||
else if (source_uses_path)
|
||||
filename = find_path_file (list->word->word);
|
||||
if (filename == 0)
|
||||
{
|
||||
if (source_searches_cwd == 0)
|
||||
{
|
||||
builtin_error (_("%s: file not found"), list->word->word);
|
||||
if (posixly_correct && interactive_shell == 0)
|
||||
{
|
||||
last_command_exit_value = 1;
|
||||
jump_to_top_level (EXITPROG);
|
||||
}
|
||||
return (EXECUTION_FAILURE);
|
||||
}
|
||||
else
|
||||
filename = savestring (list->word->word);
|
||||
}
|
||||
|
||||
begin_unwind_frame ("source");
|
||||
add_unwind_protect ((Function *)xfree, filename);
|
||||
|
||||
if (list->next)
|
||||
{
|
||||
push_dollar_vars ();
|
||||
add_unwind_protect ((Function *)maybe_pop_dollar_vars, (char *)NULL);
|
||||
remember_args (list->next, 1);
|
||||
if (debugging_mode)
|
||||
push_args (list->next); /* Update BASH_ARGV and BASH_ARGC */
|
||||
}
|
||||
set_dollar_vars_unchanged ();
|
||||
|
||||
/* Don't inherit the DEBUG trap unless function_trace_mode (overloaded)
|
||||
is set. XXX - should sourced files inherit the RETURN trap? Functions
|
||||
don't. */
|
||||
debug_trap = TRAP_STRING (DEBUG_TRAP);
|
||||
if (debug_trap && function_trace_mode == 0)
|
||||
{
|
||||
debug_trap = savestring (debug_trap);
|
||||
add_unwind_protect (xfree, debug_trap);
|
||||
add_unwind_protect (set_debug_trap, debug_trap);
|
||||
restore_default_signal (DEBUG_TRAP);
|
||||
}
|
||||
|
||||
result = source_file (filename, (list && list->next));
|
||||
|
||||
run_unwind_frame ("source");
|
||||
|
||||
return (result);
|
||||
}
|
||||
@@ -1,155 +0,0 @@
|
||||
This file is test.def, from which is created test.c.
|
||||
It implements the builtin "test" in Bash.
|
||||
|
||||
Copyright (C) 1987-2010 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Bash, the Bourne Again SHell.
|
||||
|
||||
Bash is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Bash is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Bash. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
$PRODUCES test.c
|
||||
|
||||
$BUILTIN test
|
||||
$FUNCTION test_builtin
|
||||
$SHORT_DOC test [expr]
|
||||
Evaluate conditional expression.
|
||||
|
||||
Exits with a status of 0 (true) or 1 (false) depending on
|
||||
the evaluation of EXPR. Expressions may be unary or binary. Unary
|
||||
expressions are often used to examine the status of a file. There
|
||||
are string operators as well, and numeric comparison operators.
|
||||
|
||||
File operators:
|
||||
|
||||
-a FILE True if file exists.
|
||||
-b FILE True if file is block special.
|
||||
-c FILE True if file is character special.
|
||||
-d FILE True if file is a directory.
|
||||
-e FILE True if file exists.
|
||||
-f FILE True if file exists and is a regular file.
|
||||
-g FILE True if file is set-group-id.
|
||||
-h FILE True if file is a symbolic link.
|
||||
-L FILE True if file is a symbolic link.
|
||||
-k FILE True if file has its `sticky' bit set.
|
||||
-p FILE True if file is a named pipe.
|
||||
-r FILE True if file is readable by you.
|
||||
-s FILE True if file exists and is not empty.
|
||||
-S FILE True if file is a socket.
|
||||
-t FD True if FD is opened on a terminal.
|
||||
-u FILE True if the file is set-user-id.
|
||||
-w FILE True if the file is writable by you.
|
||||
-x FILE True if the file is executable by you.
|
||||
-O FILE True if the file is effectively owned by you.
|
||||
-G FILE True if the file is effectively owned by your group.
|
||||
-N FILE True if the file has been modified since it was last read.
|
||||
|
||||
FILE1 -nt FILE2 True if file1 is newer than file2 (according to
|
||||
modification date).
|
||||
|
||||
FILE1 -ot FILE2 True if file1 is older than file2.
|
||||
|
||||
FILE1 -ef FILE2 True if file1 is a hard link to file2.
|
||||
|
||||
String operators:
|
||||
|
||||
-z STRING True if string is empty.
|
||||
|
||||
-n STRING
|
||||
STRING True if string is not empty.
|
||||
|
||||
STRING1 = STRING2
|
||||
True if the strings are equal.
|
||||
STRING1 != STRING2
|
||||
True if the strings are not equal.
|
||||
STRING1 < STRING2
|
||||
True if STRING1 sorts before STRING2 lexicographically.
|
||||
STRING1 > STRING2
|
||||
True if STRING1 sorts after STRING2 lexicographically.
|
||||
|
||||
Other operators:
|
||||
|
||||
-o OPTION True if the shell option OPTION is enabled.
|
||||
-v VAR True if the shell variable VAR is set
|
||||
! EXPR True if expr is false.
|
||||
EXPR1 -a EXPR2 True if both expr1 AND expr2 are true.
|
||||
EXPR1 -o EXPR2 True if either expr1 OR expr2 is true.
|
||||
|
||||
arg1 OP arg2 Arithmetic tests. OP is one of -eq, -ne,
|
||||
-lt, -le, -gt, or -ge.
|
||||
|
||||
Arithmetic binary operators return true if ARG1 is equal, not-equal,
|
||||
less-than, less-than-or-equal, greater-than, or greater-than-or-equal
|
||||
than ARG2.
|
||||
|
||||
Exit Status:
|
||||
Returns success if EXPR evaluates to true; fails if EXPR evaluates to
|
||||
false or an invalid argument is given.
|
||||
$END
|
||||
|
||||
$BUILTIN [
|
||||
$DOCNAME test_bracket
|
||||
$FUNCTION test_builtin
|
||||
$SHORT_DOC [ arg... ]
|
||||
Evaluate conditional expression.
|
||||
|
||||
This is a synonym for the "test" builtin, but the last argument must
|
||||
be a literal `]', to match the opening `['.
|
||||
$END
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#if defined (HAVE_UNISTD_H)
|
||||
# ifdef _MINIX
|
||||
# include <sys/types.h>
|
||||
# endif
|
||||
# include <unistd.h>
|
||||
#endif
|
||||
|
||||
#include "../bashansi.h"
|
||||
#include "../bashintl.h"
|
||||
|
||||
#include "../shell.h"
|
||||
#include "../test.h"
|
||||
#include "common.h"
|
||||
|
||||
extern char *this_command_name;
|
||||
|
||||
/* TEST/[ builtin. */
|
||||
int
|
||||
test_builtin (list)
|
||||
WORD_LIST *list;
|
||||
{
|
||||
char **argv;
|
||||
int argc, result;
|
||||
|
||||
/* We let Matthew Bradburn and Kevin Braunsdorf's code do the
|
||||
actual test command. So turn the list of args into an array
|
||||
of strings, since that is what their code wants. */
|
||||
if (list == 0)
|
||||
{
|
||||
if (this_command_name[0] == '[' && !this_command_name[1])
|
||||
{
|
||||
builtin_error (_("missing `]'"));
|
||||
return (EX_BADUSAGE);
|
||||
}
|
||||
|
||||
return (EXECUTION_FAILURE);
|
||||
}
|
||||
|
||||
argv = make_builtin_argv (list, &argc);
|
||||
result = test_command (argc, argv);
|
||||
free ((char *)argv);
|
||||
|
||||
return (result);
|
||||
}
|
||||
@@ -1,302 +0,0 @@
|
||||
This file is trap.def, from which is created trap.c.
|
||||
It implements the builtin "trap" in Bash.
|
||||
|
||||
Copyright (C) 1987-2010 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Bash, the Bourne Again SHell.
|
||||
|
||||
Bash is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Bash is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Bash. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
$PRODUCES trap.c
|
||||
|
||||
$BUILTIN trap
|
||||
$FUNCTION trap_builtin
|
||||
$SHORT_DOC trap [-lp] [[arg] signal_spec ...]
|
||||
Trap signals and other events.
|
||||
|
||||
Defines and activates handlers to be run when the shell receives signals
|
||||
or other conditions.
|
||||
|
||||
ARG is a command to be read and executed when the shell receives the
|
||||
signal(s) SIGNAL_SPEC. If ARG is absent (and a single SIGNAL_SPEC
|
||||
is supplied) or `-', each specified signal is reset to its original
|
||||
value. If ARG is the null string each SIGNAL_SPEC is ignored by the
|
||||
shell and by the commands it invokes.
|
||||
|
||||
If a SIGNAL_SPEC is EXIT (0) ARG is executed on exit from the shell. If
|
||||
a SIGNAL_SPEC is DEBUG, ARG is executed before every simple command. If
|
||||
a SIGNAL_SPEC is RETURN, ARG is executed each time a shell function or a
|
||||
script run by the . or source builtins finishes executing.
|
||||
|
||||
If no arguments are supplied, trap prints the list of commands associated
|
||||
with each signal.
|
||||
|
||||
Options:
|
||||
-l print a list of signal names and their corresponding numbers
|
||||
-p display the trap commands associated with each SIGNAL_SPEC
|
||||
|
||||
Each SIGNAL_SPEC is either a signal name in <signal.h> or a signal number.
|
||||
Signal names are case insensitive and the SIG prefix is optional. A
|
||||
signal may be sent to the shell with "kill -signal $$".
|
||||
|
||||
Exit Status:
|
||||
Returns success unless a SIGSPEC is invalid or an invalid option is given.
|
||||
$END
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#if defined (HAVE_UNISTD_H)
|
||||
# ifdef _MINIX
|
||||
# include <sys/types.h>
|
||||
# endif
|
||||
# include <unistd.h>
|
||||
#endif
|
||||
|
||||
#include "../bashtypes.h"
|
||||
#include <signal.h>
|
||||
#include <stdio.h>
|
||||
#include "../bashansi.h"
|
||||
|
||||
#include "../shell.h"
|
||||
#include "../trap.h"
|
||||
#include "common.h"
|
||||
#include "bashgetopt.h"
|
||||
|
||||
static void showtrap __P((int));
|
||||
static int display_traps __P((WORD_LIST *));
|
||||
|
||||
/* The trap command:
|
||||
|
||||
trap <arg> <signal ...>
|
||||
trap <signal ...>
|
||||
trap -l
|
||||
trap -p [sigspec ...]
|
||||
trap [--]
|
||||
|
||||
Set things up so that ARG is executed when SIGNAL(s) N is recieved.
|
||||
If ARG is the empty string, then ignore the SIGNAL(s). If there is
|
||||
no ARG, then set the trap for SIGNAL(s) to its original value. Just
|
||||
plain "trap" means to print out the list of commands associated with
|
||||
each signal number. Single arg of "-l" means list the signal names. */
|
||||
|
||||
/* Possible operations to perform on the list of signals.*/
|
||||
#define SET 0 /* Set this signal to first_arg. */
|
||||
#define REVERT 1 /* Revert to this signals original value. */
|
||||
#define IGNORE 2 /* Ignore this signal. */
|
||||
|
||||
extern int posixly_correct, subshell_environment;
|
||||
|
||||
int
|
||||
trap_builtin (list)
|
||||
WORD_LIST *list;
|
||||
{
|
||||
int list_signal_names, display, result, opt;
|
||||
|
||||
list_signal_names = display = 0;
|
||||
result = EXECUTION_SUCCESS;
|
||||
|
||||
reset_internal_getopt ();
|
||||
while ((opt = internal_getopt (list, "lp")) != -1)
|
||||
{
|
||||
switch (opt)
|
||||
{
|
||||
case 'l':
|
||||
list_signal_names++;
|
||||
break;
|
||||
case 'p':
|
||||
display++;
|
||||
break;
|
||||
default:
|
||||
builtin_usage ();
|
||||
return (EX_USAGE);
|
||||
}
|
||||
}
|
||||
list = loptend;
|
||||
|
||||
opt = DSIG_NOCASE|DSIG_SIGPREFIX; /* flags for decode_signal */
|
||||
|
||||
if (list_signal_names)
|
||||
return (sh_chkwrite (display_signal_list ((WORD_LIST *)NULL, 1)));
|
||||
else if (display || list == 0)
|
||||
{
|
||||
initialize_terminating_signals ();
|
||||
get_all_original_signals ();
|
||||
return (sh_chkwrite (display_traps (list)));
|
||||
}
|
||||
else
|
||||
{
|
||||
char *first_arg;
|
||||
int operation, sig, first_signal;
|
||||
|
||||
operation = SET;
|
||||
first_arg = list->word->word;
|
||||
first_signal = first_arg && *first_arg && all_digits (first_arg) && signal_object_p (first_arg, opt);
|
||||
|
||||
/* Backwards compatibility. XXX - question about whether or not we
|
||||
should throw an error if an all-digit argument doesn't correspond
|
||||
to a valid signal number (e.g., if it's `50' on a system with only
|
||||
32 signals). */
|
||||
if (first_signal)
|
||||
operation = REVERT;
|
||||
/* When in posix mode, the historical behavior of looking for a
|
||||
missing first argument is disabled. To revert to the original
|
||||
signal handling disposition, use `-' as the first argument. */
|
||||
else if (posixly_correct == 0 && first_arg && *first_arg &&
|
||||
(*first_arg != '-' || first_arg[1]) &&
|
||||
signal_object_p (first_arg, opt) && list->next == 0)
|
||||
operation = REVERT;
|
||||
else
|
||||
{
|
||||
list = list->next;
|
||||
if (list == 0)
|
||||
{
|
||||
builtin_usage ();
|
||||
return (EX_USAGE);
|
||||
}
|
||||
else if (*first_arg == '\0')
|
||||
operation = IGNORE;
|
||||
else if (first_arg[0] == '-' && !first_arg[1])
|
||||
operation = REVERT;
|
||||
}
|
||||
|
||||
/* If we're in a command substitution, we haven't freed the trap strings
|
||||
(though we reset the signal handlers). If we're setting a trap to
|
||||
handle a signal here, free the rest of the trap strings since they
|
||||
don't apply any more. */
|
||||
if (subshell_environment & SUBSHELL_RESETTRAP)
|
||||
{
|
||||
free_trap_strings ();
|
||||
subshell_environment &= ~SUBSHELL_RESETTRAP;
|
||||
}
|
||||
|
||||
while (list)
|
||||
{
|
||||
sig = decode_signal (list->word->word, opt);
|
||||
|
||||
if (sig == NO_SIG)
|
||||
{
|
||||
sh_invalidsig (list->word->word);
|
||||
result = EXECUTION_FAILURE;
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (operation)
|
||||
{
|
||||
case SET:
|
||||
set_signal (sig, first_arg);
|
||||
break;
|
||||
|
||||
case REVERT:
|
||||
restore_default_signal (sig);
|
||||
|
||||
/* Signals that the shell treats specially need special
|
||||
handling. */
|
||||
switch (sig)
|
||||
{
|
||||
case SIGINT:
|
||||
/* XXX - should we do this if original disposition
|
||||
was SIG_IGN? */
|
||||
if (interactive)
|
||||
set_signal_handler (SIGINT, sigint_sighandler);
|
||||
else
|
||||
set_signal_handler (SIGINT, termsig_sighandler);
|
||||
break;
|
||||
|
||||
case SIGQUIT:
|
||||
/* Always ignore SIGQUIT. */
|
||||
set_signal_handler (SIGQUIT, SIG_IGN);
|
||||
break;
|
||||
case SIGTERM:
|
||||
#if defined (JOB_CONTROL)
|
||||
case SIGTTIN:
|
||||
case SIGTTOU:
|
||||
case SIGTSTP:
|
||||
#endif /* JOB_CONTROL */
|
||||
if (interactive)
|
||||
set_signal_handler (sig, SIG_IGN);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case IGNORE:
|
||||
ignore_signal (sig);
|
||||
break;
|
||||
}
|
||||
}
|
||||
list = list->next;
|
||||
}
|
||||
}
|
||||
|
||||
return (result);
|
||||
}
|
||||
|
||||
static void
|
||||
showtrap (i)
|
||||
int i;
|
||||
{
|
||||
char *t, *p, *sn;
|
||||
|
||||
p = trap_list[i];
|
||||
if (p == (char *)DEFAULT_SIG && signal_is_hard_ignored (i) == 0)
|
||||
return;
|
||||
else if (signal_is_hard_ignored (i))
|
||||
t = (char *)NULL;
|
||||
else
|
||||
t = (p == (char *)IGNORE_SIG) ? (char *)NULL : sh_single_quote (p);
|
||||
|
||||
sn = signal_name (i);
|
||||
/* Make sure that signals whose names are unknown (for whatever reason)
|
||||
are printed as signal numbers. */
|
||||
if (STREQN (sn, "SIGJUNK", 7) || STREQN (sn, "unknown", 7))
|
||||
printf ("trap -- %s %d\n", t ? t : "''", i);
|
||||
else if (posixly_correct)
|
||||
{
|
||||
if (STREQN (sn, "SIG", 3))
|
||||
printf ("trap -- %s %s\n", t ? t : "''", sn+3);
|
||||
else
|
||||
printf ("trap -- %s %s\n", t ? t : "''", sn);
|
||||
}
|
||||
else
|
||||
printf ("trap -- %s %s\n", t ? t : "''", sn);
|
||||
|
||||
FREE (t);
|
||||
}
|
||||
|
||||
static int
|
||||
display_traps (list)
|
||||
WORD_LIST *list;
|
||||
{
|
||||
int result, i;
|
||||
|
||||
if (list == 0)
|
||||
{
|
||||
for (i = 0; i < BASH_NSIG; i++)
|
||||
showtrap (i);
|
||||
return (EXECUTION_SUCCESS);
|
||||
}
|
||||
|
||||
for (result = EXECUTION_SUCCESS; list; list = list->next)
|
||||
{
|
||||
i = decode_signal (list->word->word, DSIG_NOCASE|DSIG_SIGPREFIX);
|
||||
if (i == NO_SIG)
|
||||
{
|
||||
sh_invalidsig (list->word->word);
|
||||
result = EXECUTION_FAILURE;
|
||||
}
|
||||
else
|
||||
showtrap (i);
|
||||
}
|
||||
|
||||
return (result);
|
||||
}
|
||||
@@ -1,776 +0,0 @@
|
||||
This file is ulimit.def, from which is created ulimit.c.
|
||||
It implements the builtin "ulimit" in Bash.
|
||||
|
||||
Copyright (C) 1987-2009 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Bash, the Bourne Again SHell.
|
||||
|
||||
Bash is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Bash is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Bash. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
$PRODUCES ulimit.c
|
||||
|
||||
$BUILTIN ulimit
|
||||
$FUNCTION ulimit_builtin
|
||||
$DEPENDS_ON !_MINIX
|
||||
$SHORT_DOC ulimit [-SHacdefilmnpqrstuvx] [limit]
|
||||
Modify shell resource limits.
|
||||
|
||||
Provides control over the resources available to the shell and processes
|
||||
it creates, on systems that allow such control.
|
||||
|
||||
Options:
|
||||
-S use the `soft' resource limit
|
||||
-H use the `hard' resource limit
|
||||
-a all current limits are reported
|
||||
-b the socket buffer size
|
||||
-c the maximum size of core files created
|
||||
-d the maximum size of a process's data segment
|
||||
-e the maximum scheduling priority (`nice')
|
||||
-f the maximum size of files written by the shell and its children
|
||||
-i the maximum number of pending signals
|
||||
-l the maximum size a process may lock into memory
|
||||
-m the maximum resident set size
|
||||
-n the maximum number of open file descriptors
|
||||
-p the pipe buffer size
|
||||
-q the maximum number of bytes in POSIX message queues
|
||||
-r the maximum real-time scheduling priority
|
||||
-s the maximum stack size
|
||||
-t the maximum amount of cpu time in seconds
|
||||
-u the maximum number of user processes
|
||||
-v the size of virtual memory
|
||||
-x the maximum number of file locks
|
||||
|
||||
If LIMIT is given, it is the new value of the specified resource; the
|
||||
special LIMIT values `soft', `hard', and `unlimited' stand for the
|
||||
current soft limit, the current hard limit, and no limit, respectively.
|
||||
Otherwise, the current value of the specified resource is printed. If
|
||||
no option is given, then -f is assumed.
|
||||
|
||||
Values are in 1024-byte increments, except for -t, which is in seconds,
|
||||
-p, which is in increments of 512 bytes, and -u, which is an unscaled
|
||||
number of processes.
|
||||
|
||||
Exit Status:
|
||||
Returns success unless an invalid option is supplied or an error occurs.
|
||||
$END
|
||||
|
||||
#if !defined (_MINIX)
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include "../bashtypes.h"
|
||||
#ifndef _MINIX
|
||||
# include <sys/param.h>
|
||||
#endif
|
||||
|
||||
#if defined (HAVE_UNISTD_H)
|
||||
# include <unistd.h>
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "../bashintl.h"
|
||||
|
||||
#include "../shell.h"
|
||||
#include "common.h"
|
||||
#include "bashgetopt.h"
|
||||
#include "pipesize.h"
|
||||
|
||||
#if !defined (errno)
|
||||
extern int errno;
|
||||
#endif
|
||||
|
||||
/* For some reason, HPUX chose to make these definitions visible only if
|
||||
_KERNEL is defined, so we define _KERNEL before including <sys/resource.h>
|
||||
and #undef it afterward. */
|
||||
#if defined (HAVE_RESOURCE)
|
||||
# include <sys/time.h>
|
||||
# if defined (HPUX) && defined (RLIMIT_NEEDS_KERNEL)
|
||||
# define _KERNEL
|
||||
# endif
|
||||
# include <sys/resource.h>
|
||||
# if defined (HPUX) && defined (RLIMIT_NEEDS_KERNEL)
|
||||
# undef _KERNEL
|
||||
# endif
|
||||
#elif defined (HAVE_SYS_TIMES_H)
|
||||
# include <sys/times.h>
|
||||
#endif
|
||||
|
||||
#if defined (HAVE_LIMITS_H)
|
||||
# include <limits.h>
|
||||
#endif
|
||||
|
||||
/* Check for the most basic symbols. If they aren't present, this
|
||||
system's <sys/resource.h> isn't very useful to us. */
|
||||
#if !defined (RLIMIT_FSIZE) || !defined (HAVE_GETRLIMIT)
|
||||
# undef HAVE_RESOURCE
|
||||
#endif
|
||||
|
||||
#if !defined (HAVE_RESOURCE) && defined (HAVE_ULIMIT_H)
|
||||
# include <ulimit.h>
|
||||
#endif
|
||||
|
||||
#if !defined (RLIMTYPE)
|
||||
# define RLIMTYPE long
|
||||
# define string_to_rlimtype(s) strtol(s, (char **)NULL, 10)
|
||||
# define print_rlimtype(num, nl) printf ("%ld%s", num, nl ? "\n" : "")
|
||||
#endif
|
||||
|
||||
/* Some systems use RLIMIT_NOFILE, others use RLIMIT_OFILE */
|
||||
#if defined (HAVE_RESOURCE) && defined (RLIMIT_OFILE) && !defined (RLIMIT_NOFILE)
|
||||
# define RLIMIT_NOFILE RLIMIT_OFILE
|
||||
#endif /* HAVE_RESOURCE && RLIMIT_OFILE && !RLIMIT_NOFILE */
|
||||
|
||||
/* Some systems have these, some do not. */
|
||||
#ifdef RLIMIT_FSIZE
|
||||
# define RLIMIT_FILESIZE RLIMIT_FSIZE
|
||||
#else
|
||||
# define RLIMIT_FILESIZE 256
|
||||
#endif
|
||||
|
||||
#define RLIMIT_PIPESIZE 257
|
||||
|
||||
#ifdef RLIMIT_NOFILE
|
||||
# define RLIMIT_OPENFILES RLIMIT_NOFILE
|
||||
#else
|
||||
# define RLIMIT_OPENFILES 258
|
||||
#endif
|
||||
|
||||
#ifdef RLIMIT_VMEM
|
||||
# define RLIMIT_VIRTMEM RLIMIT_VMEM
|
||||
# define RLIMIT_VMBLKSZ 1024
|
||||
#else
|
||||
# ifdef RLIMIT_AS
|
||||
# define RLIMIT_VIRTMEM RLIMIT_AS
|
||||
# define RLIMIT_VMBLKSZ 1024
|
||||
# else
|
||||
# define RLIMIT_VIRTMEM 259
|
||||
# define RLIMIT_VMBLKSZ 1
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifdef RLIMIT_NPROC
|
||||
# define RLIMIT_MAXUPROC RLIMIT_NPROC
|
||||
#else
|
||||
# define RLIMIT_MAXUPROC 260
|
||||
#endif
|
||||
|
||||
#if !defined (RLIM_INFINITY)
|
||||
# define RLIM_INFINITY 0x7fffffff
|
||||
#endif
|
||||
|
||||
#if !defined (RLIM_SAVED_CUR)
|
||||
# define RLIM_SAVED_CUR RLIM_INFINITY
|
||||
#endif
|
||||
|
||||
#if !defined (RLIM_SAVED_MAX)
|
||||
# define RLIM_SAVED_MAX RLIM_INFINITY
|
||||
#endif
|
||||
|
||||
#define LIMIT_HARD 0x01
|
||||
#define LIMIT_SOFT 0x02
|
||||
|
||||
/* "Blocks" are defined as 512 bytes when in Posix mode and 1024 bytes
|
||||
otherwise. */
|
||||
#define POSIXBLK -2
|
||||
|
||||
#define BLOCKSIZE(x) (((x) == POSIXBLK) ? (posixly_correct ? 512 : 1024) : (x))
|
||||
|
||||
extern int posixly_correct;
|
||||
|
||||
static int _findlim __P((int));
|
||||
|
||||
static int ulimit_internal __P((int, char *, int, int));
|
||||
|
||||
static int get_limit __P((int, RLIMTYPE *, RLIMTYPE *));
|
||||
static int set_limit __P((int, RLIMTYPE, int));
|
||||
|
||||
static void printone __P((int, RLIMTYPE, int));
|
||||
static void print_all_limits __P((int));
|
||||
|
||||
static int set_all_limits __P((int, RLIMTYPE));
|
||||
|
||||
static int filesize __P((RLIMTYPE *));
|
||||
static int pipesize __P((RLIMTYPE *));
|
||||
static int getmaxuprc __P((RLIMTYPE *));
|
||||
static int getmaxvm __P((RLIMTYPE *, RLIMTYPE *));
|
||||
|
||||
typedef struct {
|
||||
int option; /* The ulimit option for this limit. */
|
||||
int parameter; /* Parameter to pass to get_limit (). */
|
||||
int block_factor; /* Blocking factor for specific limit. */
|
||||
const char * const description; /* Descriptive string to output. */
|
||||
const char * const units; /* scale */
|
||||
} RESOURCE_LIMITS;
|
||||
|
||||
static RESOURCE_LIMITS limits[] = {
|
||||
#ifdef RLIMIT_PTHREAD
|
||||
{ 'T', RLIMIT_PTHREAD, 1, "number of threads", (char *)NULL },
|
||||
#endif
|
||||
#ifdef RLIMIT_SBSIZE
|
||||
{ 'b', RLIMIT_SBSIZE, 1, "socket buffer size", "bytes" },
|
||||
#endif
|
||||
#ifdef RLIMIT_CORE
|
||||
{ 'c', RLIMIT_CORE, POSIXBLK, "core file size", "blocks" },
|
||||
#endif
|
||||
#ifdef RLIMIT_DATA
|
||||
{ 'd', RLIMIT_DATA, 1024, "data seg size", "kbytes" },
|
||||
#endif
|
||||
#ifdef RLIMIT_NICE
|
||||
{ 'e', RLIMIT_NICE, 1, "scheduling priority", (char *)NULL },
|
||||
#endif
|
||||
{ 'f', RLIMIT_FILESIZE, POSIXBLK, "file size", "blocks" },
|
||||
#ifdef RLIMIT_SIGPENDING
|
||||
{ 'i', RLIMIT_SIGPENDING, 1, "pending signals", (char *)NULL },
|
||||
#endif
|
||||
#ifdef RLIMIT_MEMLOCK
|
||||
{ 'l', RLIMIT_MEMLOCK, 1024, "max locked memory", "kbytes" },
|
||||
#endif
|
||||
#ifdef RLIMIT_RSS
|
||||
{ 'm', RLIMIT_RSS, 1024, "max memory size", "kbytes" },
|
||||
#endif /* RLIMIT_RSS */
|
||||
{ 'n', RLIMIT_OPENFILES, 1, "open files", (char *)NULL},
|
||||
{ 'p', RLIMIT_PIPESIZE, 512, "pipe size", "512 bytes" },
|
||||
#ifdef RLIMIT_MSGQUEUE
|
||||
{ 'q', RLIMIT_MSGQUEUE, 1, "POSIX message queues", "bytes" },
|
||||
#endif
|
||||
#ifdef RLIMIT_RTPRIO
|
||||
{ 'r', RLIMIT_RTPRIO, 1, "real-time priority", (char *)NULL },
|
||||
#endif
|
||||
#ifdef RLIMIT_STACK
|
||||
{ 's', RLIMIT_STACK, 1024, "stack size", "kbytes" },
|
||||
#endif
|
||||
#ifdef RLIMIT_CPU
|
||||
{ 't', RLIMIT_CPU, 1, "cpu time", "seconds" },
|
||||
#endif /* RLIMIT_CPU */
|
||||
{ 'u', RLIMIT_MAXUPROC, 1, "max user processes", (char *)NULL },
|
||||
#if defined (HAVE_RESOURCE)
|
||||
{ 'v', RLIMIT_VIRTMEM, RLIMIT_VMBLKSZ, "virtual memory", "kbytes" },
|
||||
#endif
|
||||
#ifdef RLIMIT_SWAP
|
||||
{ 'w', RLIMIT_SWAP, 1024, "swap size", "kbytes" },
|
||||
#endif
|
||||
#ifdef RLIMIT_LOCKS
|
||||
{ 'x', RLIMIT_LOCKS, 1, "file locks", (char *)NULL },
|
||||
#endif
|
||||
{ -1, -1, -1, (char *)NULL, (char *)NULL }
|
||||
};
|
||||
#define NCMDS (sizeof(limits) / sizeof(limits[0]))
|
||||
|
||||
typedef struct _cmd {
|
||||
int cmd;
|
||||
char *arg;
|
||||
} ULCMD;
|
||||
|
||||
static ULCMD *cmdlist;
|
||||
static int ncmd;
|
||||
static int cmdlistsz;
|
||||
|
||||
#if !defined (HAVE_RESOURCE) && !defined (HAVE_ULIMIT)
|
||||
long
|
||||
ulimit (cmd, newlim)
|
||||
int cmd;
|
||||
long newlim;
|
||||
{
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
#endif /* !HAVE_RESOURCE && !HAVE_ULIMIT */
|
||||
|
||||
static int
|
||||
_findlim (opt)
|
||||
int opt;
|
||||
{
|
||||
register int i;
|
||||
|
||||
for (i = 0; limits[i].option > 0; i++)
|
||||
if (limits[i].option == opt)
|
||||
return i;
|
||||
return -1;
|
||||
}
|
||||
|
||||
static char optstring[4 + 2 * NCMDS];
|
||||
|
||||
/* Report or set limits associated with certain per-process resources.
|
||||
See the help documentation in builtins.c for a full description. */
|
||||
int
|
||||
ulimit_builtin (list)
|
||||
register WORD_LIST *list;
|
||||
{
|
||||
register char *s;
|
||||
int c, limind, mode, opt, all_limits;
|
||||
|
||||
mode = 0;
|
||||
|
||||
all_limits = 0;
|
||||
|
||||
/* Idea stolen from pdksh -- build option string the first time called. */
|
||||
if (optstring[0] == 0)
|
||||
{
|
||||
s = optstring;
|
||||
*s++ = 'a'; *s++ = 'S'; *s++ = 'H';
|
||||
for (c = 0; limits[c].option > 0; c++)
|
||||
{
|
||||
*s++ = limits[c].option;
|
||||
*s++ = ';';
|
||||
}
|
||||
*s = '\0';
|
||||
}
|
||||
|
||||
/* Initialize the command list. */
|
||||
if (cmdlistsz == 0)
|
||||
cmdlist = (ULCMD *)xmalloc ((cmdlistsz = 16) * sizeof (ULCMD));
|
||||
ncmd = 0;
|
||||
|
||||
reset_internal_getopt ();
|
||||
while ((opt = internal_getopt (list, optstring)) != -1)
|
||||
{
|
||||
switch (opt)
|
||||
{
|
||||
case 'a':
|
||||
all_limits++;
|
||||
break;
|
||||
|
||||
/* -S and -H are modifiers, not real options. */
|
||||
case 'S':
|
||||
mode |= LIMIT_SOFT;
|
||||
break;
|
||||
|
||||
case 'H':
|
||||
mode |= LIMIT_HARD;
|
||||
break;
|
||||
|
||||
case '?':
|
||||
builtin_usage ();
|
||||
return (EX_USAGE);
|
||||
|
||||
default:
|
||||
if (ncmd >= cmdlistsz)
|
||||
cmdlist = (ULCMD *)xrealloc (cmdlist, (cmdlistsz *= 2) * sizeof (ULCMD));
|
||||
cmdlist[ncmd].cmd = opt;
|
||||
cmdlist[ncmd++].arg = list_optarg;
|
||||
break;
|
||||
}
|
||||
}
|
||||
list = loptend;
|
||||
|
||||
if (all_limits)
|
||||
{
|
||||
#ifdef NOTYET
|
||||
if (list) /* setting */
|
||||
{
|
||||
if (STREQ (list->word->word, "unlimited") == 0)
|
||||
{
|
||||
builtin_error (_("%s: invalid limit argument"), list->word->word);
|
||||
return (EXECUTION_FAILURE);
|
||||
}
|
||||
return (set_all_limits (mode == 0 ? LIMIT_SOFT|LIMIT_HARD : mode, RLIM_INFINITY));
|
||||
}
|
||||
#endif
|
||||
print_all_limits (mode == 0 ? LIMIT_SOFT : mode);
|
||||
return (sh_chkwrite (EXECUTION_SUCCESS));
|
||||
}
|
||||
|
||||
/* default is `ulimit -f' */
|
||||
if (ncmd == 0)
|
||||
{
|
||||
cmdlist[ncmd].cmd = 'f';
|
||||
/* `ulimit something' is same as `ulimit -f something' */
|
||||
cmdlist[ncmd++].arg = list ? list->word->word : (char *)NULL;
|
||||
if (list)
|
||||
list = list->next;
|
||||
}
|
||||
|
||||
/* verify each command in the list. */
|
||||
for (c = 0; c < ncmd; c++)
|
||||
{
|
||||
limind = _findlim (cmdlist[c].cmd);
|
||||
if (limind == -1)
|
||||
{
|
||||
builtin_error (_("`%c': bad command"), cmdlist[c].cmd);
|
||||
return (EX_USAGE);
|
||||
}
|
||||
}
|
||||
|
||||
for (c = 0; c < ncmd; c++)
|
||||
if (ulimit_internal (cmdlist[c].cmd, cmdlist[c].arg, mode, ncmd > 1) == EXECUTION_FAILURE)
|
||||
return (EXECUTION_FAILURE);
|
||||
|
||||
return (EXECUTION_SUCCESS);
|
||||
}
|
||||
|
||||
static int
|
||||
ulimit_internal (cmd, cmdarg, mode, multiple)
|
||||
int cmd;
|
||||
char *cmdarg;
|
||||
int mode, multiple;
|
||||
{
|
||||
int opt, limind, setting;
|
||||
int block_factor;
|
||||
RLIMTYPE soft_limit, hard_limit, real_limit, limit;
|
||||
|
||||
setting = cmdarg != 0;
|
||||
limind = _findlim (cmd);
|
||||
if (mode == 0)
|
||||
mode = setting ? (LIMIT_HARD|LIMIT_SOFT) : LIMIT_SOFT;
|
||||
opt = get_limit (limind, &soft_limit, &hard_limit);
|
||||
if (opt < 0)
|
||||
{
|
||||
builtin_error (_("%s: cannot get limit: %s"), limits[limind].description,
|
||||
strerror (errno));
|
||||
return (EXECUTION_FAILURE);
|
||||
}
|
||||
|
||||
if (setting == 0) /* print the value of the specified limit */
|
||||
{
|
||||
printone (limind, (mode & LIMIT_SOFT) ? soft_limit : hard_limit, multiple);
|
||||
return (EXECUTION_SUCCESS);
|
||||
}
|
||||
|
||||
/* Setting the limit. */
|
||||
if (STREQ (cmdarg, "hard"))
|
||||
real_limit = hard_limit;
|
||||
else if (STREQ (cmdarg, "soft"))
|
||||
real_limit = soft_limit;
|
||||
else if (STREQ (cmdarg, "unlimited"))
|
||||
real_limit = RLIM_INFINITY;
|
||||
else if (all_digits (cmdarg))
|
||||
{
|
||||
limit = string_to_rlimtype (cmdarg);
|
||||
block_factor = BLOCKSIZE(limits[limind].block_factor);
|
||||
real_limit = limit * block_factor;
|
||||
|
||||
if ((real_limit / block_factor) != limit)
|
||||
{
|
||||
sh_erange (cmdarg, _("limit"));
|
||||
return (EXECUTION_FAILURE);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
sh_invalidnum (cmdarg);
|
||||
return (EXECUTION_FAILURE);
|
||||
}
|
||||
|
||||
if (set_limit (limind, real_limit, mode) < 0)
|
||||
{
|
||||
builtin_error (_("%s: cannot modify limit: %s"), limits[limind].description,
|
||||
strerror (errno));
|
||||
return (EXECUTION_FAILURE);
|
||||
}
|
||||
|
||||
return (EXECUTION_SUCCESS);
|
||||
}
|
||||
|
||||
static int
|
||||
get_limit (ind, softlim, hardlim)
|
||||
int ind;
|
||||
RLIMTYPE *softlim, *hardlim;
|
||||
{
|
||||
RLIMTYPE value;
|
||||
#if defined (HAVE_RESOURCE)
|
||||
struct rlimit limit;
|
||||
#endif
|
||||
|
||||
if (limits[ind].parameter >= 256)
|
||||
{
|
||||
switch (limits[ind].parameter)
|
||||
{
|
||||
case RLIMIT_FILESIZE:
|
||||
if (filesize (&value) < 0)
|
||||
return -1;
|
||||
break;
|
||||
case RLIMIT_PIPESIZE:
|
||||
if (pipesize (&value) < 0)
|
||||
return -1;
|
||||
break;
|
||||
case RLIMIT_OPENFILES:
|
||||
value = (RLIMTYPE)getdtablesize ();
|
||||
break;
|
||||
case RLIMIT_VIRTMEM:
|
||||
return (getmaxvm (softlim, hardlim));
|
||||
case RLIMIT_MAXUPROC:
|
||||
if (getmaxuprc (&value) < 0)
|
||||
return -1;
|
||||
break;
|
||||
default:
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
*softlim = *hardlim = value;
|
||||
return (0);
|
||||
}
|
||||
else
|
||||
{
|
||||
#if defined (HAVE_RESOURCE)
|
||||
if (getrlimit (limits[ind].parameter, &limit) < 0)
|
||||
return -1;
|
||||
*softlim = limit.rlim_cur;
|
||||
*hardlim = limit.rlim_max;
|
||||
# if defined (HPUX9)
|
||||
if (limits[ind].parameter == RLIMIT_FILESIZE)
|
||||
{
|
||||
*softlim *= 512;
|
||||
*hardlim *= 512; /* Ugh. */
|
||||
}
|
||||
else
|
||||
# endif /* HPUX9 */
|
||||
return 0;
|
||||
#else
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
set_limit (ind, newlim, mode)
|
||||
int ind;
|
||||
RLIMTYPE newlim;
|
||||
int mode;
|
||||
{
|
||||
#if defined (HAVE_RESOURCE)
|
||||
struct rlimit limit;
|
||||
RLIMTYPE val;
|
||||
#endif
|
||||
|
||||
if (limits[ind].parameter >= 256)
|
||||
switch (limits[ind].parameter)
|
||||
{
|
||||
case RLIMIT_FILESIZE:
|
||||
#if !defined (HAVE_RESOURCE)
|
||||
return (ulimit (2, newlim / 512L));
|
||||
#else
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
#endif
|
||||
|
||||
case RLIMIT_OPENFILES:
|
||||
#if defined (HAVE_SETDTABLESIZE)
|
||||
# if defined (__CYGWIN__)
|
||||
/* Grrr... Cygwin declares setdtablesize as void. */
|
||||
setdtablesize (newlim);
|
||||
return 0;
|
||||
# else
|
||||
return (setdtablesize (newlim));
|
||||
# endif
|
||||
#endif
|
||||
case RLIMIT_PIPESIZE:
|
||||
case RLIMIT_VIRTMEM:
|
||||
case RLIMIT_MAXUPROC:
|
||||
default:
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
#if defined (HAVE_RESOURCE)
|
||||
if (getrlimit (limits[ind].parameter, &limit) < 0)
|
||||
return -1;
|
||||
# if defined (HPUX9)
|
||||
if (limits[ind].parameter == RLIMIT_FILESIZE)
|
||||
newlim /= 512; /* Ugh. */
|
||||
# endif /* HPUX9 */
|
||||
val = (current_user.euid != 0 && newlim == RLIM_INFINITY &&
|
||||
(mode & LIMIT_HARD) == 0 && /* XXX -- test */
|
||||
(limit.rlim_cur <= limit.rlim_max))
|
||||
? limit.rlim_max : newlim;
|
||||
if (mode & LIMIT_SOFT)
|
||||
limit.rlim_cur = val;
|
||||
if (mode & LIMIT_HARD)
|
||||
limit.rlim_max = val;
|
||||
|
||||
return (setrlimit (limits[ind].parameter, &limit));
|
||||
#else
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
getmaxvm (softlim, hardlim)
|
||||
RLIMTYPE *softlim, *hardlim;
|
||||
{
|
||||
#if defined (HAVE_RESOURCE)
|
||||
struct rlimit datalim, stacklim;
|
||||
|
||||
if (getrlimit (RLIMIT_DATA, &datalim) < 0)
|
||||
return -1;
|
||||
|
||||
if (getrlimit (RLIMIT_STACK, &stacklim) < 0)
|
||||
return -1;
|
||||
|
||||
/* Protect against overflow. */
|
||||
*softlim = (datalim.rlim_cur / 1024L) + (stacklim.rlim_cur / 1024L);
|
||||
*hardlim = (datalim.rlim_max / 1024L) + (stacklim.rlim_max / 1024L);
|
||||
return 0;
|
||||
#else
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
#endif /* HAVE_RESOURCE */
|
||||
}
|
||||
|
||||
static int
|
||||
filesize(valuep)
|
||||
RLIMTYPE *valuep;
|
||||
{
|
||||
#if !defined (HAVE_RESOURCE)
|
||||
long result;
|
||||
if ((result = ulimit (1, 0L)) < 0)
|
||||
return -1;
|
||||
else
|
||||
*valuep = (RLIMTYPE) result * 512;
|
||||
return 0;
|
||||
#else
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
#endif
|
||||
}
|
||||
|
||||
static int
|
||||
pipesize (valuep)
|
||||
RLIMTYPE *valuep;
|
||||
{
|
||||
#if defined (PIPE_BUF)
|
||||
/* This is defined on Posix systems. */
|
||||
*valuep = (RLIMTYPE) PIPE_BUF;
|
||||
return 0;
|
||||
#else
|
||||
# if defined (_POSIX_PIPE_BUF)
|
||||
*valuep = (RLIMTYPE) _POSIX_PIPE_BUF;
|
||||
return 0;
|
||||
# else
|
||||
# if defined (PIPESIZE)
|
||||
/* This is defined by running a program from the Makefile. */
|
||||
*valuep = (RLIMTYPE) PIPESIZE;
|
||||
return 0;
|
||||
# else
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
# endif /* PIPESIZE */
|
||||
# endif /* _POSIX_PIPE_BUF */
|
||||
#endif /* PIPE_BUF */
|
||||
}
|
||||
|
||||
static int
|
||||
getmaxuprc (valuep)
|
||||
RLIMTYPE *valuep;
|
||||
{
|
||||
long maxchild;
|
||||
|
||||
maxchild = getmaxchild ();
|
||||
if (maxchild < 0)
|
||||
{
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
*valuep = (RLIMTYPE) maxchild;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
print_all_limits (mode)
|
||||
int mode;
|
||||
{
|
||||
register int i;
|
||||
RLIMTYPE softlim, hardlim;
|
||||
|
||||
if (mode == 0)
|
||||
mode |= LIMIT_SOFT;
|
||||
|
||||
for (i = 0; limits[i].option > 0; i++)
|
||||
{
|
||||
if (get_limit (i, &softlim, &hardlim) == 0)
|
||||
printone (i, (mode & LIMIT_SOFT) ? softlim : hardlim, 1);
|
||||
else if (errno != EINVAL)
|
||||
builtin_error ("%s: cannot get limit: %s", limits[i].description,
|
||||
strerror (errno));
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
printone (limind, curlim, pdesc)
|
||||
int limind;
|
||||
RLIMTYPE curlim;
|
||||
int pdesc;
|
||||
{
|
||||
char unitstr[64];
|
||||
int factor;
|
||||
|
||||
factor = BLOCKSIZE(limits[limind].block_factor);
|
||||
if (pdesc)
|
||||
{
|
||||
if (limits[limind].units)
|
||||
sprintf (unitstr, "(%s, -%c) ", limits[limind].units, limits[limind].option);
|
||||
else
|
||||
sprintf (unitstr, "(-%c) ", limits[limind].option);
|
||||
|
||||
printf ("%-20s %16s", limits[limind].description, unitstr);
|
||||
}
|
||||
if (curlim == RLIM_INFINITY)
|
||||
puts ("unlimited");
|
||||
else if (curlim == RLIM_SAVED_MAX)
|
||||
puts ("hard");
|
||||
else if (curlim == RLIM_SAVED_CUR)
|
||||
puts ("soft");
|
||||
else
|
||||
print_rlimtype ((curlim / factor), 1);
|
||||
}
|
||||
|
||||
/* Set all limits to NEWLIM. NEWLIM currently must be RLIM_INFINITY, which
|
||||
causes all limits to be set as high as possible depending on mode (like
|
||||
csh `unlimit'). Returns -1 if NEWLIM is invalid, 0 if all limits
|
||||
were set successfully, and 1 if at least one limit could not be set.
|
||||
|
||||
To raise all soft limits to their corresponding hard limits, use
|
||||
ulimit -S -a unlimited
|
||||
To attempt to raise all hard limits to infinity (superuser-only), use
|
||||
ulimit -H -a unlimited
|
||||
To attempt to raise all soft and hard limits to infinity, use
|
||||
ulimit -a unlimited
|
||||
*/
|
||||
|
||||
static int
|
||||
set_all_limits (mode, newlim)
|
||||
int mode;
|
||||
RLIMTYPE newlim;
|
||||
{
|
||||
register int i;
|
||||
int retval = 0;
|
||||
|
||||
if (newlim != RLIM_INFINITY)
|
||||
{
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (mode == 0)
|
||||
mode = LIMIT_SOFT|LIMIT_HARD;
|
||||
|
||||
for (retval = i = 0; limits[i].option > 0; i++)
|
||||
if (set_limit (i, newlim, mode) < 0)
|
||||
{
|
||||
builtin_error (_("%s: cannot modify limit: %s"), limits[i].description,
|
||||
strerror (errno));
|
||||
retval = 1;
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
#endif /* !_MINIX */
|
||||
Reference in New Issue
Block a user