add directory bin

This commit is contained in:
gohigh
2024-02-19 00:21:52 -05:00
parent 1b1e027f34
commit 42f484790f
611 changed files with 242668 additions and 0 deletions

View File

@@ -0,0 +1 @@
1.11

257
bin/old/bash-1.11/COPYING Normal file
View File

@@ -0,0 +1,257 @@
GNU GENERAL PUBLIC LICENSE
Version 1, February 1989
Copyright (C) 1989 Free Software Foundation, Inc.
675 Mass Ave, Cambridge, MA 02139, USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
The Free Software Foundation has exempted Bash from the requirement of
Paragraph 2c of the General Public License. This is to say, there is
no requirement for Bash to print a notice when it is started
interactively in the usual way. We made this exception because users
and standards expect shells not to print such messages. This
exception applies to any program that serves as a shell and that is
based primarily on Bash as opposed to other GNU software.
Preamble
The license agreements of most software companies try to keep users
at the mercy of those companies. By contrast, our General Public
License is intended to guarantee your freedom to share and change free
software--to make sure the software is free for all its users. The
General Public License applies to the Free Software Foundation's
software and to any other program whose authors commit to using it.
You can use it for your programs, too.
When we speak of free software, we are referring to freedom, not
price. Specifically, the General Public License is designed to make
sure that you have the freedom to give away or sell copies of free
software, that you receive source code or can get it if you want it,
that you can change the software or use pieces of it in new free
programs; and that you know you can do these things.
To protect your rights, we need to make restrictions that forbid
anyone to deny you these rights or to ask you to surrender the rights.
These restrictions translate to certain responsibilities for you if you
distribute copies of the software, or if you modify it.
For example, if you distribute copies of a such a program, whether
gratis or for a fee, you must give the recipients all the rights that
you have. You must make sure that they, too, receive or can get the
source code. And you must tell them their rights.
We protect your rights with two steps: (1) copyright the software, and
(2) offer you this license which gives you legal permission to copy,
distribute and/or modify the software.
Also, for each author's protection and ours, we want to make certain
that everyone understands that there is no warranty for this free
software. If the software is modified by someone else and passed on, we
want its recipients to know that what they have is not the original, so
that any problems introduced by others will not reflect on the original
authors' reputations.
The precise terms and conditions for copying, distribution and
modification follow.
GNU GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License Agreement applies to any program or other work which
contains a notice placed by the copyright holder saying it may be
distributed under the terms of this General Public License. The
"Program", below, refers to any such program or work, and a "work based
on the Program" means either the Program or any work containing the
Program or a portion of it, either verbatim or with modifications. Each
licensee is addressed as "you".
1. You may copy and distribute verbatim copies of the Program's source
code as you receive it, in any medium, provided that you conspicuously and
appropriately publish on each copy an appropriate copyright notice and
disclaimer of warranty; keep intact all the notices that refer to this
General Public License and to the absence of any warranty; and give any
other recipients of the Program a copy of this General Public License
along with the Program. You may charge a fee for the physical act of
transferring a copy.
2. You may modify your copy or copies of the Program or any portion of
it, and copy and distribute such modifications under the terms of Paragraph
1 above, provided that you also do the following:
a) cause the modified files to carry prominent notices stating that
you changed the files and the date of any change; and
b) cause the whole of any work that you distribute or publish, that
in whole or in part contains the Program or any part thereof, either
with or without modifications, to be licensed at no charge to all
third parties under the terms of this General Public License (except
that you may choose to grant warranty protection to some or all
third parties, at your option).
c) If the modified program normally reads commands interactively when
run, you must cause it, when started running for such interactive use
in the simplest and most usual way, to print or display an
announcement including an appropriate copyright notice and a notice
that there is no warranty (or else, saying that you provide a
warranty) and that users may redistribute the program under these
conditions, and telling the user how to view a copy of this General
Public License.
d) You may charge a fee for the physical act of transferring a
copy, and you may at your option offer warranty protection in
exchange for a fee.
Mere aggregation of another independent work with the Program (or its
derivative) on a volume of a storage or distribution medium does not bring
the other work under the scope of these terms.
3. You may copy and distribute the Program (or a portion or derivative of
it, under Paragraph 2) in object code or executable form under the terms of
Paragraphs 1 and 2 above provided that you also do one of the following:
a) accompany it with the complete corresponding machine-readable
source code, which must be distributed under the terms of
Paragraphs 1 and 2 above; or,
b) accompany it with a written offer, valid for at least three
years, to give any third party free (except for a nominal charge
for the cost of distribution) a complete machine-readable copy of the
corresponding source code, to be distributed under the terms of
Paragraphs 1 and 2 above; or,
c) accompany it with the information you received as to where the
corresponding source code may be obtained. (This alternative is
allowed only for noncommercial distribution and only if you
received the program in object code or executable form alone.)
Source code for a work means the preferred form of the work for making
modifications to it. For an executable file, complete source code means
all the source code for all modules it contains; but, as a special
exception, it need not include source code for modules which are standard
libraries that accompany the operating system on which the executable
file runs, or for standard header files or definitions files that
accompany that operating system.
4. You may not copy, modify, sublicense, distribute or transfer the
Program except as expressly provided under this General Public License.
Any attempt otherwise to copy, modify, sublicense, distribute or transfer
the Program is void, and will automatically terminate your rights to use
the Program under this License. However, parties who have received
copies, or rights to use copies, from you under this General Public
License will not have their licenses terminated so long as such parties
remain in full compliance.
5. By copying, distributing or modifying the Program (or any work based
on the Program) you indicate your acceptance of this license to do so,
and all its terms and conditions.
6. Each time you redistribute the Program (or any work based on the
Program), the recipient automatically receives a license from the original
licensor to copy, distribute or modify the Program subject to these
terms and conditions. You may not impose any further restrictions on the
recipients' exercise of the rights granted herein.
7. The Free Software Foundation may publish revised and/or new versions
of the General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the Program
specifies a version number of the license which applies to it and "any
later version", you have the option of following the terms and conditions
either of that version or of any later version published by the Free
Software Foundation. If the Program does not specify a version number of
the license, you may choose any version ever published by the Free Software
Foundation.
8. If you wish to incorporate parts of the Program into other free
programs whose distribution conditions are different, write to the author
to ask for permission. For software which is copyrighted by the Free
Software Foundation, write to the Free Software Foundation; we sometimes
make exceptions for this. Our decision will be guided by the two goals
of preserving the free status of all derivatives of our free software and
of promoting the sharing and reuse of software generally.
NO WARRANTY
9. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
REPAIR OR CORRECTION.
10. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES.
END OF TERMS AND CONDITIONS
Appendix: How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to humanity, the best way to achieve this is to make it
free software which everyone can redistribute and change under these
terms.
To do so, attach the following notices to the program. It is safest to
attach them to the start of each source file to most effectively convey
the exclusion of warranty; and each file should have at least the
"copyright" line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) 19yy <name of author>
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 1, 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., 675 Mass Ave, Cambridge, MA 02139, USA.
Also add information on how to contact you by electronic and paper mail.
If the program is interactive, make it output a short notice like this
when it starts in an interactive mode:
Gnomovision version 69, Copyright (C) 19xx name of author
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the
appropriate parts of the General Public License. Of course, the
commands you use may be called something other than `show w' and `show
c'; they could even be mouse-clicks or menu items--whatever suits your
program.
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the program, if
necessary. Here a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the
program `Gnomovision' (a program to direct compilers to make passes
at assemblers) written by James Hacker.
<signature of Ty Coon>, 1 April 1989
Ty Coon, President of Vice
That's all there is to it!

1020
bin/old/bash-1.11/ChangeLog Normal file

File diff suppressed because it is too large Load Diff

195
bin/old/bash-1.11/INSTALL Normal file
View File

@@ -0,0 +1,195 @@
File: bash.info, Node: Install, Next: Invoke, Prev: Built-in, Up: Top
Installing BASH
***************
To install BASH you simply type `make'. The BASH `Makefile' tries
to dynamically figure out what kind of machine and operating system
you are using. It makes an educated guess based on the information
it finds.
During the `make' process, a message is displayed describing what
machine and operating system has been chosen for you. This
information is also saved in the file `.machine' so you can look at
it later.
Therefore, for most machines, simply follow this simple checklist
to install BASH:
1. Type `make'.
2. Wait for the compilation to finish.
3. Type `./bash' to see if the compile worked.
4. Type `make install DESTDIR=/usr/gnu/bin' (or wherever you
keep GNU binaries) to copy bash to your binaries directory.
* Menu:
* Problems:: What to do if BASH doesn't install quite so easily.
* Files:: Files used in the `make' process.
* Porting:: Porting BASH to a new machine.
* Bugs:: What to do if you Discover Bugs in BASH.
File: bash.info, Node: Problems, Next: Files, Prev: Install, Up: Install
What if it Doesn't Install so Easily?
=====================================
Sometimes BASH gets confused and will make the wrong assumptions
about your machine or operating system. If the displayed
information (also found in `.machine') is incorrect, you will have
to edit the file `machines.h' and provide the appropriate
information so that BASH can be installed correctly. The complete
instructions for doing this are located in the `machines.h' file.
However, if BASH says that your machine type is an
"UNKNOWN_MACHINE", or BASH thought it knew something about your
machine but was wrong, then reading the next few sections could be
of use to you (*note Files::., and *note Porting::., for more
information).
On the MIPSEB with the BSD universe, you must:
1) Place /bsd43/bin in your PATH before /bin
2) Use $(CC) -E instead of /lib/cpp to build cpp-Makefile.
File: bash.info, Node: Files, Next: Porting, Prev: Problems, Up: Install
Files Used in the `make' Process.
=================================
The following files are used during the installation of BASH, in
the `make' process:
`Makefile'
This is responsible for making the actual `Makefile' that is
used to create Bash. It runs the C preprocessor (usually
located in `/lib/cpp') on the file `cpp-Makefile', producing
the output file `bash-Makefile'.
`cpp-Makefile'
This is a file of C comments and text. It contains a
reasonable number of `ifdefs' which control what files get
compiled and which flags are passed to the various C files
comprising BASH. It includes a file called `machines.h',
`sysdefs.h', and `config.h'.
`machines.h'
This file contains the basic compilation parameters for all of
the machines to which BASH has been ported. This file
consists of a series of conditional blocks, one per machine
type.
These conditional blocks are depend upon the unique identifier
that `cpp' has predefined for this machine. In some cases,
additional information can be passed from `Makefile'. It is
possible to pass information such as whether or not a
particular file is available on this system, and so on.
`sysdefs.h'
This file is dynamically made at build time by running the shell
script `makeargs.sh'. If there appears to be something wrong in
this file, then edit the `makeargs.sh' script, and mail the
changes that you make to bash-maintainers@ai.mit.edu.
`bash-Makefile'
This is the output from the initial stage of `make'. It is a
stripped down version of `cpp-Makefile' which is tailor-made
for your machine and operating system. All subsequent `makes'
use this file.
File: bash.info, Node: Porting, Next: Bugs, Prev: Files, Up: Install
What if You Have to Port to a New Machine?
==========================================
Sometimes you may want to port BASH to a new, previously
unsupported machine. To do so you need to create a block in
`machines.h' which is conditional based on a unique identifier
present in your version of the C preprocessor.
If you don't know what that symbol is, you might try the following
simple test:
echo "main () { }" > foo.c
cc -v foo.c
You are looking for `-DMACHINE', where `MACHINE' is an identifier
for your machine. If you are very unlucky and your machine's C
preprocessor doesn't have a unique identifier, you will have to
define the identifier in Makefile manually.
Let's say you have a machine from Yoyodyne Industries, called the
YoYo. It runs a version of BSD, so it is reasonably compatible.
However, the `cpp' on this YoYo machine doesn't define any unique
identifiers. You should change the `Makefile' line for `CPPFLAGS'
to:
CPPFLAGS = -P -DYoYo
Then, in `machines.h', you copy the block for `UNKNOWN_MACHINE',
and change the conditional to;
#if defined (YoYo)
Inside of the YoYo block you define `M_MACHINE="YoYo"', and
`M_OS=BSD'. You also modify the existing defines to match your
machine's software.
If BASH still won't compile, perhaps because of missing code that
is required for your YoYo machine, you will have to write that code
and place it within a conditional block based on YoYo.
Most machines aren't that difficult; simply redefining a few of the
default values is sufficient. If you do run across a difficult
machine, please send all fixes and changes to
bash-maintainers@ai.mit.edu in the form of context diffs:
diff -c orig-machines.h machines.h >machines.diffs
Please include information about which version of the shell you have.
File: bash.info, Node: Bugs, Prev: Porting, Up: Install
Reporting Bugs
==============
If you find a bug in bash, you should report it. But first you
should make sure that it really is a bug and that it appears in the
latest version of BASH that is available.
Once you have ascertained that a bug really exists, you are welcome
to mail in a bug report. If you have a fix, please mail that too!
Suggestions and "philosophical" bug reports should be mailed to
bug-bash@ai.mit.edu. Genuine bug reports should be mailed to the
same place, or to bash-maintainers@ai.mit.edu.
*All* bug reports should include:
* The version number of BASH.
* The hardware and operating system used.
* The compiler used to compile BASH.
* A description of the bug's behavior.
* A short script or "recipe" which demonstrates the bug.
Without this information, it is generally not possible to
successfully debug BASH. Usually, without this information, the
bug won't manifest itself!
Discussion and questions about BASH in general (including questions
about this documentation) can be sent to bash-maintainers@ai.mit.edu.

View File

@@ -0,0 +1,98 @@
# Hey Emacs, this Makefile is in -*- text -*- mode!
#
# Makefile for Bash.
# If your cpp doesn't like -P, just get rid of it (the -P, not cpp).
# If you wish to use Gcc, then just type "make CC=gcc".
# If you wish to use GNU's Make, then change the MAKE define.
# If you don't like the destination, then change DESTDIR. (This only
# matters if you are typing `make install'.)
# The file that you most likely want to look at is cpp-Makefile.
#
# If you haven't read README, now might be a good time.
DESTDIR = /usr/gnu/bin
MAKE = make
RM = rm -f
SHELL = /bin/sh
GAWK = awk
# GAWK = gawk
CPPNAME = /lib/cpp
CPP = $(CPPNAME) `$(CPPMAGIC) $(GETCPPSYMS) $(CPPNAME)` -P
# CPP = $(CC) -E
CPP_MAKEFILE = cpp-Makefile
CPPFLAGS = $(SYSTEM) $(CPP_DEFINES)
CPP_ARGS = -DCPP_CC="$(CC)"
SUPPORTDIR = ./support/
MKSYSDEFS = $(SUPPORTDIR)mksysdefs
CPPMAGIC = $(SUPPORTDIR)cppmagic
CAT_S = $(SUPPORTDIR)cat-s
GETCPPSYMS = $(SUPPORTDIR)getcppsyms
GETCPPSYMS_SRC = $(SUPPORTDIR)getcppsyms.c
# Here is a command which compresses runs of multiple blank lines to a
# single blank line. "cat -s" works for BSD systems, but not for USG
# systems. You can use an awk script if you like. If you have too
# much trouble with this, just forget it. It is for making
# bash-Makefile pretty and readable; something that isn't strictly
# necessary.
# SQUASH_BLANKS = cat -s
#
SQUASH_BLANKS = $(GAWK) -f $(CAT_S)
all: .notified bash-Makefile
$(MAKE) $(MFLAGS) $(MAKEARGS) -f bash-Makefile
bash-Makefile: $(CPP_MAKEFILE) Makefile machines.h sysdefs.h config.h
@-if [ -f aix-Makefile ]; then \
echo "cp aix-Makefile tmp-Makefile.c"; \
cp aix-Makefile tmp-Makefile.c; else \
echo "cp $(CPP_MAKEFILE) tmp-Makefile.c"; \
cp $(CPP_MAKEFILE) tmp-Makefile.c; \
fi
$(RM) $(GETCPPSYMS)
$(CC) -o $(GETCPPSYMS) $(GETCPPSYMS_SRC)
@/bin/sh -c 'echo $(CPP) $(CPPFLAGS) $(CPP_ARGS) tmp-Makefile.c \| $(SQUASH_BLANKS) \> bash-Makefile'
@/bin/sh -c '$(CPP) $(CPPFLAGS) $(CPP_ARGS) tmp-Makefile.c | $(SQUASH_BLANKS) >bash-Makefile'
rm -f tmp-Makefile.c
sysdefs.h: $(MKSYSDEFS)
$(MKSYSDEFS)
# Subsequent lines contain targets that are correctly handled by an
# existing bash-Makefile.
install newversion mailable distribution architecture: bash-Makefile
$(MAKE) $(MFLAGS) $(MAKEARGS) -f bash-Makefile $@
bash.tar.Z tags documentation clone: bash-Makefile directory-frob
$(MAKE) $(MFLAGS) $(MAKEARGS) -f bash-Makefile $@
clean: bash-Makefile directory-frob
rm -f .notified
$(MAKE) $(MFLAGS) $(MAKEARGS) -f bash-Makefile $@
directory-frob:
.NOEXPORT:
.notified:
@echo ""
@echo " You are about to make this version of GNU Bash for"
@echo " this architecture for the first time. If you haven't"
@echo " yet read the README file, you may want to do so. If"
@echo " you wish to report a bug in Bash, or in the installation"
@echo " procedure, please mail it to bash-maintainers@ai.mit.edu,"
@echo " and include:"
@echo ""
@echo " * the version number of Bash,"
@echo " * the machine and OS that it is running on,"
@echo " * a description of the bug,"
@echo " * a recipe for recreating the bug reliably,"
@echo " * a fix for the bug if you have one!"
@echo ""
@touch .notified

41
bin/old/bash-1.11/README Normal file
View File

@@ -0,0 +1,41 @@
This README file is in -*- text -*- mode, because Emacs likes it that way.
This is GNU Bash, version 1.11. Bash is the GNU Project's Bourne
Again SHell, an interactive shell with Bourne shell syntax (/bin/sh);
but also with interactive command line editing, job control on
architectures that support it, Csh-like history features and brace
expansion, and a slew of other stuff. For more information on the
features of Bash that are new to this type of shell, see the file
`documentation/features.texi'. There is also a processed DVI file
there, as well as a large man page.
To compile it, try typing `make'.
You may want to read the file INSTALL in this directory for more
information, but I doubt it.
If you are a csh user and wish to convert your csh aliases to Bash
aliases, you may wish to use the script in examples/alias-conv.sh.
Bug reports for 1.11 should be sent to:
bash-maintainers@ai.mit.edu
The discussion list "bug-bash@ai.mit.edu" often contains information
about new ports of Bash, or discussions of new features or behaviour
changes that people would like. This mailing list is also available
as a news feed in gnu.bash.bug.
When you send a bug report to bash-maintainers@ai.mit.edu, please
include:
* the version number of Bash
* the machine and OS that it is running on (see .machine or .made)
* a description of the bug
* a recipe for recreating the bug reliably
* a fix for the bug if you have one!
While the maintainers of Bash do not promise to fix all bugs, we would
like this shell to be the best that we can make it.
Enjoy!

79
bin/old/bash-1.11/RELEASE Normal file
View File

@@ -0,0 +1,79 @@
This is a list of user-visible changes between bash version 1.11 and the
previous release, version 1.10, compiled by Chet Ramey.
The shell language
o If redirections fail for an empty command, the command returns failure
and changes $?. If command substitution took place while expanding the
redirections, the exit status of the command substitution becomes the
new value of $?. Previously, $? was unchanged by empty commands.
o `case' statement pattern lists now allow an optional leading left
parenthesis.
o The shell grammar was changed to allow redirections before a ( ... )
subshell command.
o Lengthy $PATH searches are now interruptible.
o A new variable, `command_oriented_history'. If set, the shell attempts
to store all lines of a multi-line command (e.g. a while loop or a
function definition) as a single history entry.
Shell builtins
o `unalias' now has a -a option, which removes all alias definitions, and
recognizes `--' as the end of options.
o If the shell is compiled with DISABLED_BUILTINS defined (look in
config.h), `builtin xxx' will find xxx even if `enable -n xxx' has
already been executed.
o The `fc' output when listing history lines was changed to match the
Posix.2a specification.
o `jobs' now has a -x option. `jobs -x command args' causes the shell to
replace all job control specifications (e.g. %%, %-) in `args' with the
appropriate process group identifier and execute `command' with the new
arguments.
o `jobs' recognizes `--' as the end of options.
o There is a new help topic that describes some of the shell variables
that bash uses.
o `set -b' is now equivalent to `set -o notify'.
o `shift' now allows the shift count to be 0, like most versions of sh.
o On machines that can set a process's maximum number of open files,
`ulimit -n newval' works as expected.
Readline
o Dynamic history completion. Bound to M-TAB in the emacs keymap. This
will search the history list for completion strings for a partial
command.
o On termios/termio machines, readline no longer unconditionally enables
8-bit input by disabling ISTRIP -- you have to run `stty -istrip' on
xterms to use the meta key. Readline will disable ISTRIP if the tty
driver indicates that the `character size' is 8 bits:
(tio.c_cflag & CSIZE) == CS8)
This was done to make readline usable on machines with hardwired 7-bit
terminals that put garbage in the eigth bit.
o An attempt at completion that expands to a single item will now cause
readline to simply insert that item into the buffer, even if the previous
command was another completion. In the last release, completion
immediately following completion caused readline to list the possible
completions.
o The `call-last-kbd-macro' function is now bindable.
o Readline binds tio.c_cc[VLNEXT] to rl_quoted_insert and tio.c_cc[VWERASE]
to rl_unix_word_rubout on Posix termios systems that support them.
o Readline now uses tio.c_cc[VEOF] as the EOF character on termios systems

431
bin/old/bash-1.11/alias.c Normal file
View File

@@ -0,0 +1,431 @@
/* alias.c -- Not a full alias, but just the kind that we use in the
shell. Csh style alias is somewhere else (`over there, in a box'). */
/* Copyright (C) 1987,1991 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 1, 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; see the file COPYING. If not, write to the Free
Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
#include <stdio.h>
#include "config.h"
#include "general.h"
#include "alias.h"
/* The number of slots to allocate when we need new slots. */
#define alias_list_grow_amount 50
/* Non-zero means expand all words on the line. Otherwise, expand
after first expansion if the expansion ends in a space. */
int alias_expand_all = 0;
/* The list of aliases that we have. */
ASSOC **aliases = (ASSOC **)NULL;
/* The number of slots in the above list. */
static int aliases_size = 0;
/* The number of aliases that are in existence. */
static int aliases_length = 0;
/* The last alias index found with find_alias (). */
static int last_alias_index = 0;
/* Scan the list of aliases looking for one with NAME. Return NULL
if the alias doesn't exist, else a pointer to the assoc. */
ASSOC *
find_alias (name)
char *name;
{
register int i;
for (i = 0; i < aliases_length; i++)
if (STREQ (name, aliases[i]->name))
return (aliases[last_alias_index = i]);
return ((ASSOC *)NULL);
}
/* Return the value of the alias for NAME, or NULL if there is none. */
char *
get_alias_value (name)
char *name;
{
ASSOC *alias = find_alias (name);
if (alias)
return (alias->value);
else
return ((char *)NULL);
}
/* Make a new alias from NAME and VALUE. If NAME can be found,
then replace its value. */
void
add_alias (name, value)
char *name, *value;
{
ASSOC *temp = find_alias (name);
if (temp)
{
free (temp->value);
temp->value = savestring (value);
}
else
{
temp = (ASSOC *)xmalloc (sizeof (ASSOC));
temp->name = savestring (name);
temp->value = savestring (value);
if ((aliases_length + 1) >= aliases_size)
{
aliases =
(ASSOC **)xrealloc (aliases,
(aliases_size += alias_list_grow_amount)
* sizeof (ASSOC *));
}
aliases[aliases_length++] = temp;
aliases[aliases_length] = (ASSOC *)NULL;
}
}
/* Remove the alias with name NAME from the alias list. Returns
the index of the removed alias, or -1 if the alias didn't exist. */
int
remove_alias (name)
char *name;
{
register int i;
if (!find_alias (name))
return (-1);
i = last_alias_index;
free (aliases[i]->name);
free (aliases[i]->value);
free (aliases[i]);
for (; i < aliases_length; i++)
aliases[i] = aliases[i + 1];
aliases_length--;
aliases[aliases_length] = (ASSOC *)NULL;
return (last_alias_index);
}
/* Delete all aliases. */
delete_all_aliases ()
{
register int i;
for (i = 0; i < aliases_length; i++)
{
free (aliases[i]->name);
free (aliases[i]->value);
free (aliases[i]);
aliases[i] = (ASSOC *)NULL;
}
aliases_length = 0;
}
/* Return non-zero if CHARACTER is a member of the class of characters
that are self-delimiting in the shell (this really means that these
characters delimit tokens). */
#define self_delimiting(character) (member ((character), " \t\n\r;|&()"))
/* Return non-zero if CHARACTER is a member of the class of characters
that delimit commands in the shell. */
#define command_separator(character) (member ((character), "\r\n;|&("))
/* If this is 1, we are checking the next token read for alias expansion
because it is the first word in a command. */
static int command_word;
/* This is for skipping quoted strings in alias expansions. */
#define quote_char(c) (((c) == '\'') || ((c) == '"'))
/* Consume a quoted string from STRING, starting at string[START] (so
string[START] is the opening quote character), and return the index
of the closing quote character matching the opening quote character.
This handles single matching pairs of unquoted quotes; it could afford
to be a little smarter... This skips words between balanced pairs of
quotes, words where the first character is quoted with a `\', and other
backslash-escaped characters. */
static int
skipquotes (string, start)
char *string;
int start;
{
register int i;
int delimiter = string[start];
/* i starts at START + 1 because string[START] is the opening quote
character. */
for (i = start + 1 ; string[i] ; i++)
{
if (string[i] == '\\')
{
i++; /* skip backslash-quoted quote characters, too */
continue;
}
if (string[i] == delimiter)
return i;
}
return (i);
}
/* Skip the white space and any quoted characters in STRING, starting at
START. Return the new index into STRING, after zero or more characters
have been skipped. */
static int
skipws (string, start)
char *string;
int start;
{
register int i = 0;
int pass_next, backslash_quoted_word, peekc;
/* skip quoted strings, in ' or ", and words in which a character is quoted
with a `\'. */
backslash_quoted_word = pass_next = 0;
/* Skip leading whitespace (or separator characters), and quoted words.
But save it in the output. */
for (i = start; string[i]; i++)
{
if (pass_next)
{
pass_next = 0;
continue;
}
if (whitespace (string[i]))
{
backslash_quoted_word = 0; /* we are no longer in a backslash-quoted word */
continue;
}
if (string[i] == '\\')
{
peekc = string[i+1];
if (isletter (peekc))
backslash_quoted_word++; /* this is a backslash-quoted word */
else
pass_next++;
continue;
}
/* This only handles single pairs of non-escaped quotes. This
overloads backslash_quoted_word to also mean that a word like
""f is being scanned, so that the quotes will inhibit any expansion
of the word. */
if (quote_char(string[i]))
{
i = skipquotes (string, i);
/* This could be a line that contains a single quote character,
in which case skipquotes () terminates with string[i] == '\0'
(the end of the string). Check for that here. */
if (string[i] == '\0')
break;
peekc = string[i + 1];
if (isletter (peekc))
backslash_quoted_word++;
continue;
}
/* If we're in the middle of some kind of quoted word, let it
pass through. */
if (backslash_quoted_word)
continue;
/* If this character is a shell command separator, then set a hint for
alias_expand that the next token is the first word in a command. */
if (command_separator (string[i]))
{
command_word++;
continue;
}
break;
}
return (i);
}
/* Characters that may appear in a token. Basically, anything except white
space and a token separator. */
#define token_char(c) (!((whitespace (string[i]) || self_delimiting (string[i]))))
/* Read from START in STRING until the next separator character, and return
the index of that separator. Skip backslash-quoted characters. Call
skipquotes () for quoted strings in the middle or at the end of tokens,
so all characters show up (e.g. foo'' and foo""bar) */
static int
rd_token (string, start)
char *string;
int start;
{
register int i;
/* From here to next separator character is a token. */
for (i = start; string[i] && token_char (string[i]); i++)
{
if (string[i] == '\\')
{
i++; /* skip backslash-escaped character */
continue;
}
/* If this character is a quote character, we want to call skipquotes
to get the whole quoted portion as part of this word. That word
will not generally match an alias, even if te unquoted word would
have. The presence of the quotes in the token serves then to
inhibit expansion. */
if (quote_char (string[i]))
{
i = skipquotes (string, i);
/* Now string[i] is the matching quote character, and the
quoted portion of the token has been scanned. */
continue;
}
}
return (i);
}
/* Return a new line, with any aliases substituted. */
char *
alias_expand (string)
char *string;
{
int line_len = 1 + strlen (string);
char *line = (char *)xmalloc (line_len);
register int i, j, start;
char *token = (char *)alloca (line_len);
int tl, real_start, expand_next, expand_this_token;
ASSOC *alias;
line[0] = i = 0;
expand_next = 0;
command_word = 1; /* initialized to expand the first word on the line */
/* Each time through the loop we find the next word in line. If it
has an alias, substitute
the alias value. If the value ends in ` ', then try again
with the next word. Else, if there is no value, or if
the value does not end in space, we are done. */
for (;;)
{
token[0] = 0;
start = i;
/* Skip white space and quoted characters */
i = skipws (string, start);
if (start == i && string[i] == '\0')
return (line);
/* copy the just-skipped characters into the output string,
expanding it if there is not enough room. */
j = strlen (line);
tl = i - start; /* number of characters just skipped */
if (1 + j + tl >= line_len)
line = (char *)xrealloc (line, line_len += (50 + tl));
strncpy (line + j, string + start, tl);
line[j + tl] = '\0';
real_start = i;
command_word = command_word || (command_separator (string[i]));
expand_this_token = (command_word || expand_next);
expand_next = 0;
/* Read the next token, and copy it into TOKEN. */
start = i;
i = rd_token (string, start);
tl = i - start; /* token length */
/* If tl == 0, but we're not at the end of the string, then we have a
single-character token, probably a delimiter */
if (tl == 0 && string[i] != '\0')
{
tl = 1;
i++; /* move past it */
}
strncpy (token, string + start, tl);
token [tl] = '\0';
/* If there is a backslash-escaped character quoted in TOKEN,
then we don't do alias expansion. This should check for all
other quoting characters, too. */
if (index(token,'\\'))
expand_this_token = 0;
/* If we should be expanding here, if we are expanding all words, or if
we are in a location in the string where an expansion is supposed to
take place, see if this word has a substitution. If it does, then do
the expansion. Note that we defer the alias value lookup until we
are sure we are expanding this token. */
if ((token[0]) &&
(expand_this_token || alias_expand_all) &&
(alias = find_alias (token)))
{
char *v = alias->value;
int l = strlen (v);
/* +3 because we possibly add one more character below. */
if ((l + 3) > line_len - strlen (line))
line = (char *)xrealloc (line, line_len += (50 + l));
strcat (line, v);
if ((expand_this_token && l && whitespace (v[l - 1])) || alias_expand_all)
expand_next = 1;
}
else
{
int ll = strlen (line);
int tl = i - real_start; /* tl == strlen(token) */
if (ll + tl + 2 > line_len)
line = (char *)xrealloc (line, line_len += 50 + ll + tl);
strncpy (line + ll, string + real_start, tl);
line[ll + tl] = '\0';
}
command_word = 0;
}
}
char *
alias_expand_word (s)
char *s;
{
ASSOC *r = find_alias (s);
if (r)
return (savestring (r->value));
else
return ((char *)NULL);
}

64
bin/old/bash-1.11/alias.h Normal file
View File

@@ -0,0 +1,64 @@
/* alias.h -- structure definitions. */
/* Copyright (C) 1987,1991 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 1, 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; see the file COPYING. If not, write to the Free
Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
#if !defined (_ALIAS_)
#define _ALIAS_
extern char *xmalloc (), *malloc ();
#ifndef whitespace
#define whitespace(c) (((c) == ' ') || ((c) == '\t'))
#endif
#ifndef savestring
#define savestring(x) (char *)strcpy (xmalloc (1 + strlen (x)), (x))
#endif
typedef struct {
char *name;
char *value;
} ASSOC;
#ifndef NULL
#define NULL 0x0
#endif
/* The list of known aliases. */
extern ASSOC **aliases;
/* Scan the list of aliases looking for one with NAME. Return NULL
if the alias doesn't exist, else a pointer to the assoc. */
extern ASSOC *find_alias ();
/* Return the value of the alias for NAME, or NULL if there is none. */
extern char *get_alias_value ();
/* Make a new alias from NAME and VALUE. If NAME can be found,
then replace its value. */
extern void add_alias ();
/* Remove the alias with name NAME from the alias list. Returns
the index of the removed alias, or -1 if the alias didn't exist. */
extern int remove_alias ();
/* Return a new line, with any aliases substituted. */
extern char *alias_substitute ();
#endif /* _ALIAS_ */

1369
bin/old/bash-1.11/bashline.c Normal file

File diff suppressed because it is too large Load Diff

350
bin/old/bash-1.11/braces.c Normal file
View File

@@ -0,0 +1,350 @@
/* braces.c -- code for doing word expansion in curly braces. */
/* Copyright (C) 1987,1991 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 1, 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; see the file COPYING. If not, write to the Free
Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
/* Stuff in curly braces gets expanded after variable and command
substitution, but before filename globbing.
(Actually, this should be true for the sake of efficiency, but it
isn't because of quoting hacks. Once I rebuild quoting it will be
true. */
#if defined (SHELL)
#include "shell.h"
#endif /* SHELL */
#include "general.h"
#define brace_whitespace(c) (!(c) || (c) == ' ' || (c) == '\t' || (c) == '\n')
#if !defined (NULL)
#define NULL (char *)0x0
#endif /* NULL */
/* Basic idea:
Segregate the text into 3 sections: preamble (stuff before an open brace),
postamble (stuff after the matching close brace) and amble (stuff after
preamble, and before postamble). Expand amble, and then tack on the
expansions to preamble. Expand postamble, and tack on the expansions to
the result so far.
*/
/* The character which is used to separate arguments. */
int brace_arg_separator = ',';
static int brace_gobbler ();
static char **expand_amble (), **array_concat (), **copy_array ();
/* Return an array of strings; the brace expansion of TEXT. */
char **
brace_expand (text)
char *text;
{
register int start;
char *preamble, *postamble, *amble;
char **tack, **result;
int i, c;
/* Find the text of the preamble. */
i = 0;
c = brace_gobbler (text, &i, '{');
preamble = (char *)xmalloc (i + 1);
strncpy (preamble, text, i);
preamble[i] = '\0';
result = (char **)xmalloc (2 * sizeof (char *));
result[0] = preamble;
result[1] = (char *)NULL;
/* Special case. If we never found an exciting character, then
the preamble is all of the text, so just return that. */
if (c != '{')
return (result);
/* Find the amble. This is the stuff inside this set of braces. */
start = ++i;
c = brace_gobbler (text, &i, '}');
/* What if there isn't a matching close brace? */
if (!c)
{
#if defined (SHELL)
register int j;
/* Well, if we found BRACE_ARG_SEPARATOR between START and I,
then this should be an error. Otherwise, it isn't. */
for (j = start; j < i; j++)
if (text[j] == brace_arg_separator)
{
free_array (result);
report_error ("Missing `}'");
throw_to_top_level ();
}
#endif
free (preamble); /* Same as result[0]; see initialization. */
result[0] = savestring (text);
return (result);
}
amble = (char *)xmalloc (1 + (i - start));
strncpy (amble, &text[start], (i - start));
amble[i - start] = '\0';
#if defined (SHELL)
/* If the amble does not contain BRACE_ARG_SEPARATOR, then just return
without doing any expansion. */
if (index (amble, brace_arg_separator) == NULL)
{
free (amble);
free (preamble);
result[0] = savestring (text);
return (result);
}
#endif /* SHELL */
postamble = &text[i + 1];
tack = expand_amble (amble);
result = array_concat (result, tack);
free (amble);
free_array (tack);
tack = brace_expand (postamble);
result = array_concat (result, tack);
free_array (tack);
return (result);
}
/* Expand the text found inside of braces. We simply try to split the
text at BRACE_ARG_SEPARATORs into separate strings. We then brace
expand each slot which needs it, until there are no more slots which
need it. */
static char **
expand_amble (text)
char *text;
{
char **result, **partial;
char *tem;
int start, i, c;
result = (char **)NULL;
for (start = 0, i = 0, c = 1; c; start = ++i)
{
c = brace_gobbler (text, &i, brace_arg_separator);
tem = (char *)xmalloc (1 + (i - start));
strncpy (tem, &text[start], (i - start));
tem[i- start] = '\0';
partial = brace_expand (tem);
if (!result)
result = partial;
else
{
register int lr = array_len (result);
register int lp = array_len (partial);
register int j;
result = (char **)xrealloc (result, (1 + lp + lr) * sizeof (char *));
for (j = 0; j < lp; j++)
result[lr + j] = partial[j];
result[lr + j] = (char *)NULL;
free (partial);
}
free (tem);
}
return (result);
}
/* Start at INDEX, and skip characters in TEXT. Set INDEX to the
index of the character matching SATISFY. This understands about
quoting. Return the character that caused us to stop searching;
this is either the same as SATISFY, or 0. */
static int
brace_gobbler (text, index, satisfy)
char *text;
int *index;
int satisfy;
{
register int i, c, quoted, level;
level = quoted = 0;
for (i = *index; c = text[i]; i++)
{
if (quoted)
{
if ((quoted == '\\') || (c == quoted))
quoted = 0;
continue;
}
if (c == '"' || c == '\'' || c == '\\')
{
quoted = c;
continue;
}
if (c == satisfy && !level && !quoted)
{
/* We ignore an open brace surrounded by whitespace, and also
an open brace followed immediately by a close brace, that
was preceded with whitespace. */
if (c == '{' &&
((!i || brace_whitespace (text[i - 1])) &&
(brace_whitespace (text[i + 1]) || text[i + 1] == '}')))
continue;
#ifdef SHELL
/* If this is being compiled as part of bash, ignore the `{'
in a `${}' construct */
if ((c != '{') || !i || (text[i - 1] != '$'))
#endif
break;
}
if (c == '{')
level++;
else if (c == '}' && level)
level--;
}
*index = i;
return (c);
}
/* Return a new array of strings which is the result of appending each
string in ARR2 to each string in ARR1. The resultant array is
len (arr1) * len (arr2) long. For convenience, ARR1 (and its contents)
are free ()'ed. ARR1 can be NULL, in that case, a new version of ARR2
is returned. */
static char **
array_concat (arr1, arr2)
char **arr1, **arr2;
{
register int i, j, len, len1, len2;
register char **result;
if (!arr1)
return (copy_array (arr2));
if (!arr2)
return (arr1);
len1 = array_len (arr1);
len2 = array_len (arr2);
result = (char **)xmalloc ((1 + (len1 * len2)) * sizeof (char *));
len = 0;
for (i = 0; i < len1; i++)
{
int strlen_1 = strlen (arr1[i]);
for (j = 0; j < len2; j++)
{
result[len] =
(char *)xmalloc (1 + strlen_1 + strlen (arr2[j]));
strcpy (result[len], arr1[i]);
strcpy (result[len] + strlen_1, arr2[j]);
len++;
}
free (arr1[i]);
}
free (arr1);
result[len] = (char *)NULL;
return (result);
}
static char **
copy_array (array)
char **array;
{
register int i;
char **new;
if (!array)
return (array);
new = (char **)xmalloc ((1 + array_len (array)) * sizeof (char *));
for (i = 0; array[i]; i++)
new[i] = savestring (array[i]);
new[i] = (char *)NULL;
return (new);
}
#if defined (TEST)
#include <stdio.h>
fatal_error (format, arg1, arg2)
char *format, *arg1, *arg2;
{
report_error (format, arg1, arg2);
exit (1);
}
report_error (format, arg1, arg2)
char *format, *arg1, *arg2;
{
fprintf (stderr, format, arg1, arg2);
fprintf (stderr, "\n");
}
main ()
{
char example[256];
for (;;)
{
char **result;
int i;
fprintf (stderr, "brace_expand> ");
if ((!fgets (example, 256, stdin)) ||
(strncmp (example, "quit", 4) == 0))
break;
if (strlen (example))
example[strlen (example) - 1] = '\0';
result = brace_expand (example);
for (i = 0; result[i]; i++)
printf ("%s\n", result[i]);
free_array (result);
}
}
/*
* Local variables:
* compile-command: "gcc -g -Bstatic -DTEST -o brace_expand braces.c general.o"
* end:
*/
#endif /* TEST */

View File

@@ -0,0 +1,41 @@
/* builtins.h -- What a builtin looks like, and where to find them. */
/* Copyright (C) 1987,1991 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 1, 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; see the file COPYING. If not, write to the Free
Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
#include "config.h"
#include "general.h"
#if defined (ALIAS)
#include "alias.h"
#endif
/* The thing that we build the array of builtins out of. */
struct builtin {
char *name;
Function *function;
int enabled;
char **long_doc; /* NULL terminated array of strings. */
char *short_doc;
};
/* Found in builtins.c, created by builtins/mkbuiltins. */
extern struct builtin shell_builtins[];
extern int num_shell_builtins;

View File

View File

@@ -0,0 +1,82 @@
# This Makefile for building libbuiltins.a is in -*- text -*- for Emacs.
#
MKBUILTINS = mkbuiltins
RANLIB = /usr/bin/ranlib
CFLAGS = -g -I.. -I.
SHELL = /bin/sh
CC = cc
AR = ar
RM = rm -f
CP = cp
.SUFFIXES:
.SUFFIXES: .def .c .o
# How to make a .o file from a .def file.
.def.o:
$(RM) $@
./$(MKBUILTINS) $(DIRECTDEFINE) $*.def
$(CC) -c $(CFLAGS) $(CPPFLAGS) $*.c
$(RM) $*.c
# How to make a .c file from a .def file.
.def.c:
$(RM) $@
./$(MKBUILTINS) $(DIRECTDEFINE) $*.def
# Here is a rule for making .o files from .c files that does not
# force the type of the machine (like -M_MACHINE) into the flags.
.c.o:
$(RM) $@
$(CC) -c $(CFLAGS) $(CPPFLAGS) $*.c
DEFS = alias.def bind.def break.def builtin.def cd.def colon.def \
command.def declare.def echo.def enable.def eval.def \
exec.def exit.def fc.def fg_bg.def hash.def help.def history.def \
jobs.def kill.def let.def read.def return.def set.def setattr.def \
shift.def source.def suspend.def test.def times.def trap.def \
type.def ulimit.def umask.def wait.def getopts.def reserved.def
STATIC_SOURCE = common.c getopt.c getopt.h
OFILES = alias.o bind.o break.o builtin.o cd.o colon.o command.o \
common.o declare.o echo.o enable.o eval.o exec.o exit.o \
fc.o fg_bg.o hash.o help.o history.o jobs.o kill.o \
let.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 getopt.o builtins.o
THINGS_TO_TAR = $(DEFS) $(STATIC_SOURCE) Makefile ChangeLog
CREATED_FILES = builtext.h builtins.c psize.aux pipesize.h
all: $(MKBUILTINS) libbuiltins.a
libbuiltins.a: $(MKBUILTINS) $(OFILES)
$(RM) $@
$(AR) clq $@ $(OFILES)
-if [ -f "$(RANLIB)" ]; then $(RANLIB) $@; fi
builtext.h builtins.c: $(MKBUILTINS) $(DEFS)
$(RM) builtext.h builtins.c
./$(MKBUILTINS) -externfile builtext.h -structfile builtins.c \
-noproduction $(DEFS)
mkbuiltins: mkbuiltins.c
$(CC) $(CFLAGS) -o $(MKBUILTINS) mkbuiltins.c
ulimit.o: ulimit.def pipesize.h
pipesize.h: psize.aux
$(SHELL) ./psize.sh > pipesize.h
psize.aux: psize.c
$(CC) $(CFLAGS) -o $@ psize.c
documentation: builtins.texi
builtins.texi: $(MKBUILTINS)
./$(MKBUILTINS) -documentonly $(DEFS)
clean:
$(RM) $(OFILES) $(CREATED_FILES) $(MKBUILTINS) libbuiltins.a

View File

@@ -0,0 +1,189 @@
This file is alias.def, from which is created alias.c
It implements the builtins "alias" and "unalias" in Bash.
Copyright (C) 1987, 1989, 1991 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 1, 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; see the file COPYING. If not, write to the Free Software
Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
$BUILTIN alias
$FUNCTION alias_builtin
$DEPENDS_ON ALIAS
$PRODUCES alias.c
$SHORT_DOC alias [ name[=value] ... ]
`alias' with no arguments prints the list of aliases in the form
NAME=VALUE on standard output. An alias is defined for each NAME
whose VALUE is given. A trailing space in VALUE causes the next
word to be checked for alias substitution. Alias returns true
unless a NAME is given for which no alias has been defined.
$END
#include <stdio.h>
#include "../shell.h"
#include "../alias.h"
extern int interactive;
static void print_alias ();
/* Hack the alias command in a Korn shell way. */
alias_builtin (list)
WORD_LIST *list;
{
int any_failed = 0;
if (!list)
{
register int i;
if (!aliases)
return (EXECUTION_FAILURE);
for (i = 0; aliases[i]; i++)
print_alias (aliases[i]);
}
else
{
while (list)
{
register char *value, *name = list->word->word;
register int offset;
for (offset = 0; name[offset] && name[offset] != '='; offset++);
if (offset && name[offset] == '=')
{
name[offset] = '\0';
value = name + offset + 1;
add_alias (name, value);
}
else
{
ASSOC *t = find_alias (name);
if (t)
print_alias (t);
else
{
if (interactive)
builtin_error ("`%s' not found", name);
any_failed++;
}
}
list = list->next;
}
}
if (any_failed)
return (EXECUTION_FAILURE);
else
return (EXECUTION_SUCCESS);
}
$BUILTIN unalias
$FUNCTION unalias_builtin
$DEPENDS_ON ALIAS
$SHORT_DOC unalias [-a] [name ...]
Remove NAMEs from the list of defined aliases. If the -a option is given,
then remove all alias definitions.
$END
/* Remove aliases named in LIST from the aliases database. */
unalias_builtin (list)
register WORD_LIST *list;
{
register ASSOC *alias;
int any_failed = 0;
while (list && *list->word->word == '-')
{
register char *word = list->word->word;
if (strcmp (word, "-a") == 0)
{
delete_all_aliases ();
list = list->next;
}
else if (strcmp (word, "--") == 0)
{
list = list->next;
break;
}
else
{
bad_option (word);
return (EXECUTION_FAILURE);
}
}
while (list)
{
alias = find_alias (list->word->word);
if (alias)
remove_alias (alias->name);
else
{
if (interactive)
builtin_error ("`%s' not an alias", list->word->word);
any_failed++;
}
list = list->next;
}
if (any_failed)
return (EXECUTION_FAILURE);
else
return (EXECUTION_SUCCESS);
}
/* Return a new string which is the quoted version of STRING. */
static char *
single_quote (string)
char *string;
{
register int i, j, c;
char *result;
result = (char *)xmalloc (3 + (2 * strlen (string)));
result[0] = '\'';
for (i = 0, j = 1; string && (c = string[i]); i++)
{
result[j++] = c;
if (c == '\'')
result[j++] = '\'';
}
result[j++] = '\'';
result[j] = '\0';
return (result);
}
/* Output ALIAS in such a way as to allow it to be read back in. */
static void
print_alias (alias)
ASSOC *alias;
{
char *value = single_quote (alias->value);
printf ("alias %s=%s\n", alias->name, value);
free (value);
fflush (stdout);
}

View File

@@ -0,0 +1,178 @@
This file is bind.def, from which is created bind.c.
It implements the builtin "bind" in Bash.
Copyright (C) 1987, 1989, 1991 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 1, 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; see the file COPYING. If not, write to the Free Software
Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
$PRODUCES bind.c
$BUILTIN bind
$DEPENDS_ON READLINE
$FUNCTION bind_builtin
$SHORT_DOC bind [-lvd] [-f filename] [-q name] [keyseq:readline-function]
Bind a key sequence to a Readline function, or to a macro. The
syntax is equivalent to that found in ~/.inputrc, but must be
passed as a single argument: bind '"\C-x\C-r": re-read-init-file'.
Arguments we accept:
-l List names of functions.
-v List function names and bindings.
-d Dump functions and bindings such that they
can be read back in.
-f filename Read key bindings from FILENAME.
-q function-name Query about which keys invoke the named function.
$END
#include <stdio.h>
#include "../shell.h"
#include <readline/readline.h>
#include <readline/history.h>
int
bind_builtin (list)
WORD_LIST *list;
{
extern int bash_readline_initialized;
int processing_args = 1;
int return_code = EXECUTION_SUCCESS;
begin_unwind_frame ("bind");
unwind_protect_pointer (rl_outstream);
rl_outstream = stdout;
if (!bash_readline_initialized)
initialize_readline ();
while (processing_args && list && list->word->word[0] == '-')
{
register int i;
extern void rl_function_dumper ();
char *word = list->word->word;
list = list->next;
for (i = 1; word[i]; i++)
{
switch (word[i])
{
case 'l':
rl_list_funmap_names (0);
break;
case 'v':
rl_function_dumper (0);
break;
case 'd':
rl_function_dumper (1);
break;
case 'f':
if (!list)
{
builtin_error ("-f requires a file name");
goto error_exit;
}
else
{
extern int errno;
char *initfile;
initfile = list->word->word;
if (rl_read_init_file (initfile) != 0)
{
builtin_error ("Cannot read %s: %s",
initfile, strerror (errno));
goto error_exit;
}
else
list = list->next;
}
break;
case 'q':
if (!list)
{
builtin_error ("-q requires the name of a function");
goto error_exit;
}
else while (list)
{
extern Function *rl_named_function ();
extern char **rl_invoking_keyseqs ();
Function *function;
char *name, **keyseqs;
name = list->word->word;
list = list->next;
function = rl_named_function (name);
if (!function)
{
builtin_error ("Unknown function name `%s'", name);
goto error_exit;
}
keyseqs = rl_invoking_keyseqs (function);
if (!keyseqs)
{
printf ("%s is not bound to any keys.\n", name);
}
else
{
register int j;
printf ("%s can be invoked via ", name);
for (j = 0; j < 5 && keyseqs[j]; j++)
printf ("\"%s\"%s", keyseqs[j],
keyseqs[j + 1] ? ", " : ".\n");
if (keyseqs[j])
printf ("...\n");
free_array (keyseqs);
}
}
break;
case '-':
processing_args = 0;
break;
default:
builtin_error ("Bad argument %c", word[i]);
error_exit:
return_code = EXECUTION_FAILURE;
goto bind_exit;
}
}
}
while (list)
{
rl_parse_and_bind (list->word->word);
list = list->next;
}
bind_exit:
run_unwind_frame ("bind");
return (return_code);
}

View File

@@ -0,0 +1,109 @@
This file is break.def, from which is created break.c.
It implements the builtins "break" and "continue" in Bash.
Copyright (C) 1987, 1989, 1991 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 1, 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; see the file COPYING. If not, write to the Free Software
Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
$PRODUCES break.c
$BUILTIN break
$FUNCTION break_builtin
$SHORT_DOC break [n]
Exit from within a FOR, WHILE or UNTIL loop. If N is specified,
break N levels.
$END
#include "../shell.h"
static int check_loop_level ();
/* The depth of while's and until's. */
int loop_level = 0;
/* Non-zero when a "break" instruction is encountered. */
int breaking = 0;
/* Non-zero when we have encountered a continue instruction. */
int continuing = 0;
/* Set up to break x levels, where x defaults to 1, but can be specified
as the first argument. */
break_builtin (list)
WORD_LIST *list;
{
int newbreak;
if (!check_loop_level ())
return (EXECUTION_FAILURE);
newbreak = get_numeric_arg (list);
if (newbreak <= 0)
return (EXECUTION_FAILURE);
if (newbreak > loop_level)
newbreak = loop_level;
breaking = newbreak;
return (EXECUTION_SUCCESS);
}
$BUILTIN continue
$FUNCTION continue_builtin
$SHORT_DOC continue [n]
Resume the next iteration of the enclosing FOR, WHILE or UNTIL loop.
If N is specified, resume at the N-th enclosing loop.
$END
/* Set up to continue x levels, where x defaults to 1, but can be specified
as the first argument. */
continue_builtin (list)
WORD_LIST *list;
{
int newcont;
if (!check_loop_level ())
return (EXECUTION_FAILURE);
newcont = get_numeric_arg (list);
if (newcont <= 0)
return (EXECUTION_FAILURE);
if (newcont > loop_level)
newcont = loop_level;
continuing = newcont;
return (EXECUTION_SUCCESS);
}
/* Return non-zero if a break or continue command would be okay.
Print an error message if break or continue is meaningless here. */
static int
check_loop_level ()
{
extern char *this_command_name;
#if defined (BREAK_COMPLAINS)
if (!loop_level)
builtin_error ("Only meaningful in a `for', `while', or `until' loop");
#endif /* BREAK_COMPLAINS */
return (loop_level);
}

View File

@@ -0,0 +1,66 @@
This file is builtin.def, from which is created builtin.c.
It implements the builtin "builtin" in Bash.
Copyright (C) 1987, 1989, 1991 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 1, 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; see the file COPYING. If not, write to the Free Software
Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
$PRODUCES builtin.c
$BUILTIN builtin
$FUNCTION builtin_builtin
$SHORT_DOC builtin [shell-builtin [arg ...]]
Run a shell builtin. This is useful when you wish to rename a
shell builtin to be a function, but need the functionality of the
builtin within the function itself.
$END
#include "../shell.h"
extern char *this_command_name;
/* Run the command mentioned in list directly, without going through the
normal alias/function/builtin/filename lookup process. */
builtin_builtin (list)
WORD_LIST *list;
{
extern Function *find_shell_builtin (), *builtin_address ();
Function *function;
register char *command;
if (!list)
return (EXECUTION_SUCCESS);
command = (list->word->word);
#if defined (DISABLED_BUILTINS)
function = builtin_address (command);
#else /* !DISABLED_BUILTINS */
function = find_shell_builtin (command);
#endif /* !DISABLED_BUILTINS */
if (!function)
{
builtin_error ("%s: Not a shell builtin!", command);
return (EXECUTION_FAILURE);
}
else
{
this_command_name = command;
list = list->next;
return ((*function) (list));
}
}

View File

@@ -0,0 +1,588 @@
This file is cd.def, from which is created cd.c. It implements the
builtins "cd", "pwd", "pushd", "popd", and "dirs" in Bash.
Copyright (C) 1987, 1989, 1991 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 1, 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; see the file COPYING. If not, write to the Free Software
Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
$PRODUCES cd.c
#include <stdio.h>
#include <sys/param.h>
#include "../shell.h"
#include "../maxpath.h"
static int change_to_directory (), cd_to_string ();
/* Keeps track of the current working directory. */
extern char *the_current_working_directory;
/* By default, follow the symbolic links as if they were real directories
while hacking the `cd' command. This means that `cd ..' moves up in
the string of symbolic links that make up the current directory, instead
of the absolute directory. The shell variable `nolinks' controls this
flag. */
int follow_symbolic_links = 1;
$BUILTIN cd
$FUNCTION cd_builtin
$SHORT_DOC cd [dir]
Change the current directory to DIR. The variable $HOME is the
default DIR. The variable $CDPATH defines the search path for
the directory containing DIR. Alternative directory names are
separated by a colon (:). A null directory name is the same as
the current directory, i.e. `.'. If DIR begins with a slash (/),
then $CDPATH is not used. If the directory is not found, and the
shell variable `cdable_vars' exists, then try the word as a variable
name. If that variable has a value, then cd to the value of that
variable.
$END
int
cd_builtin (list)
WORD_LIST *list;
{
char *dirname;
{
extern int restricted;
if (restricted)
{
builtin_error ("Privileged command");
return (EXECUTION_FAILURE);
}
}
if (list)
{
char *extract_colon_unit ();
char *path_string = get_string_value ("CDPATH");
char *path;
int index = 0;
dirname = list->word->word;
if (path_string && !absolute_pathname (dirname))
{
while ((path = extract_colon_unit (path_string, &index)))
{
char *dir;
if (*path && (*path == '~'))
{
char *tilde_expand (), *te_string = tilde_expand (path);
free (path);
path = te_string;
}
if (!*path)
{
free (path);
path = savestring ("."); /* by definition. */
}
dir = (char *)alloca (2 + strlen (dirname) + strlen (path));
if (!dir)
fatal_error ("Out of memory");
strcpy (dir, path);
if (path[strlen (path) - 1] != '/')
strcat (dir, "/");
strcat (dir, dirname);
free (path);
if (change_to_directory (dir))
{
if (strncmp (dir, "./", 2) != 0)
printf ("%s\n", dir);
dirname = dir;
goto bind_and_exit;
}
}
}
if (!change_to_directory (dirname))
{
/* Maybe this is `cd -', equivalent to `cd $OLDPWD' */
if (dirname[0] == '-' && dirname[1] == '\0')
{
char *t = get_string_value ("OLDPWD");
if (t && change_to_directory (t))
goto bind_and_exit;
}
/* If the user requests it, then perhaps this is the name of
a shell variable, whose value contains the directory to
change to. If that is the case, then change to that
directory. */
if (find_variable ("cdable_vars"))
{
char *t = get_string_value (dirname);
if (t && change_to_directory (t))
{
printf ("%s\n", t);
goto bind_and_exit;
}
}
file_error (dirname);
return (EXECUTION_FAILURE);
}
goto bind_and_exit;
}
else
{
dirname = get_string_value ("HOME");
if (!dirname)
return (EXECUTION_FAILURE);
if (!change_to_directory (dirname))
{
file_error (dirname);
return (EXECUTION_FAILURE);
}
bind_and_exit:
{
char *get_working_directory (), *get_string_value ();
char *directory = get_working_directory ("cd");
bind_variable ("OLDPWD", get_string_value ("PWD"));
bind_variable ("PWD", directory);
if (directory)
free (directory);
}
return (EXECUTION_SUCCESS);
}
}
$BUILTIN pwd
$FUNCTION pwd_builtin
$SHORT_DOC pwd
Print the current working directory.
$END
/* Non-zero means that pwd always give verbatim directory, regardless of
symbolic link following. */
static int verbatim_pwd = 1;
/* Print the name of the current working directory. */
pwd_builtin (list)
WORD_LIST *list;
{
char *get_working_directory (), *getwd (), *directory;
no_args (list);
if (verbatim_pwd)
{
char *buffer = (char *)xmalloc (MAXPATHLEN);
directory = getwd (buffer);
if (!directory)
{
builtin_error ("%s", buffer);
free (buffer);
}
}
else
{
directory = get_working_directory ("pwd");
}
if (directory)
{
printf ("%s\n", directory);
fflush (stdout);
free (directory);
return (EXECUTION_SUCCESS);
}
else
return (EXECUTION_FAILURE);
}
$BUILTIN pushd
$FUNCTION pushd_builtin
$DEPENDS_ON PUSHD_AND_POPD
$SHORT_DOC pushd [dir | +n | -n]
Adds a directory to the top of the directory stack, or rotates
the stack, making the new top of the stack the current working
directory. With no arguments, exchanges the top two directories.
+n Rotates the stack so that the Nth directory (counting
from the left of the list shown by `dirs') is at the top.
-n Rotates the stack so that the Nth directory (counting
from the right) is at the top.
dir adds DIR to the directory stack at the top, making it the
new current working directory.
You can see the directory stack with the `dirs' command.
If the variable `pushd_silent' is not set and the pushd command
was successful, a `dirs' is be performed as well.
$END
#if defined (PUSHD_AND_POPD)
/* Some useful commands whose behaviour has been observed in Csh. */
/* The list of remembered directories. */
static char **pushd_directory_list = (char **)NULL;
/* Number of existing slots in this list. */
static int directory_list_size = 0;
/* Offset to the end of the list. */
static int directory_list_offset = 0;
pushd_builtin (list)
WORD_LIST *list;
{
char *temp, *current_directory, *get_working_directory ();
int j = directory_list_offset - 1;
char direction = '+';
/* If there is no argument list then switch current and
top of list. */
if (!list)
{
if (!directory_list_offset)
{
builtin_error ("No other directory");
return (EXECUTION_FAILURE);
}
current_directory = get_working_directory ("pushd");
if (!current_directory)
return (EXECUTION_FAILURE);
temp = pushd_directory_list[j];
pushd_directory_list[j] = current_directory;
goto change_to_temp;
}
else
{
direction = *(list->word->word);
if (direction == '+' || direction == '-')
{
int num;
if (1 == sscanf (&(list->word->word)[1], "%d", &num))
{
if (direction == '-')
num = directory_list_offset - num;
if (num > directory_list_offset || num < 0)
{
if (!directory_list_offset)
builtin_error ("Directory stack empty");
else
builtin_error ("Stack contains only %d directories",
directory_list_offset + 1);
return (EXECUTION_FAILURE);
}
else
{
/* Rotate the stack num times. Remember, the
current directory acts like it is part of the
stack. */
temp = get_working_directory ("pushd");
if (!num)
goto change_to_temp;
do
{
char *top =
pushd_directory_list[directory_list_offset - 1];
for (j = directory_list_offset - 2; j > -1; j--)
pushd_directory_list[j + 1] = pushd_directory_list[j];
pushd_directory_list[j + 1] = temp;
temp = top;
num--;
}
while (num);
temp = savestring (temp);
change_to_temp:
{
int tt = EXECUTION_FAILURE;
if (temp)
{
tt = cd_to_string (temp);
free (temp);
}
if ((tt == EXECUTION_SUCCESS) &&
(!find_variable ("pushd_silent")))
dirs_builtin ((WORD_LIST *)NULL);
return (tt);
}
}
}
}
/* Change to the directory in list->word->word. Save the current
directory on the top of the stack. */
current_directory = get_working_directory ("pushd");
if (!current_directory)
return (EXECUTION_FAILURE);
if (cd_builtin (list) == EXECUTION_SUCCESS)
{
if (directory_list_offset == directory_list_size)
{
pushd_directory_list = (char **)
xrealloc (pushd_directory_list,
(directory_list_size += 10) * sizeof (char *));
}
pushd_directory_list[directory_list_offset++] = current_directory;
if (!find_variable ("pushd_silent"))
dirs_builtin ((WORD_LIST *)NULL);
return (EXECUTION_SUCCESS);
}
else
{
free (current_directory);
return (EXECUTION_FAILURE);
}
}
}
#endif /* PUSHD_AND_POPD */
$BUILTIN dirs
$FUNCTION dirs_builtin
$DEPENDS_ON PUSHD_AND_POPD
$SHORT_DOC dirs [-l]
Display the list of currently remembered directories. Directories
find their way onto the list with the `pushd' command; you can get
back up through the list with the `popd' command.
The -l flag specifies that `dirs' should not print shorthand versions
of directories which are relative to your home directory. This means
that `~/bin' might be displayed as `/homes/bfox/bin'.
$END
#if defined (PUSHD_AND_POPD)
/* Print the current list of directories on the directory stack. */
dirs_builtin (list)
WORD_LIST *list;
{
register int i, format = 0;
char *temp, *polite_directory_format (), *get_working_directory ();
/* Maybe do long form? */
if (list)
{
if (strcmp (list->word->word, "-l") == 0)
format++;
else if (!format || list->next)
{
bad_option (list->word->word);
return (EXECUTION_FAILURE);
}
}
/* The first directory printed is always the current working directory. */
temp = get_working_directory ("dirs");
if (!temp)
temp = savestring ("<no directory>");
printf ("%s", format ? temp : polite_directory_format (temp));
free (temp);
/* Now print any directories in the array. */
for (i = (directory_list_offset - 1); i > -1; i--)
printf (" %s", format ? pushd_directory_list[i] :
polite_directory_format (pushd_directory_list[i]));
putchar ('\n');
fflush (stdout);
return (EXECUTION_SUCCESS);
}
#endif /* PUSHD_AND_POPD */
$BUILTIN popd
$FUNCTION popd_builtin
$DEPENDS_ON PUSHD_AND_POPD
$SHORT_DOC popd [+n | -n]
Removes entries from the directory stack. With no arguments,
removes the top directory from the stack, and cd's to the new
top directory.
+n removes the Nth entry counting from the left of the list
shown by `dirs', starting with zero. For example: `popd +0'
removes the first directory, `popd +1' the second.
-n removes the Nth entry counting from the right of the list
shown by `dirs', starting with zero. For example: `popd -0'
removes the last directory, `popd -1' the next to last.
You can see the directory stack with the `dirs' command.
If the variable 'pushd_silent' is not set and the popd command
was successful, a 'dirs' will be performed as well..
$END
#if defined (PUSHD_AND_POPD)
/* Pop the directory stack, and then change to the new top of the stack.
If LIST is non-null it should consist of a word +N or -N, which says
what element to delete from the stack. The default is the top one. */
popd_builtin (list)
WORD_LIST *list;
{
register int i;
int which = 0;
char direction = '+';
if (list)
{
direction = *(list->word->word);
if ((direction != '+' && direction != '-') ||
(1 != sscanf (&((list->word->word)[1]), "%d", &which)))
{
builtin_error ("bad arg `%s'", list->word->word);
return (EXECUTION_FAILURE);
}
}
if (which > directory_list_offset || (!directory_list_offset && !which))
{
if (!directory_list_offset)
builtin_error ("Directory stack empty");
else
builtin_error ("Stack contains only %d directories",
directory_list_offset + 1);
return (EXECUTION_FAILURE);
}
/* Handle case of no specification, or top of stack specification. */
if ((direction == '+' && which == 0) ||
(direction == '-' && which == directory_list_offset))
{
i = cd_to_string (pushd_directory_list[directory_list_offset - 1]);
if (i != EXECUTION_SUCCESS)
return (i);
free (pushd_directory_list[--directory_list_offset]);
}
else
{
/* Since an offset other than the top directory was specified,
remove that directory from the list and shift the remainder
of the list into place. */
if (direction == '+')
i = directory_list_offset - which;
else
i = which;
free (pushd_directory_list[i]);
directory_list_offset--;
/* Shift the remainder of the list into place. */
for (; i < directory_list_offset; i++)
pushd_directory_list[i] = pushd_directory_list[i + 1];
}
if (!find_variable ("pushd_silent"))
dirs_builtin ((WORD_LIST *)NULL);
return (EXECUTION_SUCCESS);
}
#endif /* PUSHD_AND_POPD */
/* Do the work of changing to the directory NEWDIR. Handle symbolic
link following, etc. */
static int
change_to_directory (newdir)
char *newdir;
{
char *get_working_directory (), *make_absolute ();
char *t;
if (follow_symbolic_links)
{
if (!the_current_working_directory)
{
t = get_working_directory ("cd_links");
if (t)
free (t);
}
if (the_current_working_directory)
t = make_absolute (newdir, the_current_working_directory);
else
t = savestring (newdir);
/* Get rid of trailing `/'. */
{
register int len_t = strlen (t);
if (len_t > 1)
{
--len_t;
if (t[len_t] == '/')
t[len_t] = '\0';
}
}
if (chdir (t) < 0)
{
free (t);
return (0);
}
if (the_current_working_directory)
strcpy (the_current_working_directory, t);
free (t);
return (1);
}
else
{
if (chdir (newdir) < 0)
return (0);
else
return (1);
}
}
/* Switch to the directory in NAME. This uses the cd_builtin to do the work,
so if the result is EXECUTION_FAILURE then an error message has already
been printed. */
static int
cd_to_string (name)
char *name;
{
extern WORD_LIST *make_word_list ();
WORD_LIST *tlist = make_word_list (make_word (name), NULL);
int result = (cd_builtin (tlist));
dispose_words (tlist);
return (result);
}

View File

@@ -0,0 +1,37 @@
This file is colon.def, from which is created colon.c.
It implements the builtin ":" in Bash.
Copyright (C) 1987, 1989, 1991 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 1, 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; see the file COPYING. If not, write to the Free Software
Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
$PRODUCES colon.c
$BUILTIN :
$DOCNAME colon_builtin
$FUNCTION colon_builtin
$SHORT_DOC :
No effect; the command does nothing. A zero exit code is returned.
$END
/* Do nothing. This command is a no-op. */
int
colon_builtin (ignore)
char *ignore;
{
return (0);
}

View File

@@ -0,0 +1,142 @@
This file is command.def, from which is created command.c.
It implements the builtin "command" in Bash.
Copyright (C) 1987, 1989, 1991 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 1, 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; see the file COPYING. If not, write to the Free Software
Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
$PRODUCES command.c
$BUILTIN command
$FUNCTION command_builtin
$SHORT_DOC command [-p] [command [arg ...]]
Runs COMMAND with ARGS ignoring shell functions. If you have a shell
function called `ls', and you wish to call the command `ls', you can
say "command ls". If the -p option is given, a default value is used
for PATH that is guaranteed to find all of the standard utilities.
$END
#include "../shell.h"
static void restore_path ();
static char *get_standard_path ();
/* Run the commands mentioned in LIST without paying attention to shell
functions. */
int
command_builtin (list)
WORD_LIST *list;
{
int result;
int use_standard_path = 0;
char *old_path;
while (list)
{
if (strcmp (list->word->word, "-p") == 0)
{
use_standard_path = 1;
list = list->next;
}
else if (strcmp (list->word->word, "--") == 0)
{
list = list->next;
break;
}
else if (*list->word->word == '-')
{
bad_option (list->word->word);
return (EXECUTION_FAILURE);
}
else
break;
}
if (!list)
return (EXECUTION_SUCCESS);
begin_unwind_frame ("command_builtin");
/* We don't want this to be reparsed (consider command echo 'foo &'), so
just make a simple_command structure and call execute_command with it. */
{
COMMAND *command;
extern COMMAND *make_bare_simple_command ();
extern WORD_LIST *copy_word_list ();
extern void dispose_command ();
if (use_standard_path)
{
char *standard_path;
old_path = get_string_value ("PATH");
if (old_path)
old_path = savestring (old_path);
else
old_path = savestring ("");
add_unwind_protect ((Function *)restore_path, old_path);
standard_path = get_standard_path ();
bind_variable ("PATH", standard_path);
free (standard_path);
}
command = make_bare_simple_command ();
command->value.Simple->words = (WORD_LIST *)copy_word_list (list);
command->value.Simple->redirects = (REDIRECT *)NULL;
command->flags |= (CMD_NO_FUNCTIONS | CMD_INHIBIT_EXPANSION);
command->value.Simple->flags |= (CMD_NO_FUNCTIONS | CMD_INHIBIT_EXPANSION);
add_unwind_protect ((char *)dispose_command, command);
result = execute_command (command);
}
run_unwind_frame ("command_builtin");
return (result);
}
/* Restore the value of the $PATH variable after replacing it when
executing `command -p'. */
static void
restore_path (var)
char *var;
{
bind_variable ("PATH", var);
free (var);
}
/* Return a value for PATH that is guaranteed to find all of the standard
utilities. This uses Posix.2 configuration variables, if present. It
uses a value defined in config.h as a last resort. */
static char *
get_standard_path ()
{
#if defined (_CS_PATH) && !defined (HPUX_70)
char *p;
size_t len;
len = (long) confstr (_CS_PATH, (char *)NULL, (size_t)0);
p = xmalloc ((int)len + 2);
(void) confstr (_CS_PATH, p, len);
return (p);
#else /* !_CSPATH || HPUX_70 */
# if defined (CS_PATH)
return (savestring (CS_PATH));
# else
return (savestring (STANDARD_UTILS_PATH));
# endif /* !CS_PATH */
#endif /* !_CS_PATH || HPUX_70 */
}

View File

@@ -0,0 +1,624 @@
/* Copyright (C) 1987, 1989, 1991 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 1, 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; see the file COPYING. If not, write to the Free Software
Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
#include <stdio.h>
#include <sys/types.h>
#if defined (HAVE_VPRINTF)
#include <varargs.h>
#endif /* VPRINTF */
#include "../shell.h"
#include "../unwind_prot.h"
#include "../maxpath.h"
#include "../jobs.h"
#include "../builtins.h"
#include "hashcom.h"
void no_args (), remember_args (), parse_and_execute_cleanup ();
extern int follow_symbolic_links, interactive;
/* 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. */
int
get_numeric_arg (list)
WORD_LIST *list;
{
int count = 1;
if (list)
{
if (sscanf (list->word->word, "%d", &count) != 1)
{
builtin_error ("bad non-numeric arg `%s'", list->word->word);
throw_to_top_level ();
}
no_args (list->next);
}
return (count);
}
/* 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. */
#if defined (HAVE_VPRINTF)
/* VARARGS */
builtin_error (va_alist)
va_dcl
{
extern char *this_command_name;
char *format;
va_list args;
if (this_command_name && *this_command_name)
fprintf (stderr, "%s: ", this_command_name);
va_start (args);
format = va_arg (args, char *);
vfprintf (stderr, format, args);
va_end (args);
fprintf (stderr, "\n");
}
#else /* Without VARARGS. */
builtin_error (format, arg1, arg2, arg3, arg4, arg5)
char *format, *arg1, *arg2, *arg3, *arg4, *arg5;
{
extern char *this_command_name;
if (this_command_name && *this_command_name)
fprintf (stderr, "%s: ", this_command_name);
fprintf (stderr, format, arg1, arg2, arg3, arg4, arg5);
fprintf (stderr, "\n");
fflush (stderr);
}
#endif /* HAVE_VPRINTF */
/* Remember LIST in $0 ... $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;
extern WORD_LIST *copy_word_list ();
for (i = 1; i < 10; i++)
{
if (destructive && dollar_vars[i])
{
free (dollar_vars[i]);
dollar_vars[i] = (char *)NULL;
}
if (list)
{
if (!destructive && dollar_vars[i])
free (dollar_vars[i]);
dollar_vars[i] = savestring (list->word->word);
list = list->next;
}
}
/* If arguments remain, assign them to REST_OF_ARGS. */
if (!list)
{
dispose_words (rest_of_args);
rest_of_args = NULL;
}
else
{
rest_of_args = (WORD_LIST *)copy_word_list (list);
}
}
/* Return if LIST is NULL else barf and jump to top_level. */
void
no_args (list)
WORD_LIST *list;
{
if (list)
{
builtin_error ("extra arguments");
longjmp (top_level, DISCARD);
}
}
/* 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 = 0;
int digits = 0;
while (*string && *string >= '0' && *string < '8')
{
digits++;
result = (result * 8) + *string++ - '0';
}
if (!digits || result > 0777 || *string)
result = -1;
return (result);
}
/* Temporary static. */
char *dotted_filename = (char *)NULL;
/* Return the full pathname that FILENAME hashes to. If FILENAME
is hashed, but data->check_dot is non-zero, check ./FILENAME
and return that if it is executable. */
char *
find_hashed_filename (filename)
char *filename;
{
extern HASH_TABLE *hashed_filenames;
extern int hashing_disabled;
register BUCKET_CONTENTS *item;
if (hashing_disabled)
return ((char *)NULL);
item = find_hash_item (filename, hashed_filenames);
if (item)
{
/* If this filename is hashed, but `.' comes before it in the path,
then see if `./filename' is an executable. */
if (pathdata(item)->check_dot)
{
if (dotted_filename)
free (dotted_filename);
dotted_filename = (char *)xmalloc (3 + strlen (filename));
strcpy (dotted_filename, "./");
strcat (dotted_filename, filename);
if (executable_file (dotted_filename))
return (dotted_filename);
/* Watch out. If this file was hashed to "./filename", and
"./filename" is not executable, then return NULL. */
/* Since we already know "./filename" is not executable, what
we're really interested in is whether or not the `path'
portion of the hashed filename is equivalent to the current
directory, but only if it starts with a `.'. (This catches
./. and so on.) same_file () is in execute_cmd.c; it tests
general Unix file equivalence -- same device and inode. */
{
char *path = pathdata (item)->path;
if (*path == '.')
{
int same = 0;
char *rindex (), *tail;
tail = rindex (path, '/');
if (tail)
{
*tail = '\0';
same = same_file
(".", path, (struct stat *)NULL, (struct stat *)NULL);
*tail = '/';
}
if (same)
return ((char *)NULL);
}
}
}
return (pathdata (item)->path);
}
else
return ((char *)NULL);
}
/* **************************************************************** */
/* */
/* Pushing and Popping a Context */
/* */
/* **************************************************************** */
WORD_LIST **dollar_arg_stack = (WORD_LIST **)NULL;
int dollar_arg_stack_slots = 0;
int dollar_arg_stack_index = 0;
void push_dollar_vars (), pop_dollar_vars ();
void
push_context ()
{
extern int variable_context;
push_dollar_vars ();
variable_context++;
}
void
pop_context ()
{
extern int variable_context;
pop_dollar_vars ();
kill_all_local_variables ();
variable_context--;
}
/* Save the existing positional parameters on a stack. */
void
push_dollar_vars ()
{
extern WORD_LIST *list_rest_of_args ();
if (dollar_arg_stack_index + 2 > dollar_arg_stack_slots)
{
if (!dollar_arg_stack)
{
dollar_arg_stack =
(WORD_LIST **)xrealloc (dollar_arg_stack,
(dollar_arg_stack_slots += 10)
* sizeof (WORD_LIST **));
}
}
dollar_arg_stack[dollar_arg_stack_index] = list_rest_of_args ();
dollar_arg_stack[++dollar_arg_stack_index] = (WORD_LIST *)NULL;
}
/* Restore the positional parameters from our stack. */
void
pop_dollar_vars ()
{
if (!dollar_arg_stack || !dollar_arg_stack_index)
return;
remember_args (dollar_arg_stack[--dollar_arg_stack_index], 1);
dispose_words (dollar_arg_stack[dollar_arg_stack_index]);
dollar_arg_stack[dollar_arg_stack_index] = (WORD_LIST *)NULL;
}
/* Function called when one of the builtin commands detects a bad
option. */
bad_option (s)
char *s;
{
builtin_error ("unknown option: %s", s);
}
/* 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 (!follow_symbolic_links)
{
if (the_current_working_directory)
free (the_current_working_directory);
the_current_working_directory = (char *)NULL;
}
if (!the_current_working_directory)
{
char *directory, *getwd ();
the_current_working_directory = (char *)xmalloc (MAXPATHLEN);
directory = getwd (the_current_working_directory);
if (!directory)
{
fprintf (stderr, "%s: %s\n\r",
for_whom, the_current_working_directory);
free (the_current_working_directory);
the_current_working_directory = (char *)NULL;
return (char *)NULL;
}
}
return (savestring (the_current_working_directory));
}
#if defined (JOB_CONTROL)
/* Return the job spec found in LIST. */
get_job_spec (list)
WORD_LIST *list;
{
register char *word;
int job = NO_JOB;
int substring = 0;
if (!list)
return (current_job);
word = list->word->word;
if (!*word)
return (current_job);
if (*word == '%')
word++;
if (digit (*word) && (sscanf (word, "%d", &job) == 1))
return (job - 1);
switch (*word)
{
case 0:
case '%':
case '+':
return (current_job);
case '-':
return (previous_job);
case '?': /* Substring search requested. */
substring++;
word++;
goto find_string;
default:
find_string:
{
register int i, wl = strlen (word);
for (i = 0; i < job_slots; i++)
{
if (jobs[i])
{
register PROCESS *p = jobs[i]->pipe;
extern char *strindex ();
do
{
if ((substring && strindex (p->command, word)) ||
(strncmp (p->command, word, wl) == 0))
if (job != NO_JOB)
{
builtin_error ("ambigious job spec: %s", word);
return (DUP_JOB);
}
else
job = i;
p = p->next;
}
while (p != jobs[i]->pipe);
}
}
return (job);
}
}
}
#endif /* JOB_CONTROL */
/* The command name of the currently running function. */
extern char *this_command_name;
int parse_and_execute_level = 0;
/* How to force parse_and_execute () to clean up after itself. */
void
parse_and_execute_cleanup ()
{
run_unwind_frame ("parse_and_execute_top");
}
/* Parse and execute the commands in STRING. Returns whatever
execute_command () returns. This frees STRING. */
int
parse_and_execute (string, from_file)
char *string;
char *from_file;
{
extern int remember_on_history;
extern int history_expansion_inhibited;
extern int indirection_level;
extern int builtin_pipe_in, builtin_pipe_out;
extern COMMAND *global_command;
extern char *indirection_level_string ();
extern int pop_stream (), free ();
int last_result = EXECUTION_SUCCESS;
int code, jump_to_top_level = 0;
char *orig_string = string;
/* Unwind protect this invocation of parse_and_execute (). */
begin_unwind_frame ("parse_and_execute_top");
unwind_protect_int (parse_and_execute_level);
unwind_protect_jmp_buf (top_level);
unwind_protect_int (indirection_level);
unwind_protect_int (interactive);
unwind_protect_int (remember_on_history);
unwind_protect_int (history_expansion_inhibited);
add_unwind_protect (pop_stream, (char *)NULL);
if (orig_string)
add_unwind_protect (free, orig_string);
end_unwind_frame ();
parse_and_execute_level++;
push_stream ();
interactive = 0;
indirection_level++;
/* We don't remember text read by the shell this way on
the history list, and we don't use !$ in shell scripts. */
remember_on_history = 0;
history_expansion_inhibited = 1;
with_input_from_string (string, from_file);
{
extern char *yy_input_dev;
COMMAND *command;
while (*yy_input_dev)
{
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. */
if (code = setjmp (top_level))
{
switch (code)
{
case FORCE_EOF:
case EXITPROG:
run_unwind_frame ("pe_dispose");
/* Remember to call longjmp (top_level) after the old
value for it is restored. */
jump_to_top_level = 1;
goto out;
case DISCARD:
run_unwind_frame ("pe_dispose");
continue;
default:
programming_error ("bad jump to top_level: %d", code);
break;
}
}
if (parse_command () == 0)
{
if ((command = global_command) != (COMMAND *)NULL)
{
extern struct fd_bitmap *new_fd_bitmap ();
extern void dispose_fd_bitmap ();
struct fd_bitmap *bitmap;
bitmap = new_fd_bitmap (FD_BITMAP_SIZE);
begin_unwind_frame ("pe_dispose");
add_unwind_protect (dispose_fd_bitmap, bitmap);
global_command = (COMMAND *)NULL;
if (builtin_pipe_in != NO_PIPE)
bitmap->bitmap[builtin_pipe_in] = 1;
if (builtin_pipe_out != NO_PIPE)
bitmap->bitmap[builtin_pipe_out] = 1;
last_result =
execute_command_internal
(command, 0, NO_PIPE, NO_PIPE, bitmap);
dispose_command (command);
run_unwind_frame ("pe_dispose");
}
}
else
{
last_result = EXECUTION_FAILURE;
/* Since we are shell compatible, syntax errors in a script
abort the execution of the script. Right? */
break;
}
}
}
out:
run_unwind_frame ("parse_and_execute_top");
if (interrupt_state && parse_and_execute_level == 0)
throw_to_top_level ();
if (jump_to_top_level)
longjmp (top_level, code);
return (last_result);
}
/* Return the address of the builtin named NAME.
DISABLED_OKAY means find it even if the builtin is disabled. */
Function *
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 = strcmp (shell_builtins[mid].name, name);
if (j == 0)
{
if (shell_builtins[mid].function &&
(shell_builtins[mid].enabled || disabled_okay))
return (shell_builtins[mid].function);
else
return ((Function *)NULL);
}
if (j > 0)
hi = mid - 1;
else
lo = mid + 1;
}
return ((Function *)NULL);
}
/* 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. */
Function *
find_shell_builtin (name)
char *name;
{
return (builtin_address_internal (name, 0));
}
/* Return the address of builtin with NAME, irregardless of its state of
enableness. */
Function *
builtin_address (name)
char *name;
{
return (builtin_address_internal (name, 1));
}
static int
shell_builtin_compare (sbp1, sbp2)
struct builtin *sbp1, *sbp2;
{
return (strcmp (sbp1->name, sbp2->name));
}
/* Sort the table of shell builtins so that the binary search will work
in find_shell_builtin. */
initialize_shell_builtins ()
{
qsort (shell_builtins, num_shell_builtins, sizeof (struct builtin),
shell_builtin_compare);
}

View File

@@ -0,0 +1,278 @@
This file is declare.def, from which is created declare.c.
It implements the builtins "declare" and "local" in Bash.
Copyright (C) 1987, 1989, 1991 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 1, 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; see the file COPYING. If not, write to the Free Software
Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
$PRODUCES declare.c
$BUILTIN declare
$FUNCTION declare_builtin
$SHORT_DOC declare [-[frxi]] name[=value] ...
Declare variables and/or give them attributes. If no NAMEs are
given, then display the values of variables instead.
The flags are:
-f to select from among function names only,
-r to make NAMEs readonly,
-x to make NAMEs export,
-i to make NAMEs have the `integer' attribute set.
Variables with the integer attribute have arithmetic evaluation (see
`let') done when the variable is assigned to.
Using `+' instead of `-' turns off the given attribute instead. When
used in a function, makes NAMEs local, as with the `local' command.
$END
$BUILTIN typeset
$FUNCTION declare_builtin
$SHORT_DOC typeset [-[frxi]] name[=value] ...
Obsolete. See `declare'.
$END
#include <stdio.h>
#include "../shell.h"
static int declare_internal ();
/* 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 name[=value] ...
Create a local variable called NAME, and give it VALUE. LOCAL
can only be used within a function; it makes the variable NAME
have a visible scope restricted to that function and its children.
$END
int
local_builtin (list)
register WORD_LIST *list;
{
extern int variable_context;
if (variable_context)
return (declare_internal (list, 1));
else
{
builtin_error ("Can only be used in a function");
return (EXECUTION_FAILURE);
}
}
/* The workhorse function. */
static int
declare_internal (list, no_modifiers)
register WORD_LIST *list;
int no_modifiers;
{
extern int variable_context, array_needs_making;
int flags_on = 0, flags_off = 0;
int any_failed = 0;
while (list)
{
register char *t = list->word->word;
int *flags;
if (strcmp (t, "--") == 0)
{
list = list->next;
break;
}
if (*t != '+' && *t != '-')
break;
if (no_modifiers)
{
builtin_error ("Modifiers not allowed");
return (EXECUTION_FAILURE);
}
if (*t == '+')
flags = &flags_off;
else
flags = &flags_on;
t++;
while (*t)
{
if (*t == 'f')
*flags |= att_function, t++;
else if (*t == 'x')
*flags |= att_exported, t++, array_needs_making = 1;
else if (*t == 'r')
*flags |= att_readonly, t++;
else if (*t == 'i')
*flags |= att_integer, t++;
else
{
builtin_error ("unknown option: `-%c'", *t);
return (EXECUTION_FAILURE);
}
}
list = list->next;
}
/* If there are no more arguments left, then we just want to show
some variables. */
if (!list)
{
/* If we didn't allow modifiers, then this is the `local' command.
Perhaps the flag should be called `local_command' instead of
`no_modifiers'. At any rate, only show local variables defined
at this context level. */
if (no_modifiers)
{
register SHELL_VAR **vlist;
register int i;
vlist = map_over (variable_in_context, shell_variables);
if (vlist)
{
for (i = 0; vlist[i]; i++)
print_assignment (vlist[i]);
free (vlist);
}
}
else
{
if (!flags_on)
set_builtin ((WORD_LIST *)NULL);
else
set_or_show_attributes ((WORD_LIST *)NULL, flags_on);
}
fflush (stdout);
return (EXECUTION_SUCCESS);
}
/* There are arguments left, so we are making variables. */
while (list)
{
char *value, *name = savestring (list->word->word);
int offset = assignment (name);
if (offset)
{
name[offset] = '\0';
value = name + offset + 1;
}
else
{
value = "";
}
/* 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. */
if (variable_context)
make_local_variable (name);
/* 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)
{
builtin_error ("Can't use `-f' to make functions");
return (EXECUTION_FAILURE);
}
else
{
SHELL_VAR *find_function (), *funvar;
funvar = find_function (name);
if (funvar)
{
extern char *named_function_string ();
char *result = named_function_string
(name, (COMMAND *)function_cell (funvar), 1);
printf ("%s\n", result);
}
else
any_failed++;
goto hack_next_variable;
}
}
else
{
SHELL_VAR *var;
var = find_variable (name);
if (!var)
var = bind_variable (name, "");
/* We are not allowed to rebind readonly variables that
already are readonly unless we are turning off the
readonly bit. */
if (flags_off & att_readonly)
flags_on &= ~att_readonly;
if (value && readonly_p (var) && (!(flags_off & att_readonly)))
{
builtin_error ("%s: readonly variable", name);
any_failed++;
goto hack_next_variable;
}
var->attributes |= flags_on;
var->attributes &= ~flags_off;
if (offset)
{
free (var->value);
if (integer_p (var))
{
long val, evalexp ();
char *itos ();
val = evalexp (value);
var->value = itos ((int)val);
}
else
var->value = savestring (value);
}
}
stupidly_hack_special_variables (name);
hack_next_variable:
free (name);
list = list->next;
}
return ((!any_failed) ? EXECUTION_SUCCESS : EXECUTION_FAILURE);
}

View File

@@ -0,0 +1,174 @@
This file is echo.def, from which is created echo.c.
It implements the builtin "echo" in Bash.
Copyright (C) 1987, 1989, 1991 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 1, 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; see the file COPYING. If not, write to the Free Software
Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
$PRODUCES echo.c
#include <stdio.h>
#include "../shell.h"
$BUILTIN echo
$FUNCTION echo_builtin
$DEPENDS_ON V9_ECHO
$SHORT_DOC echo [-neE] [arg ...]
Output the ARGs. If -n is specified, the trailing newline is
suppressed. If the -e option is given, interpretation of the
following backslash-escaped characters is turned on:
\a alert (bell)
\b backspace
\c suppress trailing newline
\f form feed
\n new line
\r carriage return
\t horizontal tab
\v vertical tab
\\ backslash
\num the character whose ASCII code is NUM (octal).
You can explicitly turn off the interpretation of the above characters
on System V systems with the -E option.
$END
$BUILTIN echo
$FUNCTION echo_builtin
$DEPENDS_ON !V9_ECHO
$SHORT_DOC echo [-n] [arg ...]
Output the ARGs. If -n is specified, the trailing newline is suppressed.
$END
#if defined (V9_ECHO)
# if defined (USG)
# define VALID_ECHO_OPTIONS "neE"
# else
# define VALID_ECHO_OPTIONS "ne"
# endif /* !USG */
#else /* !V9_ECHO */
# define VALID_ECHO_OPTIONS "n"
#endif /* !V9_ECHO */
/* Print the words in LIST to standard output. If the first word is
`-n', then don't print a trailing newline. We also support the
echo syntax from Version 9 unix systems. */
echo_builtin (list)
WORD_LIST *list;
{
int display_return = 1, do_v9 = 0;
/* System V machines already have a /bin/sh with a v9 behaviour. We
give Bash the identical behaviour for these machines so that the
existing system shells won't barf. */
#if defined (V9_ECHO) && defined (USG)
do_v9 = 1;
#endif
while (list && list->word->word[0] == '-')
{
register char *temp;
register int i;
/* If it appears that we are handling options, then make sure that
all of the options specified are actually valid. Otherwise, the
string should just be echoed. */
temp = &(list->word->word[1]);
for (i = 0; temp[i]; i++)
{
if (rindex (VALID_ECHO_OPTIONS, temp[i]) == 0)
goto just_echo;
}
if (!*temp)
goto just_echo;
/* All of the options in TEMP are valid options to ECHO.
Handle them. */
while (*temp)
{
if (*temp == 'n')
display_return = 0;
#if defined (V9_ECHO)
else if (*temp == 'e')
do_v9 = 1;
#if defined (USG)
else if (*temp == 'E')
do_v9 = 0;
#endif /* USG */
#endif /* V9_ECHO */
else
goto just_echo;
temp++;
}
list = list->next;
}
just_echo:
if (list)
{
#if defined (V9_ECHO)
if (do_v9)
{
while (list)
{
register char *s = list->word->word;
register int c;
while (c = *s++)
{
if (c == '\\' && *s)
{
switch (c = *s++)
{
case 'a': c = '\007'; break;
case 'b': c = '\b'; break;
case 'c': display_return = 0; continue;
case 'f': c = '\f'; break;
case 'n': c = '\n'; break;
case 'r': c = '\r'; break;
case 't': c = '\t'; break;
case 'v': c = (int) 0x0B; break;
case '0': case '1': case '2': case '3':
case '4': case '5': case '6': case '7':
c -= '0';
if (*s >= '0' && *s <= '7')
c = c * 8 + (*s++ - '0');
if (*s >= '0' && *s <= '7')
c = c * 8 + (*s++ - '0');
break;
case '\\': break;
default: putchar ('\\'); break;
}
}
putchar(c);
}
list = list->next;
if (list)
putchar(' ');
}
}
else
#endif /* V9_ECHO */
print_word_list (list, " ");
}
if (display_return)
printf ("\n");
fflush (stdout);
return (EXECUTION_SUCCESS);
}

View File

@@ -0,0 +1,103 @@
This file is enable.def, from which is created enable.c.
It implements the builtin "enable" in Bash.
Copyright (C) 1987, 1989, 1991 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 1, 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; see the file COPYING. If not, write to the Free Software
Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
$PRODUCES enable.c
$BUILTIN enable
$FUNCTION enable_builtin
$SHORT_DOC enable [-n] [name ...]
Enable and disable builtin shell commands. This allows
you to use a disk command which has the same name as a shell
builtin. If -n is used, the NAMEs become disabled. Otherwise
NAMEs are enabled. For example, to use the `test' found on your
path instead of the shell builtin version, you type `enable -n test'.
$END
#include "../shell.h"
#include "../builtins.h"
static int enable_shell_command ();
/* Enable/disable shell commands present in LIST. If list is not specified,
then print out a list of shell commands showing which are enabled and
which are disabled. */
enable_builtin (list)
WORD_LIST *list;
{
int result = 0, any_failed = 0;
if (!list)
{
register int i;
for (i = 0; i < num_shell_builtins; i++)
{
if (!shell_builtins[i].function)
continue;
printf ("enable %s%s\n", shell_builtins[i].enabled ? "" : "-n ",
shell_builtins[i].name);
}
}
else
{
int disable_p = (strcmp (list->word->word, "-n") == 0);
if (disable_p)
list = list->next;
while (list)
{
result = enable_shell_command (list->word->word, disable_p);
if (!result)
{
builtin_error ("%s: not a shell builtin", list->word->word);
any_failed++;
}
list = list->next;
}
}
return (any_failed ? EXECUTION_FAILURE : EXECUTION_SUCCESS);
}
/* Enable the shell command NAME. If DISABLE_P is non-zero, then
disable NAME instead. */
static int
enable_shell_command (name, disable_p)
char *name;
int disable_p;
{
register int i;
int found = 0;
for (i = 0; i < num_shell_builtins; i++)
{
if (!shell_builtins[i].function)
continue;
if (strcmp (name, shell_builtins[i].name) == 0)
{
found++;
shell_builtins[i].enabled = !disable_p;
}
}
return (found);
}

View File

@@ -0,0 +1,46 @@
This file is eval.def, from which is created eval.c.
It implements the builtin "eval" in Bash.
Copyright (C) 1987, 1989, 1991 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 1, 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; see the file COPYING. If not, write to the Free Software
Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
$PRODUCES eval.c
$BUILTIN eval
$FUNCTION eval_builtin
$SHORT_DOC eval [arg ...]
Read ARGs as input to the shell and execute the resulting command(s).
$END
#include "../shell.h"
/* Parse the string that these words make, and execute the command found. */
int
eval_builtin (list)
WORD_LIST *list;
{
char *string_list ();
int result;
/* Note that parse_and_execute () free ()'s what it is passed. */
if (list)
result = parse_and_execute (string_list (list), "eval");
else
result = EXECUTION_SUCCESS;
return (result);
}

View File

@@ -0,0 +1,127 @@
This file is exec.def, from which is created exec.c.
It implements the builtin "exec" in Bash.
Copyright (C) 1987, 1989, 1991 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 1, 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; see the file COPYING. If not, write to the Free Software
Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
$PRODUCES exec.c
$BUILTIN exec
$FUNCTION exec_builtin
$SHORT_DOC exec [ [-] file [redirection ...]]
Exec FILE, replacing this shell with the specified program.
If FILE is not specified, the redirections take effect in this
shell. If the first argument is `-', then place a dash in the
zeroth arg passed to FILE. This is what login does. If the file
cannot be exec'ed for some reason, the shell exits, unless the
shell variable "no_exit_on_failed_exec" exists.
$END
#include "../shell.h"
#include <sys/types.h>
#include <signal.h>
#include <errno.h>
extern int interactive, errno;
extern REDIRECT *redirection_undo_list;
int
exec_builtin (list)
WORD_LIST *list;
{
extern char *find_user_command ();
maybe_make_export_env ();
/* First, let the redirections remain. */
dispose_redirects (redirection_undo_list);
redirection_undo_list = (REDIRECT *)NULL;
if (!list)
return (EXECUTION_SUCCESS);
else
{
/* Otherwise, execve the new command with args. */
char *command, **args;
int dash_name = 0;
if (strcmp (list->word->word, "-") == 0)
{
/* The user would like to exec this command as if it was a
login command. Do so. */
list = list->next;
dash_name++;
}
if (!list)
return (EXECUTION_SUCCESS);
args = (char **)make_word_array (list);
/* A command with a slash anywhere in its name is not looked up in
the search path. */
if (absolute_program (args[0]))
command = args[0];
else
command = find_user_command (args[0]);
if (!command)
{
builtin_error ("%s: not found", args[0]);
goto failed_exec;
}
command = (char *)full_pathname (command);
/* If the user wants this to look like a login shell, then
prepend a `-' onto the first argument (argv[0]). */
if (dash_name)
{
char *new_name = (char *)xmalloc (2 + strlen (args[0]));
strcpy (new_name, "-");
strcat (new_name, args[0]);
free (args[0]);
args[0] = new_name;
}
/* 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. */
adjust_shell_level (-1);
maybe_make_export_env ();
maybe_save_shell_history ();
restore_default_signal (SIGINT);
restore_default_signal (SIGQUIT);
restore_default_signal (SIGTERM);
restore_original_signals ();
shell_execve (command, args, export_env);
adjust_shell_level (1);
if (!executable_file (command))
builtin_error ("%s: cannot execute: %s", command, strerror (errno));
else
file_error (command);
failed_exec:
if (!interactive && !find_variable ("no_exit_on_failed_exec"))
exit (EXECUTION_FAILURE);
return (EXECUTION_FAILURE);
}
}

View File

@@ -0,0 +1,134 @@
This file is exit.def, from which is created exit.c.
It implements the builtins "bye" and "exit", and "logout" in Bash.
Copyright (C) 1987, 1989, 1991 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 1, 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; see the file COPYING. If not, write to the Free Software
Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
$PRODUCES exit.c
$BUILTIN exit
$FUNCTION exit_builtin
$SHORT_DOC exit [n]
Exit the shell with a status of N. If N is omitted, the exit status
is that of the last command executed.
$END
$BUILTIN bye
$FUNCTION exit_builtin
$SHORT_DOC bye [n]
Synonym for exit.
$END
#include <stdio.h>
#include <sys/types.h>
#include "../shell.h"
#include "../jobs.h"
#if defined (JOB_CONTROL)
extern int jobs_builtin ();
#endif /* JOB_CONTROL */
extern int interactive;
int
exit_builtin (list)
WORD_LIST *list;
{
extern int login_shell;
if (interactive)
{
fprintf (stderr, login_shell ? "logout\n" : "exit\n");
fflush (stderr);
}
return (exit_or_logout (list));
}
$BUILTIN logout
$FUNCTION logout_builtin
$SHORT_DOC logout
Logout of a login shell.
$END
/* How to logout. */
int
logout_builtin (list)
WORD_LIST *list;
{
if (!login_shell && interactive)
{
builtin_error ("Not login shell: use `exit' or `bye'");
return (EXECUTION_FAILURE);
}
else
return (exit_or_logout (list));
}
/* Clean up work for exiting or logging out. */
Function *last_shell_builtin = (Function *)NULL;
Function *this_shell_builtin = (Function *)NULL;
exit_or_logout (list)
WORD_LIST *list;
{
extern int last_command_exit_value;
int exit_value;
#if defined (JOB_CONTROL)
int exit_immediate_okay;
exit_immediate_okay = (!interactive ||
last_shell_builtin == exit_builtin ||
last_shell_builtin == logout_builtin ||
last_shell_builtin == jobs_builtin);
/* Check for stopped jobs if the user wants to. */
if (!exit_immediate_okay)
{
register int i;
for (i = 0; i < job_slots; i++)
if (jobs[i] && (jobs[i]->state == JSTOPPED))
{
fprintf (stderr, "There are stopped jobs.\n");
/* This is NOT superfluous because EOF can get here without
going through the command parser. Set both last and this
so that either `exit', `logout', or ^D will work to exit
immediately if nothing intervenes. */
this_shell_builtin = last_shell_builtin = exit_builtin;
return (EXECUTION_FAILURE);
}
}
#endif /* JOB_CONTROL */
/* Get return value if present. This means that you can type
`logout 5' to a shell, and it returns 5. */
if (list)
exit_value = get_numeric_arg (list);
else
exit_value = last_command_exit_value;
/* Run our `~/.bash_logout' file if it exists, and this is a login shell. */
if (login_shell)
maybe_execute_file ("~/.bash_logout");
last_command_exit_value = exit_value;
/* Exit the program. */
longjmp (top_level, EXITPROG);
}

View File

@@ -0,0 +1,689 @@
This file is fc.def, from which is created fc.c.
It implements the builtin "fc" in Bash.
Copyright (C) 1987, 1989, 1991 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 1, 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; see the file COPYING. If not, write to the Free Software
Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
$PRODUCES fc.c
$BUILTIN fc
$FUNCTION fc_builtin
$SHORT_DOC fc [-e ename] [-nlr] [first] [last] or fc -s [pat=rep] [cmd]
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).
With the `fc -s [pat=rep ...] [command]' format, the 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.
$END
#include <stdio.h>
#include <sys/param.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/file.h>
#include <errno.h>
#include "../shell.h"
#include "../builtins.h"
#include "../flags.h"
#include "../maxpath.h"
#include <readline/history.h>
#if defined (NULL)
#undef NULL
#endif
#define NULL 0
extern int errno;
/* **************************************************************** */
/* */
/* 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.
*/
static char *fc_dosubs (), *fc_replace (), *fc_gethist (), *fc_readline ();
static int fc_gethnum ();
static void fc_replhist (), fc_addhist ();
/* Data structure describing a list of global replacements to perform. */
typedef struct repl {
struct repl *next;
char *pat;
char *rep;
} REPL;
#define USAGE "usage: fc [-e ename] [-nlr] [first] [last] or fc -s [pat=rep] [command]"
/* True if A is the first substring in B. */
#define prefix(a, b) (strncmp ((a), (b), strlen ((a))) == 0)
/* 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)
/* String to execute on a file that we want to edit. */
#define FC_EDIT_COMMAND "${FCEDIT:-${EDITOR:-vi}}"
int
fc_builtin (list)
WORD_LIST *list;
{
register int i;
register char *sep;
int numbering, reverse, listing, execute;
int histbeg, histend, last_hist, retval, first;
FILE *stream;
REPL *rlist = (REPL *) NULL, *rl;
char *ename = NULL, *command, *newcom, *line;
HIST_ENTRY **hlist;
char fn[MAXPATHLEN];
numbering = 1;
reverse = listing = execute = 0;
/* Parse out the options and set which of the two forms we're in. */
while (list && *list->word->word == '-')
{
register char *s = &((list->word->word)[1]);
register int c;
if (!isletter (*s)) /* for stuff like fc -e - -2 */
break;
while (c = *s++)
{
switch (c)
{
case 'n':
numbering = 0;
break;
case 'l':
listing = 1;
break;
case 'r':
reverse = 1;
break;
case 's':
execute = 1;
break;
case 'e':
list = list->next;
if (list == NULL)
{
builtin_error (USAGE);
return (EXECUTION_FAILURE);
}
ename = list->word->word;
break;
default:
builtin_error (USAGE);
return (EXECUTION_FAILURE);
}
}
list = list->next;
}
if (ename && (*ename == '-') && (ename[1] == '\0'))
execute = 1;
/* The "execute" form of the command (re-run, with possible string
substitutions). */
if (execute)
{
while (list && ((sep = (char *)index (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. */
if (rlist && rlist->next)
rlist = (REPL *) reverse_list ((GENERIC_LIST *) rlist);
hlist = history_list ();
/* If we still have something in list, it is a command spec.
Otherwise, we use the most recent command in time. */
if (list)
command = fc_gethist (list->word->word, hlist);
else
command = fc_gethist ((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;
}
printf ("%s\n", command);
fc_replhist (command); /* replace `fc -e -' with command */
return (parse_and_execute (command, "fc"));
}
/* This is the second form of the command (the list-or-edit-and-rerun
form). */
hlist = history_list ();
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. */
last_hist = i - 2;
if (list)
{
histbeg = fc_gethnum (list->word->word, hlist);
list = list->next;
if (list)
histend = fc_gethnum (list->word->word, hlist);
else
{
if (listing)
histend = last_hist;
else
histend = histbeg;
}
}
else
{
/* The default for listing is the last 16 history items. */
if (listing)
{
histend = last_hist;
histbeg = histend - 16;
}
else
{
/* For editing, it is the last history command. */
histbeg = histend = last_hist;
}
}
/* We print error messages for line specifications out of range. */
if ((histbeg < 0) || (histend < 0) ||
(histbeg > last_hist) || (histend > last_hist))
{
builtin_error ("history specification out of range");
return (EXECUTION_FAILURE);
}
if (histend < histbeg)
{
int t = histend;
histend = histbeg;
histbeg = t;
reverse = 1;
}
if (listing)
stream = stdout;
else
{
numbering = 0;
sprintf (fn, "/tmp/bash%d", (int)time ((long *) 0) + (int)getpid ());
stream = fopen (fn, "w");
if (!stream)
{
builtin_error ("cannot open temp file %s", fn);
return (EXECUTION_FAILURE);
}
}
if (!reverse)
{
for (i = histbeg; i <= histend; i++)
{
QUIT;
if (numbering)
fprintf (stream, "%d\t%c", i + history_base,
histdata (i) ? '*' : ' ');
fprintf (stream, "%s\n", histline (i));
}
}
else
{
for (i = histend; i >= histbeg; i--)
{
QUIT;
if (numbering)
fprintf (stream, "%d\t%c", i + history_base,
histdata (i) ? '*' : ' ');
fprintf (stream, "%s\n", histline (i));
}
}
if (listing)
return (EXECUTION_SUCCESS);
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
{
command = (char *)xmalloc (3 + strlen (FC_EDIT_COMMAND) + strlen (fn));
sprintf (command, "%s %s", FC_EDIT_COMMAND, fn);
}
parse_and_execute (command, "fc");
/* Now reopen the file and execute the edited commands. */
stream = fopen (fn, "r");
if (stream == NULL)
{
builtin_error ("cannot reopen temp file %s", fn);
unlink (fn);
return (EXECUTION_FAILURE);
}
retval = EXECUTION_SUCCESS;
first = 1;
/* First, write the commands to the history file. This will not happen
when we call parse_and_execute, since parse_and_execute disables
the command line history while it executes. */
while ((line = fc_readline (stream)) != NULL)
{
if (line[0] == '\n')
{
free (line);
continue; /* Skip blank lines. */
}
if (first)
{
first = 0;
fc_replhist (line);
}
else
fc_addhist (line);
}
fclose (stream);
{
extern int echo_input_at_read;
extern int unlink ();
/* Turn on the `v' flag while maybe_execute_file runs so the commands
will be echoed as they are read by the parser. */
begin_unwind_frame ("fc builtin");
add_unwind_protect (unlink, fn);
unwind_protect_int (echo_input_at_read);
echo_input_at_read = 1;
retval = maybe_execute_file (fn);
run_unwind_frame ("fc builtin");
}
return (retval);
}
/* 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 = 1, n;
register int i, j;
register char *s;
/* 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. */
i -= 2;
/* 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;
/* Anything specified greater than the last history element that we
deal with is an error. */
if (n > i + history_base)
return (-1);
/* If the value is negative or zero, then it is an offset from
the current history item. */
if (n <= 0)
return (i + n);
return (n - history_base);
}
for (j = i; j >= 0; j--)
{
if (prefix (command, histline (j)))
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)
return ((char *)NULL);
i = fc_gethnum (command, hlist);
if (i >= 0)
return (savestring (histline (i)));
else
return ((char *)NULL);
}
/* 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);
}
/* 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 = savestring (command);
register REPL *r;
for (r = subs; r; r = r->next)
{
register char *t;
t = fc_replace (r->pat, r->rep, new);
free (new);
new = t;
}
return (new);
}
/* Replace the occurrences of PAT with REP in COMMAND.
This returns a new string; the caller should free it. */
static char *
fc_replace (pat, rep, command)
char *pat, *rep, *command;
{
register int i;
int patlen, replen, templen;
char *new, *temp;
patlen = strlen (pat);
replen = strlen (rep);
temp = savestring (command);
templen = strlen (temp);
i = 0;
for (; (i + patlen) <= templen; i++)
{
if (strncmp (temp + i, pat, patlen) == 0)
{
new = (char *) xmalloc (1 + (replen - patlen) + templen);
strncpy (new, temp, i);
strncpy (new + i, rep, replen);
strncpy (new + i + replen,
temp + i + patlen, templen - (i + patlen));
new[templen + (replen - patlen)] = '\0'; /* just in case */
free (temp);
temp = new;
i += replen;
templen = strlen (temp);
}
}
return (temp);
}
/* 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.
Should this do anything with the history_control variable? */
static void
fc_replhist (command)
char *command;
{
register int i;
HIST_ENTRY **hlist, *histent, *discard, *history_get ();
char *data;
int n;
if (command == NULL || *command == NULL)
return;
hlist = history_list ();
if (hlist == NULL)
return;
for (i = 0; hlist[i]; i++);
i--;
/* History_get () takes a parameter that should be
offset by history_base. */
histent = history_get (history_base + i); /* Don't free this */
if (histent == NULL)
return;
if (histent->data)
data = savestring (histent->data);
else
data = (char *) NULL;
n = strlen (command);
if (command[n - 1] == '\n')
command[n - 1] = '\0';
if (command && *command)
{
discard = replace_history_entry (i, command, data);
if (discard)
{
if (discard->line)
free (discard->line);
free ((char *) discard);
}
}
}
/* Add LINE to the history, after removing a single trailing newline. */
static void
fc_addhist (line)
char *line;
{
register int n = strlen (line);
if (line[n - 1] == '\n')
line[n - 1] = '\0';
if (line && *line)
add_history (line);
}

View File

@@ -0,0 +1,126 @@
This file is fg_bg.def, from which is created fg_bg.c.
It implements the builtins "bg" and "fg" in Bash.
Copyright (C) 1987, 1989, 1991 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 1, 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; see the file COPYING. If not, write to the Free Software
Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
$PRODUCES fg_bg.c
$BUILTIN fg
$FUNCTION fg_builtin
$DEPENDS_ON JOB_CONTROL
$SHORT_DOC fg [job_spec]
Place JOB_SPEC in the foreground, and make it the current job. If
JOB_SPEC is not present, the shell's notion of the current job is
used.
$END
#include <sys/types.h>
#include <signal.h>
#include "../shell.h"
#include "../jobs.h"
extern int job_control;
static int fg_bg ();
/* How to bring a job into the foreground. */
int
fg_builtin (list)
WORD_LIST *list;
{
int fg_bit = 1;
register WORD_LIST *t = list;
if (!job_control)
return (EXECUTION_SUCCESS);
/* If the last arg on the line is '&', then start this job in the
background. Else, fg the job. */
while (t && t->next)
t = t->next;
if (t && strcmp (t->word->word, "&") == 0)
fg_bit = 0;
return (fg_bg (list, fg_bit));
}
$BUILTIN bg
$FUNCTION bg_builtin
$DEPENDS_ON JOB_CONTROL
$SHORT_DOC bg [job_spec]
Place JOB_SPEC in the background, as if it had been started with
`&'. If JOB_SPEC is not present, the shell's notion of the current
job is used.
$END
/* How to put a job into the background. */
int
bg_builtin (list)
WORD_LIST *list;
{
if (!job_control)
return (EXECUTION_SUCCESS);
return (fg_bg (list, 0));
}
/* How to put a job into the foreground/background. */
static int
fg_bg (list, foreground)
WORD_LIST *list;
int foreground;
{
extern char *this_command_name;
sigset_t set, oset;
int job, status = EXECUTION_SUCCESS;
BLOCK_CHILD (set, oset);
job = get_job_spec (list);
if (job < 0 || job >= job_slots || !jobs[job])
{
if (job != DUP_JOB)
builtin_error ("No such job %s", list ? list->word->word : "");
goto failure;
}
/* Or if jobs[job]->pgrp == shell_pgrp. */
if (jobs[job]->job_control == 0)
{
builtin_error ("job %%%d started without job control", job + 1);
goto failure;
}
status = start_job (job, foreground);
if (status >= 0)
{
/* win: */
UNBLOCK_CHILD (oset);
return (status);
}
else
{
failure:
UNBLOCK_CHILD (oset);
return (EXECUTION_FAILURE);
}
}

View File

@@ -0,0 +1,625 @@
/* Getopt for GNU.
Copyright (C) 1987, 1989, 1990, 1991 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 1, 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., 675 Mass Ave, Cambridge, MA 02139, USA. */
#ifdef __STDC__
#define CONST const
#else
#define CONST
#endif
/* This version of `getopt' appears to the caller like standard Unix `getopt'
but it behaves differently for the user, since it allows the user
to intersperse the options with the other arguments.
As `getopt' works, it permutes the elements of `argv' so that,
when it is done, all the options precede everything else. Thus
all application programs are extended to handle flexible argument order.
Setting the environment variable _POSIX_OPTION_ORDER disables permutation.
Then the behavior is completely standard.
GNU application programs can use a third alternative mode in which
they can distinguish the relative order of options and other arguments. */
#include <stdio.h>
/* If compiled with GNU C, use the built-in alloca */
#if defined (__GNUC__)
# define alloca __builtin_alloca
#else /* not __GNUC__ */
# if defined (sparc) || defined (HAVE_ALLOCA_H)
# include <alloca.h>
# else
# if defined (_AIX)
/*#pragma alloca*/
# else
char *alloca ();
# endif /* _AIX */
# endif /* sparc || HAVE_ALLOCA_H */
#endif /* not __GNUC__ */
#if defined(STDC_HEADERS) || defined(__GNU_LIBRARY__)
#include <stdlib.h>
#include <string.h>
#define bcopy(s, d, n) memcpy ((d), (s), (n))
#define index strchr
#else /* STDC_HEADERS or __GNU_LIBRARY__ */
#ifdef USG
#include <string.h>
#define bcopy(s, d, n) memcpy ((d), (s), (n))
#define index strchr
#else /* USG */
#ifdef VMS
#include <string.h>
#else
#include <strings.h>
#endif /* VMS */
/* Declaring bcopy causes errors on systems whose declarations are different.
If the declaration is omitted, everything works fine. rms. */
#endif /* USG */
extern char *getenv ();
extern char *malloc ();
#endif /* STDC_HEADERS or __GNU_LIBRARY__ */
/* For communication from `getopt' to the caller.
When `getopt' finds an option that takes an argument,
the argument value is returned here.
Also, when `ordering' is RETURN_IN_ORDER,
each non-option ARGV-element is returned here. */
char *optarg = 0;
/* Index in ARGV of the next element to be scanned.
This is used for communication to and from the caller
and for communication between successive calls to `getopt'.
On entry to `getopt', zero means this is the first call; initialize.
When `getopt' returns EOF, this is the index of the first of the
non-option elements that the caller should itself scan.
Otherwise, `optind' communicates from one call to the next
how much of ARGV has been scanned so far. */
int optind = 0;
/* The next char to be scanned in the option-element
in which the last option character we returned was found.
This allows us to pick up the scan where we left off.
If this is zero, or a null string, it means resume the scan
by advancing to the next ARGV-element. */
static char *nextchar;
/* Callers store zero here to inhibit the error message
for unrecognized options. */
int opterr = 1;
/* This character is the one the last call to getopt () processed as an
option. */
int optopt = -1;
/* Describe how to deal with options that follow non-option ARGV-elements.
If the caller did not specify anything,
the default is REQUIRE_ORDER if the environment variable
_POSIX_OPTION_ORDER is defined, PERMUTE otherwise.
REQUIRE_ORDER means don't recognize them as options;
stop option processing when the first non-option is seen.
This is what Unix does.
This mode of operation is selected by either setting the environment
variable _POSIX_OPTION_ORDER, or using `+' as the first character
of the list of option characters.
PERMUTE is the default. We permute the contents of ARGV as we scan,
so that eventually all the non-options are at the end. This allows options
to be given in any order, even with programs that were not written to
expect this.
RETURN_IN_ORDER is an option available to programs that were written
to expect options and other ARGV-elements in any order and that care about
the ordering of the two. We describe each non-option ARGV-element
as if it were the argument of an option with character code 1.
Using `-' as the first character of the list of option characters
selects this mode of operation.
The special argument `--' forces an end of option-scanning regardless
of the value of `ordering'. In the case of RETURN_IN_ORDER, only
`--' can cause `getopt' to return EOF with `optind' != ARGC. */
static enum
{
REQUIRE_ORDER, PERMUTE, RETURN_IN_ORDER
} ordering, default_ordering = PERMUTE;
/* Describe the long-named options requested by the application.
_GETOPT_LONG_OPTIONS is a vector of `struct option' terminated by an
element containing a name which is zero.
The field `has_arg' is 1 if the option takes an argument,
2 if it takes an optional argument. */
struct option
{
char *name;
int has_arg;
int *flag;
int val;
};
CONST struct option *_getopt_long_options;
int _getopt_long_only = 0;
/* Index in _GETOPT_LONG_OPTIONS of the long-named option actually found.
Only valid when a long-named option was found. */
int option_index;
/* Handle permutation of arguments. */
/* Describe the part of ARGV that contains non-options that have
been skipped. `first_nonopt' is the index in ARGV of the first of them;
`last_nonopt' is the index after the last of them. */
static int first_nonopt;
static int last_nonopt;
/* Exchange two adjacent subsequences of ARGV.
One subsequence is elements [first_nonopt,last_nonopt)
which contains all the non-options that have been skipped so far.
The other is elements [last_nonopt,optind), which contains all
the options processed since those non-options were skipped.
`first_nonopt' and `last_nonopt' are relocated so that they describe
the new indices of the non-options in ARGV after they are moved. */
static void
exchange (argv)
char **argv;
{
int nonopts_size = (last_nonopt - first_nonopt) * sizeof (char *);
char **temp = (char **) alloca (nonopts_size);
/* Interchange the two blocks of data in ARGV. */
bcopy (&argv[first_nonopt], temp, nonopts_size);
bcopy (&argv[last_nonopt], &argv[first_nonopt],
(optind - last_nonopt) * sizeof (char *));
bcopy (temp, &argv[first_nonopt + optind - last_nonopt], nonopts_size);
/* Update records for the slots the non-options now occupy. */
first_nonopt += (optind - last_nonopt);
last_nonopt = optind;
}
/* Scan elements of ARGV (whose length is ARGC) for option characters
given in OPTSTRING.
If an element of ARGV starts with '-', and is not exactly "-" or "--",
then it is an option element. The characters of this element
(aside from the initial '-') are option characters. If `getopt'
is called repeatedly, it returns successively each of the option characters
from each of the option elements.
If `getopt' finds another option character, it returns that character,
updating `optind' and `nextchar' so that the next call to `getopt' can
resume the scan with the following option character or ARGV-element.
If there are no more option characters, `getopt' returns `EOF'.
Then `optind' is the index in ARGV of the first ARGV-element
that is not an option. (The ARGV-elements have been permuted
so that those that are not options now come last.)
OPTSTRING is a string containing the legitimate option characters.
If an option character is seen that is not listed in OPTSTRING,
return '?' after printing an error message. If you set `opterr' to
zero, the error message is suppressed but we still return '?'.
If a char in OPTSTRING is followed by a colon, that means it wants an arg,
so the following text in the same ARGV-element, or the text of the following
ARGV-element, is returned in `optarg'. Two colons mean an option that
wants an optional arg; if there is text in the current ARGV-element,
it is returned in `optarg', otherwise `optarg' is set to zero.
If OPTSTRING starts with `-' or `+', it requests different methods of
handling the non-option ARGV-elements.
See the comments about RETURN_IN_ORDER and REQUIRE_ORDER, above.
Long-named options begin with `+' instead of `-'.
Their names may be abbreviated as long as the abbreviation is unique
or is an exact match for some defined option. If they have an
argument, it follows the option name in the same ARGV-element, separated
from the option name by a `=', or else the in next ARGV-element.
When `getopt' finds a long-named option, it returns 0 if that option's
`flag' field is nonzero, the value of the option's `val' field
otherwise. */
/* Call this function with an argument of 1 to set the default option
ordering to that required by Posix. The normal default is PERMUTE. */
void
getopt_set_posix_option_order (on_or_off)
int on_or_off;
{
if (on_or_off == 1)
default_ordering = REQUIRE_ORDER;
else
default_ordering = PERMUTE;
}
int
getopt (argc, argv, optstring)
int argc;
char **argv;
CONST char *optstring;
{
optarg = 0;
if (optind > argc || optind < 0)
{
optind = argc;
return (EOF);
}
/* Initialize the internal data when the first call is made.
Start processing options with ARGV-element 1 (since ARGV-element 0
is the program name); the sequence of previously skipped
non-option ARGV-elements is empty. */
if (optind == 0)
{
first_nonopt = last_nonopt = optind = 1;
nextchar = 0;
/* Determine how to handle the ordering of options and nonoptions. */
if (optstring[0] == '-')
{
ordering = RETURN_IN_ORDER;
++optstring;
}
else if (optstring[0] == '+')
{
ordering = REQUIRE_ORDER;
++optstring;
}
else if (getenv ("_POSIX_OPTION_ORDER") != 0)
ordering = REQUIRE_ORDER;
else
ordering = default_ordering;
}
if (nextchar == 0 || *nextchar == 0)
{
if (ordering == PERMUTE)
{
/* If we have just processed some options following some non-options,
exchange them so that the options come first. */
if (first_nonopt != last_nonopt && last_nonopt != optind)
exchange (argv);
else if (last_nonopt != optind)
first_nonopt = optind;
/* Now skip any additional non-options
and extend the range of non-options previously skipped. */
while (optind < argc
&& (argv[optind][0] != '-'
|| argv[optind][1] == 0)
&& (_getopt_long_options == 0
|| argv[optind][0] != '+'
|| argv[optind][1] == 0))
optind++;
last_nonopt = optind;
}
/* Special ARGV-element `--' means premature end of options.
Skip it like a null option,
then exchange with previous non-options as if it were an option,
then skip everything else like a non-option. */
if (optind != argc && !strcmp (argv[optind], "--"))
{
optind++;
if (first_nonopt != last_nonopt && last_nonopt != optind)
exchange (argv);
else if (first_nonopt == last_nonopt)
first_nonopt = optind;
last_nonopt = argc;
optind = argc;
}
/* If we have done all the ARGV-elements, stop the scan
and back over any non-options that we skipped and permuted. */
if (optind == argc)
{
/* Set the next-arg-index to point at the non-options
that we previously skipped, so the caller will digest them. */
if (first_nonopt != last_nonopt)
optind = first_nonopt;
return EOF;
}
/* If we have come to a non-option and did not permute it,
either stop the scan or describe it to the caller and pass it by. */
if ((argv[optind][0] != '-' || argv[optind][1] == 0)
&& (_getopt_long_options == 0
|| argv[optind][0] != '+' || argv[optind][1] == 0))
{
if (ordering == REQUIRE_ORDER)
return EOF;
optarg = argv[optind++];
return 1;
}
/* We have found another option-ARGV-element.
Start decoding its characters. */
nextchar = argv[optind] + 1;
}
if (_getopt_long_options != 0
&& (argv[optind][0] == '+'
|| (_getopt_long_only && argv[optind][0] == '-'))
)
{
CONST struct option *p;
char *s = nextchar;
int exact = 0;
int ambig = 0;
CONST struct option *pfound = 0;
int indfound;
while (*s && *s != '=')
s++;
/* Test all options for either exact match or abbreviated matches. */
for (p = _getopt_long_options, option_index = 0; p->name;
p++, option_index++)
if (!strncmp (p->name, nextchar, s - nextchar))
{
if (s - nextchar == strlen (p->name))
{
/* Exact match found. */
pfound = p;
indfound = option_index;
exact = 1;
break;
}
else if (pfound == 0)
{
/* First nonexact match found. */
pfound = p;
indfound = option_index;
}
else
/* Second nonexact match found. */
ambig = 1;
}
if (ambig && !exact)
{
fprintf (stderr, "%s: option `%s' is ambiguous\n",
argv[0], argv[optind]);
nextchar += strlen (nextchar);
optind++;
return '?';
}
if (pfound != 0)
{
option_index = indfound;
optind++;
if (*s)
{
if (pfound->has_arg > 0)
optarg = s + 1;
else
{
fprintf (stderr,
"%s: option `%c%s' doesn't allow an argument\n",
argv[0], argv[optind - 1][0], pfound->name);
nextchar += strlen (nextchar);
return '?';
}
}
else if (pfound->has_arg == 1)
{
if (optind < argc)
optarg = argv[optind++];
else
{
fprintf (stderr, "%s: option `%s' requires an argument\n",
argv[0], argv[optind - 1]);
nextchar += strlen (nextchar);
return '?';
}
}
nextchar += strlen (nextchar);
if (pfound->flag)
{
*(pfound->flag) = pfound->val;
return 0;
}
return pfound->val;
}
/* Can't find it as a long option. If this is getopt_long_only,
and the option starts with '-' and is a valid short
option, then interpret it as a short option. Otherwise it's
an error. */
if (_getopt_long_only == 0 || argv[optind][0] == '+' ||
index (optstring, *nextchar) == 0)
{
if (opterr != 0)
fprintf (stderr, "%s: unrecognized option `%c%s'\n",
argv[0], argv[optind][0], nextchar);
nextchar += strlen (nextchar);
optind++;
return '?';
}
}
/* Look at and handle the next option-character. */
{
char c = *nextchar++;
char *temp = index (optstring, c);
/* Increment `optind' when we start to process its last character. */
if (*nextchar == 0)
optind++;
optopt = c;
if (temp == 0 || c == ':')
{
if (opterr != 0)
{
if (c < 040 || c >= 0177)
fprintf (stderr, "%s: illegal option -- 0%o\n",
argv[0], c);
else
fprintf (stderr, "%s: illegal option -- %c\n",
argv[0], c);
}
optarg = (char *)NULL;
return '?';
}
if (temp[1] == ':')
{
if (temp[2] == ':')
{
/* This is an option that accepts an argument optionally. */
if (*nextchar != 0)
{
optarg = nextchar;
optind++;
}
else
optarg = 0;
nextchar = 0;
}
else
{
/* This is an option that requires an argument. */
if (*nextchar != 0)
{
optarg = nextchar;
/* If we end this ARGV-element by taking the rest as an arg,
we must advance to the next element now. */
optind++;
}
else if (optind == argc)
{
if (opterr != 0)
fprintf (stderr, "%s: option requires an argument -- %c\n",
argv[0], c);
optarg = "";
c = '?';
}
else
/* We already incremented `optind' once;
increment it again when taking next ARGV-elt as argument. */
optarg = argv[optind++];
nextchar = 0;
}
}
return c;
}
}
#ifdef TEST
/* Compile with -DTEST to make an executable for use in testing
the above definition of `getopt'. */
int
main (argc, argv)
int argc;
char **argv;
{
int c;
int digit_optind = 0;
while (1)
{
int this_option_optind = optind ? optind : 1;
c = getopt (argc, argv, "abc:d:0123456789");
if (c == EOF)
break;
switch (c)
{
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
if (digit_optind != 0 && digit_optind != this_option_optind)
printf ("digits occur in two different argv-elements.\n");
digit_optind = this_option_optind;
printf ("option %c\n", c);
break;
case 'a':
printf ("option a\n");
break;
case 'b':
printf ("option b\n");
break;
case 'c':
printf ("option c with value `%s'\n", optarg);
break;
case '?':
break;
default:
printf ("?? getopt returned character code 0%o ??\n", c);
}
}
if (optind < argc)
{
printf ("non-option ARGV-elements: ");
while (optind < argc)
printf ("%s ", argv[optind++]);
printf ("\n");
}
exit (0);
}
#endif /* TEST */

View File

@@ -0,0 +1,108 @@
/* declarations for getopt
Copyright (C) 1989, 1990, 1991 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 1, 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., 675 Mass Ave, Cambridge, MA 02139, USA. */
/* For communication from `getopt' to the caller.
When `getopt' finds an option that takes an argument,
the argument value is returned here.
Also, when `ordering' is RETURN_IN_ORDER,
each non-option ARGV-element is returned here. */
extern char *optarg;
/* Index in ARGV of the next element to be scanned.
This is used for communication to and from the caller
and for communication between successive calls to `getopt'.
On entry to `getopt', zero means this is the first call; initialize.
When `getopt' returns EOF, this is the index of the first of the
non-option elements that the caller should itself scan.
Otherwise, `optind' communicates from one call to the next
how much of ARGV has been scanned so far. */
extern int optind;
/* Callers store zero here to inhibit the error message `getopt' prints
for unrecognized options. */
extern int opterr;
/* getopt () stores the last character processed as an option here just
before returning. */
extern int optopt;
/* Describe the long-named options requested by the application.
_GETOPT_LONG_OPTIONS is a vector of `struct option' terminated by an
element containing a name which is zero.
The field `has_arg' is:
0 if the option does not take an argument,
1 if the option requires an argument,
2 if the option takes an optional argument.
If the field `flag' is nonzero, it points to a variable that is set
to the value given in the field `val' when the option is found, but
left unchanged if the option is not found.
To have a long-named option do something other than set an `int' to
a compiled-in constant, such as set a value from `optarg', set the
option's `flag' field to zero and its `val' field to a nonzero
value (the equivalent single-letter option character, if there is
one). For long options that have a zero `flag' field, `getopt'
returns the contents of the `val' field. */
struct option
{
char *name;
int has_arg;
int *flag;
int val;
};
#ifdef __STDC__
extern const struct option *_getopt_long_options;
#else
extern struct option *_getopt_long_options;
#endif
/* If nonzero, '-' can introduce long-named options.
Set by getopt_long_only. */
extern int _getopt_long_only;
/* The index in GETOPT_LONG_OPTIONS of the long-named option found.
Only valid when a long-named option has been found by the most
recent call to `getopt'. */
extern int option_index;
#ifdef __STDC__
int getopt (int argc, char **argv, const char *shortopts);
int getopt_long (int argc, char **argv, const char *shortopts,
const struct option *longopts, int *longind);
int getopt_long_only (int argc, char **argv, const char *shortopts,
const struct option *longopts, int *longind);
void getopt_set_posix_option_order (int on_or_off);
void envopt(int *pargc, char ***pargv, char *optstr);
#else
int getopt ();
int getopt_long ();
int getopt_long_only ();
void getopt_set_posix_option_order ();
void envopt();
#endif

View File

@@ -0,0 +1,272 @@
This file is getopts.def, from which is created getopts.c.
It implements the builtin "getopts" in Bash.
Copyright (C) 1987, 1989, 1991 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 1, 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; see the file COPYING. If not, write to the Free Software
Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
$PRODUCES getopts.c
$BUILTIN getopts
$DEPENDS_ON GETOPTS_BUILTIN
$FUNCTION getopts_builtin
$SHORT_DOC getopts optstring name [arg]
Getopts is used by shell procedures to parse positional parameters.
OPTSTRING contains the option letters to be recognized; if a letter
is followed by a colon, the option is expected to have an argument,
which should be separated from it by white space.
Each time it is invoked, getopts will place the next option in the
shell variable $name, initializing name if it does not exist, and
the index of the next argument to be processed into the shell
variable OPTIND. OPTIND is initialized to 1 each time the shell or
a shell script is invoked. When an option requires an argument,
getopts places that argument into the shell variable OPTARG.
getopts reports errors in one of two ways. If the first character
of OPTSTRING is a colon, getopts uses silent error reporting. In
this mode, no error messages are printed. If an illegal option is
seen, getopts places the option character found into OPTARG. If a
required argument is not found, getopts places a ':' into NAME and
sets OPTARG to the option character found. If getopts is not in
silent mode, and an illegal option is seen, getopts places '?' into
NAME and unsets OPTARG. If a required option is not found, a '?'
is placed in NAME, OPTARG is unset, and a diagnostic message is
printed.
If the shell variable OPTERR has the value 0, getopts disables the
printing of error messages, even if the first character of
OPTSTRING is not a colon. OPTERR has the value 1 by default.
Getopts normally parses the positional parameters ($0 - $9), but if
more arguments are given, they are parsed instead.
$END
#include <stdio.h>
#include "../shell.h"
#include "getopt.h"
#ifndef NULL
#define NULL 0
#endif
#define G_EOF (-1)
#define G_ILLEGAL_OPT (-2)
#define G_ARG_MISSING (-3)
extern char *this_command_name;
/* getopts_reset is magic code for when OPTIND is reset. N is the
value that has just been assigned to OPTIND. */
void
getopts_reset (newind)
int newind;
{
optind = newind;
}
/* Error handling is now performed as specified by Posix.2, draft 11
(identical to that of ksh-88). The special handling is enabled if
the first character of the option string is a colon; this handling
disables diagnostic messages concerning missing option arguments
and illegal option characters. The handling is as follows.
ILLEGAL OPTIONS:
name -> "?"
if (special_error) then
OPTARG = option character found
no error output
else
OPTARG unset
diagnostic message
fi
MISSING OPTION ARGUMENT;
if (special_error) then
name -> ":"
OPTARG = option character found
else
name -> "?"
OPTARG unset
diagnostic message
fi
*/
static int
dogetopts (argc, argv)
int argc;
char **argv;
{
int ret, special_error, old_opterr = 0;
char strval[2];
char *optstr; /* list of options */
char *name; /* variable to get flag val */
char *t;
if (argc < 3)
{
builtin_error("3 arguments expected");
return (EXECUTION_FAILURE);
}
/* argv[0] is "getopts". */
optstr = argv[1];
name = argv[2];
argc -= 2;
argv += 2;
special_error = optstr[0] == ':';
if (special_error)
{
old_opterr = opterr;
optstr++;
opterr = 0; /* suppress diagnostic messages */
}
if (argc > 1)
{
t = argv[0];
argv[0] = dollar_vars[0];
ret = getopt(argc, argv, optstr);
argv[0] = t;
}
else
{
register int i;
for (i = 0; dollar_vars[i]; i++);
ret = getopt (i, dollar_vars, optstr);
}
if (special_error)
opterr = old_opterr;
/* Set the OPTIND variable in any case, to handle "--" skipping. */
{
char numval[16];
sprintf (numval, "%d", optind);
bind_variable ("OPTIND", numval);
}
/* If an error occurred, decide which one it is and set the return
code appropriately. In all cases, the option character in error
is in OPTOPT. If an illegal option was encountered, OPTARG is
NULL. If a required option argument was missing, OPTARG points
to a NULL string (that is, optarg[0] == 0). */
if (ret == '?')
{
if (optarg == NULL)
ret = G_ILLEGAL_OPT;
else if (optarg[0] == '\0')
ret = G_ARG_MISSING;
}
if (ret == G_EOF)
{
bind_variable (name, "?");
return (EXECUTION_FAILURE);
}
if (ret == G_ILLEGAL_OPT)
{
/* Illegal option encountered. */
strval[0] = '?';
strval[1] = '\0';
bind_variable (name, strval);
if (special_error)
{
strval[0] = (char) optopt;
strval[1] = '\0';
bind_variable ("OPTARG", strval);
}
else
makunbound ("OPTARG", shell_variables);
return (EXECUTION_SUCCESS);
}
if (ret == G_ARG_MISSING)
{
/* Required argument missing. */
if (special_error)
{
strval[0] = ':';
strval[1] = '\0';
bind_variable (name, strval);
strval[0] = (char) optopt;
strval[1] = '\0';
bind_variable ("OPTARG", strval);
}
else
{
strval[0] = '?';
strval[1] = '\0';
bind_variable (name, strval);
makunbound ("OPTARG", shell_variables);
}
return (EXECUTION_SUCCESS);
}
bind_variable ("OPTARG", optarg);
strval[0] = (char) ret;
strval[1] = '\0';
bind_variable (name, strval);
return (EXECUTION_SUCCESS);
}
/* The getopts builtin. Build an argv, and call dogetopts with it. */
int
getopts_builtin (list)
WORD_LIST *list;
{
register int i;
char **av;
int ac, ret;
WORD_LIST *t = list;
static int order_set = 0;
if (!list)
return EXECUTION_FAILURE;
for (ac = 0; t; t = t->next, ac++);
ac++;
av = (char **)xmalloc ((1 + ac) * sizeof (char *));
av[ac] = (char *) NULL;
av[0] = savestring (this_command_name);
for (t = list, i = 1; t; t = t->next, i++)
av[i] = savestring (t->word->word);
if (order_set == 0)
{
getopt_set_posix_option_order (1);
order_set++;
}
ret = dogetopts (ac, av);
free_array (av);
return (ret);
}

View File

@@ -0,0 +1,207 @@
This file is hash.def, from which is created hash.c.
It implements the builtin "hash" in Bash.
Copyright (C) 1987, 1989, 1991 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 1, 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; see the file COPYING. If not, write to the Free Software
Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
$PRODUCES hash.c
$BUILTIN hash
$FUNCTION hash_builtin
$SHORT_DOC hash [-r] [name ...]
For each NAME, the full pathname of the command is determined and
remembered. The -r option causes the shell to forget all remembered
locations. If no arguments are given, information about remembered
commands is presented.
$END
#include <stdio.h>
#include "../shell.h"
#include "../builtins.h"
#include "../flags.h"
#include "hashcom.h"
void remember_filename ();
void
initialize_filename_hashing ()
{
hashed_filenames = make_hash_table (FILENAME_HASH_BUCKETS);
}
/* 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. */
hash_builtin (list)
WORD_LIST *list;
{
int expunge_hash_table = 0;
int any_failed = 0;
if (hashing_disabled)
{
builtin_error ("Hashing is disabled");
return (EXECUTION_FAILURE);
}
while (list)
{
if (strcmp (list->word->word, "-r") == 0)
{
expunge_hash_table = 1;
list = list->next;
}
else if (strcmp (list->word->word, "--") == 0)
{
list = list->next;
break;
}
else if (*list->word->word == '-')
{
bad_option (list->word->word);
return (EXECUTION_FAILURE);
}
else
break;
}
/* We want hash -r to be silent, but hash -- to print hashing info. That
is the reason for the !expunge_hash_table. */
if (!list && !expunge_hash_table)
{
/* Print information about current hashed info. */
int any_printed = 0;
int bucket = 0;
register BUCKET_CONTENTS *item_list;
while (bucket < hashed_filenames->nbuckets)
{
item_list = get_hash_bucket (bucket, hashed_filenames);
if (item_list)
{
if (!any_printed)
{
printf ("hits\tcommand\n");
any_printed++;
}
while (item_list)
{
printf ("%4d\t%s\n",
item_list->times_found, pathdata(item_list)->path);
item_list = item_list->next;
}
}
bucket++;
}
if (!any_printed)
printf ("No commands in hash table.\n");
return (EXECUTION_SUCCESS);
}
if (expunge_hash_table)
{
int bucket = 0;
register BUCKET_CONTENTS *item_list, *prev;
while (bucket < hashed_filenames->nbuckets)
{
item_list = get_hash_bucket (bucket, hashed_filenames);
if (item_list)
{
while (item_list)
{
prev = item_list;
free (item_list->key);
free (pathdata(item_list)->path);
free (item_list->data);
item_list = item_list->next;
free (prev);
}
hashed_filenames->bucket_array[bucket] = (BUCKET_CONTENTS *)NULL;
}
bucket++;
}
}
while (list)
{
/* Add or rehash the specified commands. */
extern Function *find_shell_builtin ();
extern char *find_user_command ();
char *word;
char *full_path;
SHELL_VAR *var;
word = list->word->word;
if (absolute_program (word))
{
list = list->next;
continue;
}
full_path = find_user_command (word);
var = find_function (word);
if (!find_shell_builtin (word) && (!var))
{
if (full_path && executable_file (full_path))
{
extern int dot_found_in_search;
remember_filename (word, full_path, dot_found_in_search);
}
else
{
builtin_error ("%s: not found", word);
any_failed++;
}
}
list = list->next;
}
fflush (stdout);
if (any_failed)
return (EXECUTION_FAILURE);
else
return (EXECUTION_SUCCESS);
}
/* Place FILENAME (key) and FULL_PATHNAME (data->path) into the
hash table. CHECK_DOT if non-null is for future calls to
find_hashed_filename (). */
void
remember_filename (filename, full_pathname, check_dot)
char *filename, *full_pathname;
int check_dot;
{
register BUCKET_CONTENTS *item;
if (hashing_disabled)
return;
item = add_hash_item (filename, hashed_filenames);
if (item->data)
free (pathdata(item)->path);
else
item->data = (char *)xmalloc (sizeof (PATH_DATA));
item->key = savestring (filename);
pathdata(item)->path = savestring (full_pathname);
pathdata(item)->check_dot = check_dot;
item->times_found = 0;
}

View File

@@ -0,0 +1,13 @@
/* hashcom.h - Common defines for hashing filenames. */
#include "../hash.h"
#define FILENAME_HASH_BUCKETS 631
HASH_TABLE *hashed_filenames;
typedef struct {
char *path; /* The full pathname of the file. */
int check_dot; /* Whether `.' appeared before this one in $PATH. */
} PATH_DATA;
#define pathdata(x) ((PATH_DATA *)(x)->data)

View File

@@ -0,0 +1,134 @@
This file is help.def, from which is created help.c.
It implements the builtin "help" in Bash.
Copyright (C) 1987, 1989, 1991 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 1, 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; see the file COPYING. If not, write to the Free Software
Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
$PRODUCES help.c
$BUILTIN help
$FUNCTION help_builtin
$SHORT_DOC help [pattern ...]
Display helpful information about builtin commands. If PATTERN is
specified, gives detailed help on all commands matching PATTERN,
otherwise a list of the builtins is printed.
$END
#include <stdio.h>
#include "../shell.h"
#include "../builtins.h"
#if defined (USE_GLOB_LIBRARY)
# include <glob/glob.h>
#else
# define FNM_NOMATCH 1
#endif /* USE_GLOB_LIBRARY */
/* Print out a list of the known functions in the shell, and what they do.
If LIST is supplied, print out the list which matches for each pattern
specified. */
help_builtin (list)
WORD_LIST *list;
{
if (!list)
{
register int i, j;
char blurb[256];
show_shell_version ();
printf (
"Shell commands that are defined internally. Type `help' to see this list.\n\
Type `help name' to find out more about the function `name'.\n\
Use `info bash' to find out more about the shell in general.\n\
\n\
A star (*) next to a name means that the command is disabled.\n\
\n");
for (i = 0; i < num_shell_builtins; i++)
{
QUIT;
sprintf (blurb, "%c%s", shell_builtins[i].enabled ? ' ' : '*',
shell_builtins[i].short_doc);
blurb[35] = '\0';
printf ("%s", blurb);
if (i % 2)
printf ("\n");
else
for (j = strlen (blurb); j < 35; j++)
putc (' ', stdout);
}
if (i % 2)
printf ("\n");
}
else
{
int match_found = 0;
char *pattern = "";
if (glob_pattern_p (list->word->word))
{
printf ("Shell commands matching keyword%s `",
list->next ? "s" : "");
print_word_list (list, ", ");
printf ("'\n\n");
}
while (list)
{
register int i = 0, plen;
char *name;
pattern = list->word->word;
plen = strlen (pattern);
while (name = shell_builtins[i].name)
{
int doc_index;
QUIT;
if ((strnicmp (pattern, name, plen) == 0) ||
(fnmatch (pattern, name, 0) != FNM_NOMATCH))
{
printf ("%s: %s\n", name, shell_builtins[i].short_doc);
for (doc_index = 0;
shell_builtins[i].long_doc[doc_index]; doc_index++)
printf (" %s\n", shell_builtins[i].long_doc[doc_index]);
match_found++;
}
i++;
}
list = list->next;
}
if (!match_found)
{
fprintf (stderr, "No help topics match `%s'. Try `help help'.\n",
pattern);
fflush (stderr);
return (EXECUTION_FAILURE);
}
}
fflush (stdout);
return (EXECUTION_SUCCESS);
}

View File

@@ -0,0 +1,180 @@
This file is history.def, from which is created history.c.
It implements the builtin "history" in Bash.
Copyright (C) 1987, 1989, 1991 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 1, 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; see the file COPYING. If not, write to the Free Software
Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
$PRODUCES history.c
$BUILTIN history
$FUNCTION history_builtin
$SHORT_DOC history [n] [ [-awrn] [filename]]
Display the history list with line numbers. Lines listed with
with a `*' have been modified. Argument of N says to list only
the last N lines. Argument `-w' means to write out the current
history file; `-r' means to read it instead. Argument `-a' means
to append history lines from this session to the history file.
Argument `-n' means to read all history lines not already read
from the history file. If FILENAME is given, then use that file,
else if $HISTFILE has a value, use that, else use ~/.bash_history.
$END
#include "../shell.h"
#include <sys/types.h>
#include <sys/file.h>
#include "../filecntl.h"
#include "../posixstat.h"
#include <readline/history.h>
/* History. Arg of -w FILENAME means write file, arg of -r FILENAME
means read file. Arg of N means only display that many items. */
history_builtin (list)
WORD_LIST *list;
{
register int i;
int limited = 0, limit = 0;
HIST_ENTRY **hlist;
while (list)
{
char *arg = list->word->word;
if ((arg[0] == '-') &&
(strlen (arg) == 2) &&
(member (arg[1], "rwan")))
{
char *file;
int result = EXECUTION_SUCCESS;
if (list->next)
file = list->next->word->word;
else
file = get_string_value ("HISTFILE");
switch (arg[1])
{
case 'a': /* Append `new' lines to file. */
{
extern int history_lines_this_session;
extern int history_lines_in_file;
if (history_lines_this_session)
{
void using_history ();
if (history_lines_this_session < where_history ())
{
/* If the filename was supplied, then create it
if it doesn't already exist. */
if (file)
{
struct stat buf;
if (stat (file, &buf) == -1)
{
int tem;
tem = open (file, O_CREAT, 0666);
close (tem);
}
}
result =
append_history (history_lines_this_session, file);
history_lines_in_file += history_lines_this_session;
history_lines_this_session = 0;
}
}
break;
}
case 'w': /* Write entire history. */
{
result = write_history (file);
break;
}
case 'r': /* Read entire file. */
{
result = read_history (file);
break;
}
case 'n': /* Read `new' history from file. */
{
extern int history_lines_in_file;
/* Read all of the lines in the file that we haven't
already read. */
using_history ();
result =
read_history_range (file, history_lines_in_file, -1);
using_history ();
history_lines_in_file = where_history ();
break;
}
}
return (result ? EXECUTION_FAILURE : EXECUTION_SUCCESS);
}
else if (strcmp (list->word->word, "--") == 0)
{
list = list->next;
break;
}
else if (*list->word->word == '-')
{
bad_option (list->word->word);
return (EXECUTION_FAILURE);
}
else
break;
}
if (list)
{
limited = 1;
limit = get_numeric_arg (list);
}
hlist = history_list ();
if (hlist)
{
for (i = 0; hlist[i]; i++);
if (limit < 0)
limit = -limit;
if (!limited)
i = 0;
else
if ((i -= limit) < 0)
i = 0;
while (hlist[i])
{
QUIT;
printf ("%5d%c %s\n", i + history_base,
hlist[i]->data ? '*' : ' ', hlist[i]->line);
i++;
}
}
return (EXECUTION_SUCCESS);
}

View File

@@ -0,0 +1,169 @@
This file is jobs.def, from which is created jobs.c.
It implements the builtin "jobs" in Bash.
Copyright (C) 1987, 1989, 1991 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 1, 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; see the file COPYING. If not, write to the Free Software
Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
$PRODUCES jobs.c
$BUILTIN jobs
$FUNCTION jobs_builtin
$DEPENDS_ON JOB_CONTROL
$SHORT_DOC jobs [-lnp] [jobspec ...] | jobs -x command [args]
Lists the active jobs. The -l option lists process id's in addition
to the normal information; the -p option lists process id's only.
If -n is given, only processes that have changed status since the last
notification are printed. JOBSPEC restricts output to that job.
If -x is given, COMMAND is run after all job specifications that appear
in ARGS have been replaced with the process ID of that job's process group
leader.
$END
#include "../shell.h"
#if defined (JOB_CONTROL)
#include <sys/types.h>
#include <signal.h>
#include "../jobs.h"
extern int job_control;
static int execute_list_with_replacements ();
/* The `jobs' command. Prints outs a list of active jobs. If the
argument `-l' is given, then the process id's are printed also.
If the argument `-p' is given, print the process group leader's
pid only. If `-n' is given, only processes that have changed
status since the last notification are printed. If -x is given,
replace all job specs with the pid of the appropriate process
group leader and execute the command. */
int
jobs_builtin (list)
WORD_LIST *list;
{
int form = JLIST_STANDARD;
if (!job_control)
return (EXECUTION_SUCCESS);
while (list && (*list->word->word == '-'))
{
register char *arg = list->word->word;
if (strcmp (arg, "-l") == 0)
form = JLIST_LONG;
else if (strcmp (arg, "-p") == 0)
form = JLIST_PID_ONLY;
else if (strcmp (arg, "-n") == 0)
form = JLIST_CHANGED_ONLY;
else if (strcmp (arg, "-x") == 0)
{
if (form != JLIST_STANDARD)
{
builtin_error ("Other options not allowed with `-x'");
return (EXECUTION_FAILURE);
}
list = list->next;
return (execute_list_with_replacements (list));
}
else if (strcmp (arg, "--") == 0)
{
list = list->next;
break;
}
else
{
bad_option (list->word->word);
return (EXECUTION_FAILURE);
}
list = list->next;
}
if (!list)
{
list_jobs (form);
return (EXECUTION_SUCCESS);
}
while (list)
{
int job;
sigset_t set, oset;
BLOCK_CHILD (set, oset);
job = get_job_spec (list);
if ((job == NO_JOB) || !jobs || !jobs[job])
builtin_error ("No such job %s", list->word->word);
else if (job != DUP_JOB)
list_one_job ((JOB *)NULL, form, 0, job);
UNBLOCK_CHILD (oset);
list = list->next;
}
return (EXECUTION_SUCCESS);
}
static int
execute_list_with_replacements (list)
WORD_LIST *list;
{
register WORD_LIST *l;
int job, result;
/* First do the replacement of job specifications with pids. */
for (l = list; l; l = l->next)
{
if (l->word->word[0] == '%') /* we have a winner */
{
extern char *itos ();
job = get_job_spec (l);
/* A bad job spec is not really a job spec! Pass it through. */
if (job < 0 || job >= job_slots || !jobs[job])
continue;
free (l->word->word);
l->word->word = itos (jobs[job]->pgrp);
}
}
/* Next make a new simple command and execute it. */
begin_unwind_frame ("jobs_builtin");
{
extern COMMAND *make_bare_simple_command ();
extern WORD_LIST *copy_word_list ();
extern void dispose_command ();
COMMAND *command = (COMMAND *)NULL;
add_unwind_protect (dispose_command, command);
command = make_bare_simple_command ();
command->value.Simple->words = copy_word_list (list);
command->value.Simple->redirects = (REDIRECT *)NULL;
command->flags |= CMD_INHIBIT_EXPANSION;
command->value.Simple->flags |= CMD_INHIBIT_EXPANSION;
result = execute_command (command);
}
run_unwind_frame ("jobs_builtin");
return (result);
}
#endif /* JOB_CONTROL */

View File

@@ -0,0 +1,262 @@
This file is kill.def, from which is created kill.c.
It implements the builtin "kill" in Bash.
Copyright (C) 1987, 1989, 1991 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 1, 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; see the file COPYING. If not, write to the Free Software
Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
$PRODUCES kill.c
$BUILTIN kill
$FUNCTION kill_builtin
$DEPENDS_ON JOB_CONTROL
$SHORT_DOC kill [-s sigspec | -sigspec] [pid | job]... | -l [signum]
Send the processes named by PID (or JOB) the signal SIGSPEC. If
SIGSPEC is not present, then SIGTERM is assumed. An argument of `-l'
lists the signal names; if arguments follow `-l' they are assumed to
be signal numbers for which names should be listed. Kill is a builtin
for two reasons: it allows job ID's to be used instead of pids, and if
you run out of processes, you can still kill them.
$END
#include <sys/types.h>
#include <errno.h>
extern int errno;
#include "../shell.h"
#include "../trap.h"
#include "../jobs.h"
#if defined (JOB_CONTROL)
extern int job_control;
#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 signal = SIGTERM;
int any_succeeded = 0, listing = 0, saw_signal = 0;
char *sigspec;
pid_t pid;
if (!list)
return (EXECUTION_SUCCESS);
/* Process options. */
while (list)
{
if (strcmp (list->word->word, "-l") == 0)
{
listing++;
list = list->next;
}
else if (strcmp (list->word->word, "-s") == 0)
{
list = list->next;
if (list)
{
sigspec = list->word->word;
if (strcmp (sigspec, "0") == 0)
signal = 0;
else
signal = decode_signal (sigspec);
list = list->next;
}
else
{
builtin_error ("-s requires an argument");
return (EXECUTION_FAILURE);
}
}
else if (strcmp (list->word->word, "--") == 0)
{
list = list->next;
break;
}
/* 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 ((*(list->word->word) == '-') && !saw_signal)
{
sigspec = &(list->word->word)[1];
signal = decode_signal (sigspec);
saw_signal++;
list = list->next;
}
else
break;
}
if (listing)
{
if (!list)
{
register int i, column = 0;
for (i = 1; i < NSIG; i++)
{
char *name = signal_name (i);
if ((strncmp (name, "SIGJUNK", 7) == 0) ||
(strncmp (name, "Unknown", 7) == 0))
continue;
printf ("%2d) %s", i, name);
if (++column < 4)
printf ("\t");
else
{
printf ("\n");
column = 0;
}
}
if (column != 0)
printf ("\n");
}
else
{
/* List individual signal names. */
while (list)
{
int signum;
char *name;
if ((sscanf (list->word->word, "%d", &signum) != 1) ||
(signum <= 0))
{
list_error:
builtin_error ("bad signal number: %s", list->word->word);
list = list->next;
continue;
}
/* This is specified by Posix.2 so that exit statuses can be
mapped into signal numbers. */
if (signum > 128)
signum -= 128;
if (signum > NSIG)
goto list_error;
name = signal_name (signum);
if ((strncmp (name, "SIGJUNK", 7) == 0) ||
(strncmp (name, "Unknown", 7) == 0))
{
list = list->next;
continue;
}
printf ("%s\n", name);
list = list->next;
}
}
return (EXECUTION_SUCCESS);
}
/* OK, we are killing processes. */
if (signal == NO_SIG)
{
builtin_error ("bad signal spec `%s'", sigspec);
return (EXECUTION_FAILURE);
}
while (list)
{
char *word = list->word->word;
if (*word == '-')
word++;
if (all_digits (word))
{
/* Use the entire argument in case of minus sign presence. */
pid = (pid_t) atoi (list->word->word);
if (kill_pid (pid, signal, 0) < 0)
goto signal_error;
else
any_succeeded++;
}
else if (*list->word->word != '%')
{
builtin_error ("No such pid %s", list->word->word);
CONTINUE_OR_FAIL;
}
else if (job_control) /* can't kill jobs if not using job control */
{ /* Must be a job spec. Check it out. */
int job;
sigset_t set, oset;
BLOCK_CHILD (set, oset);
job = get_job_spec (list);
if (job < 0 || job >= job_slots || !jobs[job])
{
if (job != DUP_JOB)
builtin_error ("No such job %s", list->word->word);
UNBLOCK_CHILD (oset);
CONTINUE_OR_FAIL;
}
/* 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. */
if (jobs[job]->job_control)
pid = jobs[job]->pgrp;
else
pid = jobs[job]->pipe->pid;
UNBLOCK_CHILD (oset);
if (kill_pid (pid, signal, 1) < 0)
{
signal_error:
if (errno == EPERM)
builtin_error ("(%d) - Not owner", (int)pid);
else if (errno == ESRCH)
builtin_error ("(%d) - No such pid", (int)pid);
else
builtin_error ("Invalid signal %d", signal);
CONTINUE_OR_FAIL;
}
else
any_succeeded++;
}
else
{
builtin_error ("bad process specification `%s'", list->word->word);
CONTINUE_OR_FAIL;
}
continue_killing:
list = list->next;
}
if (any_succeeded)
return (EXECUTION_SUCCESS);
else
return (EXECUTION_FAILURE);
}
#endif /* JOB_CONTROL */

View File

@@ -0,0 +1,78 @@
This file is let.def, from which is created let.c.
It implements the builtin "let" in Bash.
Copyright (C) 1987, 1989, 1991 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 1, 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; see the file COPYING. If not, write to the Free Software
Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
$BUILTIN let
$FUNCTION let_builtin
$PRODUCES let.c
$SHORT_DOC let arg [arg ...]
Each ARG is an arithmetic expression to be evaluated. Evaluation
is done in long integers with no check for overflow, though division
by 0 is trapped and flagged as an error. The following list of
operators is grouped into levels of equal-precedence operators.
The levels are listed in order of decreasing precedence.
- unary minus
! logical NOT
* / % multiplication, division, remainder
+ - addition, subtraction
<= >= < > comparison
== != equality inequality
= assignment
Shell variables are allowed as operands. The name of the variable
is replaced by its value (coerced to a long integer) within
an expression. The variable need not have its integer attribute
turned on to be used in an expression.
Operators are evaluated in order of precedence. Sub-expressions in
parentheses are evaluated first and may override the precedence
rules above.
If the last ARG evaluates to 0, let returns 1; 0 is returned
otherwise.
$END
#include "../shell.h"
/* Arithmetic LET function. */
let_builtin (list)
WORD_LIST *list;
{
long ret = 0L;
extern long evalexp ();
if (!list)
{
builtin_error ("argument (expression) expected");
return (EXECUTION_FAILURE);
}
while (list)
{
ret = evalexp (list->word->word);
list = list->next;
}
if (ret == 0L)
return (EXECUTION_FAILURE);
else
return (EXECUTION_SUCCESS);
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,74 @@
/* psize.c - Find pipe size. */
/* Copyright (C) 1987, 1991 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 1, 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; see the file COPYING. If not, write to the Free
Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
/* Write output in 128-byte chunks until we get a sigpipe or write gets an
EPIPE. Then report how many bytes we wrote. We assume that this is the
pipe size. */
#include <stdio.h>
#include <sys/types.h>
#include <signal.h>
#include <errno.h>
#include "../general.h"
extern int errno;
int nw;
sighandler
sigpipe (sig)
int sig;
{
fprintf (stderr, "%d\n", nw);
exit (0);
}
#if !defined (NeXT)
char *
memset (s, c, n)
register char *s;
register int c, n;
{
register char *p = s;
while (--n >= 0)
*s++ = c;
return (p);
}
#endif /* !NeXT */
main (argc, argv)
int argc;
char **argv;
{
char buf[128];
memset (buf, ' ', 128);
signal (SIGPIPE, sigpipe);
nw = 0;
for (;;)
{
int n;
n = write (1, buf, 128);
nw += n;
}
}

View File

@@ -0,0 +1,20 @@
#! /bin/sh
#
# psize.sh -- determine this system's pipe size, and write a define to
# pipesize.h so ulimit.c can use it.
echo "/*"
echo " * pipesize.h"
echo " *"
echo " * This file is automatically generated by psize.sh"
echo " * Do not edit!"
echo " */"
echo ""
./psize.aux 2>/tmp/pipesize | sleep 3
echo "#define PIPESIZE `cat /tmp/pipesize`"
rm -f /tmp/pipesize
exit 0

View File

@@ -0,0 +1,197 @@
This file is read.def, from which is created read.c.
It implements the builtin "read" in Bash.
Copyright (C) 1987, 1989, 1991 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 1, 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; see the file COPYING. If not, write to the Free Software
Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
$PRODUCES read.c
$BUILTIN read
$FUNCTION read_builtin
$SHORT_DOC read [-r] [name ...]
One line is read from the standard input, and the first word is
assigned to the first NAME, the second word to the second NAME, etc.
with leftover words assigned to the last NAME. Only the characters
found in $IFS are recognized as word delimiters. The return code is
zero, unless end-of-file is encountered. If the -r option is given, a
backslash-newline pair (\\n) is not ignored, and the backslash is
considered to be part of the line.
$END
#include <stdio.h>
#include "../shell.h"
static int stream_close ();
/* 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.
S. R. Bourne's shell complains if you don't name a variable
to receive the stuff that is read. GNU's shell doesn't. This
allows you to let the user type random things. */
read_builtin (list)
WORD_LIST *list;
{
extern int interrupt_immediately, free ();
extern SHELL_VAR *bind_variable ();
register char *varname;
int size, c, i = 0, fildes, ignore_backslash_nl = 1;
char *input_string, *ifs_chars;
WORD_LIST *words, *rwords, *list_string ();
extern char *string_list_dollar_star ();
FILE *input_stream;
ifs_chars = get_string_value ("IFS");
input_string = (char *)xmalloc (size = 128);
/* We need unbuffered input from stdin. So we make a new
unbuffered stream with the same file descriptor, then
unbuffer that one. */
fildes = dup (fileno (stdin));
if (fildes == -1)
return (EXECUTION_FAILURE);
input_stream = fdopen (fildes, "r");
if (!input_stream)
{
close (fildes);
return (EXECUTION_FAILURE);
}
setbuf (input_stream, (char *)NULL);
{
begin_unwind_frame ("read_builtin");
add_unwind_protect (free, input_string);
add_unwind_protect (stream_close, input_stream);
interrupt_immediately++;
}
while (list)
{
if (strcmp (list->word->word, "-r") == 0)
{
ignore_backslash_nl = 0;
list = list->next;
}
else if (strcmp (list->word->word, "--") == 0)
{
list = list->next;
break;
}
else if (*list->word->word == '-')
{
bad_option (list->word->word);
return (EXECUTION_FAILURE);
}
else
break;
}
while ((c = getc (input_stream)) != EOF)
{
if (i + 1 >= size)
input_string = (char *)xrealloc (input_string, size += 128);
input_string[i++] = c;
if (c == '\n')
{
if (ignore_backslash_nl &&
(i >= 2) && (input_string[i - 2] == '\\'))
{
i -= 2;
continue;
}
/* Both ksh and the s5r3 sh chop off the trailing newline. */
i--;
break;
}
}
input_string[i] = '\0';
interrupt_immediately--;
discard_unwind_frame ("read_builtin");
fclose (input_stream);
if (c == EOF)
return (EXECUTION_FAILURE);
if (!list)
{
SHELL_VAR *var;
var = bind_variable ("REPLY", input_string);
var->attributes &= ~att_invisible;
free (input_string);
}
else
{
words = list_string (input_string, ifs_chars, 0);
rwords = words;
free (input_string);
while (list)
{
SHELL_VAR *var;
varname = list->word->word;
if (!list->next)
{
/* Call string_list_dollar_star because P1003.2.9 specifies
that the intervening separators are preserved in the
result of a read that specifies fewer variables than words
read. */
char *t = words ? string_list_dollar_star (words) : "";
var = bind_variable (varname, t);
}
else
var = bind_variable (varname, words ? words->word->word : "");
stupidly_hack_special_variables (varname);
var->attributes &= ~att_invisible;
list = list->next;
if (words)
words = words->next;
}
if (rwords)
dispose_words (rwords);
}
return (EXECUTION_SUCCESS);
}
/* This way I don't have to know whether fclose () is a
function or a macro. */
static int
stream_close (file)
FILE *file;
{
return (fclose (file));
}

View File

@@ -0,0 +1,128 @@
This file is reserved.def, in which the shell reserved words are defined.
It has no direct C file production, but defines builtins for the help
command.
Copyright (C) 1987, 1989, 1991 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 1, 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; see the file COPYING. If not, write to the Free Software
Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
$BUILTIN for
$SHORT_DOC for NAME [in WORDS ... ;] do COMMANDS; done
The `for' loop executes a sequence of commands for each member in a
list of items. If `in WORDS ...;' is not present, then `in "$@"' is
assumed. For each element in WORDS, NAME is set to that element, and
the COMMANDS are executed.
$END
$BUILTIN case
$SHORT_DOC case WORD in [PATTERN [| PATTERN]...) COMMANDS ;;]... esac
Selectively execute COMMANDS based upon WORD matching PATTERN. The
`|' is used to separate multiple patterns.
$END
$BUILTIN if
$SHORT_DOC if COMMANDS; then COMMANDS; [else COMMANDS;] fi
`if' executes the `then' COMMANDS only if the final command in the
`if' COMMANDS has an exit status of zero.
$END
$BUILTIN while
$SHORT_DOC while COMMANDS; do COMMANDS; done
Expand and execute COMMANDS as long as the final command in the
`while' COMMANDS has an exit status of zero.
$END
$BUILTIN until
$SHORT_DOC until COMMANDS; do COMMANDS; done
Expand and execute COMMANDS as long as the final command in the
`until' COMMANDS has an exit status which is not zero.
$END
$BUILTIN function
$SHORT_DOC function NAME { COMMANDS ; } or NAME () { COMMANDS ; }
Create a simple command invoked by NAME which runs COMMANDS.
Arguments on the command line along with NAME are passed to the
function as $0 .. $n.
$END
$BUILTIN { ... }
$DOCNAME grouping_braces
$SHORT_DOC { COMMANDS }
Run a set of commands in a group. This is one way to redirect an
entire set of commands.
$END
$BUILTIN %
$DOCNAME fg_percent
$SHORT_DOC %[DIGITS | WORD] [&]
This is similar to the `fg' command. Resume a stopped or background
job. If you specifiy DIGITS, then that job is used. If you specify
WORD, then the job whose name begins with WORD is used. Following the
job specification with a `&' places the job in the background.
$END
$BUILTIN Variables
$DOCNAME variable_help
$SHORT_DOC Names and meaning of some variables.
BASH_VERSION The version numbers of this Bash.
CDPATH A colon separated list of directories to search
when the argument to `cd' is not found in the current
directory.
HISTFILE The name of the file where your command history is stored.
HISTFILESIZE The maximum number of lines this file can contain.
HISTSIZE The maximum number of history lines that a running
shell can access.
HOME The complete pathname to your login directory.
HOSTTYPE The type of CPU and OS this version of Bash is running
under.
PATH A colon separated list of directories to search when
looking for commands.
PROMPT_COMMAND A command to be executed before the printing of each
primary prompt.
PS1 The primary prompt string.
TERM The name of the current terminal type (/etc/termcap).
auto_resume Non-null means a command word appearing on a line by
itself is first looked for in the list of currently
stopped jobs. If found there, that job is foregrounded.
histchars Characters controlling history expansion and quick
substitution. The first character is the history
substitution character, usually `!'. The second is
the `quick substition' character, usually `^'.
history_control Set to a value of "ignorespace", it means don't enter
lines which begin with a SPC on the history list. Set
to a value of "ignoredups", it means don't enter lines
which match the last entered line. Unset, or any
other value than those above mean to save all lines
on the history list.
hostname_completion_file
Contains the name of a file in the same format as
`/etc/hosts' that should be read when Bash needs to
complete a hostname.
ignoreeof Controls the action of the shell on receipt of an EOF
character as the sole input. If set, then the value
of it is the number of EOF characters that can be seen
in a row as sole input characters before the shell
will exit (default 10). When unset, EOF signifies the
end of input.
no_exit_on_failed_exec
If this variable exists, the shell will not exit in
the case that it couldn't execute the file specified
in the `exec' command.
notify notify of job termination immediately.
$END

View File

@@ -0,0 +1,59 @@
This file is return.def, from which is created return.c.
It implements the builtin "return" in Bash.
Copyright (C) 1987, 1989, 1991 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 1, 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; see the file COPYING. If not, write to the Free Software
Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
$PRODUCES return.c
$BUILTIN return
$FUNCTION return_builtin
$SHORT_DOC return [n]
Causes a function to exit with the return value specified by N. If N
is omitted, the return status is that of the last command.
$END
#include "../shell.h"
/* If we are executing a user-defined function then exit with the value
specified as an argument. if no argument is given, then the last
exit status is used. */
int
return_builtin (list)
WORD_LIST *list;
{
extern int last_command_exit_value;
extern int return_catch_flag, return_catch_value;
extern jmp_buf return_catch;
return_catch_value = get_numeric_arg (list);
if (!list)
return_catch_value = last_command_exit_value;
if (return_catch_flag)
longjmp (return_catch, 1);
else
{
builtin_error ("Can only `return' from a function");
return (EXECUTION_FAILURE);
}
}

View File

@@ -0,0 +1,485 @@
This file is set.def, from which is created set.c.
It implements the "set" and "unset" builtins in Bash.
Copyright (C) 1987, 1989, 1991 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 1, 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; see the file COPYING. If not, write to the Free Software
Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
$PRODUCES set.c
#include <stdio.h>
#include "../shell.h"
#include "../flags.h"
extern int interactive;
$BUILTIN set
$FUNCTION set_builtin
$SHORT_DOC set [-abefhknotuvxldH] [arg ...]
-a Mark variables which are modified or created for export
-b Notify of job termination immediately
-e Exit immediately if a command exits with a non-zero status
-f Disable file name generation (globbing)
-h Locate and remember function commands as functions are
defined. Function commands are normally looked up when
the function is executed
-k All keyword arguments are placed in the environment for a
command, not just those that precede the command name
-m Job control is enabled
-n Read commands but do not execute them
-o option-name
Set the variable corresponding to option-name:
allexport same as -a
braceexpand the shell will perform brace expansion
emacs use an emacs-style line editing interface
errexit same as -e
histexpand same as -H
ignoreeof the shell will not exit upon reading EOF
monitor same as -m
noclobber disallow redirection to existing files
noexec same as -n
noglob same as -f
nohash same as -d
notify save as -b
nounset same as -u
verbose same as -v
vi use a vi-style line editing interface
xtrace same as -x
-t Exit after reading and executing one command
-u Treat unset variables as an error when substituting
-v Print shell input lines as they are read
-x Print commands and their arguments as they are executed
-l Save and restore the binding of the NAME in a FOR command.
-d Disable the hashing of commands that are looked up for execution.
Normally, commands are remembered in a hash table, and once
found, do not have to be looked up again
-H Enable ! style history substitution. This flag is on
by default.
-C If set, disallow existing regular files to be overwritten
by redirection of output.
Using + rather than - causes these flags to be turned off. The
flags can also be used upon invocation of the shell. The current
set of flags may be found in $-. The remaining ARGs are positional
parameters and are assigned, in order, to $1, $2, .. $9. If no
ARGs are given, all shell variables are printed.
$END
/* An a-list used to match long options for set -o to the corresponding
option letter. */
struct {
char *name;
int letter;
} o_options[] = {
{ "allexport", 'a' },
{ "errexit", 'e' },
{ "histexpand", 'H' },
{ "monitor", 'm' },
{ "noexec", 'n' },
{ "noglob", 'f' },
{ "nohash", 'd' },
#if defined (JOB_CONTROL)
{ "notify", 'b' },
#endif /* JOB_CONTROL */
{"nounset", 'u' },
{"verbose", 'v' },
{"xtrace", 'x' },
{(char *)NULL, 0},
};
static void
list_long_opts ()
{
register int i;
char *on = "on", *off = "off";
extern int noclobber, no_brace_expansion;
extern SHELL_VAR *find_variable ();
#if defined (READLINE)
extern int rl_editing_mode, no_line_editing;
#endif /* READLINE */
printf ("%-15s\t%s\n", "braceexpand", (no_brace_expansion == 0) ? on : off);
printf ("%-15s\t%s\n", "noclobber", (noclobber == 1) ? on : off);
if (find_variable ("ignoreeof") || find_variable ("IGNOREEOF"))
printf ("%-15s\t%s\n", "ignoreeof", on);
else
printf ("%-15s\t%s\n", "ignoreeof", off);
#if defined (READLINE)
if (no_line_editing)
{
printf ("%-15s\toff\n", "emacs");
printf ("%-15s\toff\n", "vi");
}
else
{
/* Magic. This code `knows' how readline handles rl_editing_mode. */
printf ("%-15s\t%s\n", "emacs", (rl_editing_mode == 1) ? on : off);
printf ("%-15s\t%s\n", "vi", (rl_editing_mode == 0) ? on : off);
}
#endif /* READLINE */
for (i = 0; o_options[i].name; i++)
{
int *on_or_off, zero = 0;
char name[2];
name[0] = o_options[i].letter;
name[1] = '\0';
on_or_off = find_flag (name);
if (on_or_off == (int *)FLAG_ERROR)
on_or_off = &zero;
printf ("%-15s\t%s\n", o_options[i].name, (*on_or_off == 1) ? on : off);
}
}
set_minus_o_option (on_or_off, option_name)
int on_or_off;
char *option_name;
{
extern int no_brace_expansion;
int option_char = -1;
if (strcmp (option_name, "braceexpand") == 0)
{
if (on_or_off == FLAG_ON)
no_brace_expansion = 0;
else
no_brace_expansion = 1;
}
else if (strcmp (option_name, "noclobber") == 0)
{
if (on_or_off == FLAG_ON)
bind_variable ("noclobber", "");
else
unbind_variable ("noclobber");
stupidly_hack_special_variables ("noclobber");
}
else if (strcmp (option_name, "ignoreeof") == 0)
{
unbind_variable ("ignoreeof");
unbind_variable ("IGNOREEOF");
if (on_or_off == FLAG_ON)
bind_variable ("IGNOREEOF", "10");
stupidly_hack_special_variables ("IGNOREEOF");
}
#if defined (READLINE)
else if ((strcmp (option_name, "emacs") == 0) ||
(strcmp (option_name, "vi") == 0))
{
extern int no_line_editing;
if (on_or_off == FLAG_ON)
{
rl_variable_bind ("editing-mode", option_name);
if (interactive)
with_input_from_stdin ();
no_line_editing = 0;
}
else
{
extern int rl_editing_mode;
int isemacs = (rl_editing_mode == 1);
if ((isemacs && strcmp (option_name, "emacs") == 0) ||
(!isemacs && strcmp (option_name, "vi") == 0))
{
if (interactive)
with_input_from_stream (stdin, "stdin");
no_line_editing = 1;
}
else
builtin_error ("not in %s editing mode",
option_name);
}
}
#endif /* READLINE */
else
{
register int i;
for (i = 0; o_options[i].name; i++)
{
if (strcmp (option_name, o_options[i].name) == 0)
{
option_char = o_options[i].letter;
break;
}
}
if (option_char == -1)
{
builtin_error ("%s: unknown option name", option_name);
return (EXECUTION_FAILURE);
}
if (change_flag_char (option_char, on_or_off) == FLAG_ERROR)
{
bad_option (option_name);
return (EXECUTION_FAILURE);
}
}
return (EXECUTION_SUCCESS);
}
/* Set some flags from the word values in the input list. If LIST is empty,
then print out the values of the variables instead. If LIST contains
non-flags, then set $1 - $9 to the successive words of LIST. */
set_builtin (list)
WORD_LIST *list;
{
int on_or_off, flag_name, force_assignment = 0;
if (!list)
{
SHELL_VAR **vars;
vars = all_shell_variables ();
if (vars)
{
print_var_list (vars);
free (vars);
}
vars = all_shell_functions ();
if (vars)
{
print_var_list (vars);
free (vars);
}
return (EXECUTION_SUCCESS);
}
/* Check validity of flag arguments. */
if (*list->word->word == '-' || *list->word->word == '+')
{
register char *arg;
WORD_LIST *save_list = list;
while (list && (arg = list->word->word))
{
char s[2];
if (arg[0] != '-' && arg[0] != '+')
break;
/* `-' or `--' signifies end of flag arguments. */
if (arg[0] == '-' &&
(!arg[1] || (arg[1] == '-' && !arg[2])))
break;
s[1] = '\0';
while (s[0] = *++arg)
{
if (find_flag (s) == (int *)FLAG_ERROR && s[0] != 'o')
{
bad_option (s);
return (EXECUTION_FAILURE);
}
}
list = list->next;
}
list = save_list;
}
/* Do the set command. While the list consists of words starting with
'-' or '+' treat them as flags, otherwise, start assigning them to
$1 ... $n. */
while (list)
{
char *string = list->word->word;
/* If the argument is `--' then signal the end of the list and
remember the remaining arguments. */
if ((strcmp (string, "--") == 0) || (strcmp (string, "-") == 0))
{
list = list->next;
/* `set --' unsets the positional parameters. */
if (strcmp (string, "--") == 0)
force_assignment = 1;
/* Until told differently, the old shell behaviour of
`set - [arg ...]' being equivalent to `set +xv [arg ...]'
stands. Posix.2 says the behaviour is marked as obsolescent. */
else
{
change_flag_char ('x', '+');
change_flag_char ('v', '+');
}
break;
}
if ((on_or_off = *string) &&
(on_or_off == '-' || on_or_off == '+'))
{
int i = 1;
while (flag_name = string[i++])
{
if (flag_name == '?')
{
/* Print all the possible flags. */
}
else if (flag_name == 'o') /* -+o option-name */
{
char *option_name;
WORD_LIST *opt;
opt = list->next;
if (!opt)
{
list_long_opts ();
continue;
}
option_name = opt->word->word;
if (!option_name || !*option_name || (*option_name == '-'))
{
list_long_opts ();
continue;
}
list = list->next; /* Skip over option name. */
if (set_minus_o_option
(on_or_off, option_name) != EXECUTION_SUCCESS)
return (EXECUTION_FAILURE);
}
else
{
if (change_flag_char (flag_name, on_or_off) == FLAG_ERROR)
{
char opt[3];
opt[0] = on_or_off;
opt[1] = flag_name;
opt[2] = '\0';
bad_option (opt);
return (EXECUTION_FAILURE);
}
}
}
}
else
{
break;
}
list = list->next;
}
/* Assigning $1 ... $n */
if (list || force_assignment)
remember_args (list, 1);
return (EXECUTION_SUCCESS);
}
$BUILTIN unset
$FUNCTION unset_builtin
$SHORT_DOC unset [-f] [-v] [name ...]
For each NAME, remove the corresponding variable or function. Given
the `-v', unset will only act on variables. Given the `-f' flag,
unset will only act on functions. With neither flag, unset first
tries to unset a variable, and if that fails, then tries to unset a
function. Some variables (such as PATH and IFS) cannot be unset; also
see readonly.
$END
unset_builtin (list)
WORD_LIST *list;
{
extern char **non_unsettable_vars;
int unset_function = 0, unset_variable = 0;
int any_failed = 0;
char *name;
while (list)
{
name = list->word->word;
if (strcmp (name, "-f") == 0)
{
list = list->next;
unset_function++;
continue;
}
if (strcmp (name, "-v") == 0)
{
list = list->next;
unset_variable++;
continue;
}
else if (strcmp (name, "--") == 0)
{
list = list->next;
break;
}
else if (*name == '-')
{
bad_option (name);
return (EXECUTION_FAILURE);
}
else
break;
}
if (unset_function && unset_variable)
{
builtin_error ("cannot simultaneously unset a function and a variable");
return (EXECUTION_FAILURE);
}
while (list)
{
name = list->word->word;
if (!unset_function &&
find_name_in_list (name, non_unsettable_vars) > -1)
{
builtin_error ("%s: cannot unset", name);
any_failed++;
}
else
{
/* Unless the -f option is supplied, the name refers to a
variable. */
int tem = makunbound (name,
unset_function ? shell_functions : shell_variables);
/* This is what Posix.2 draft 11+ says. ``If neither -f nor -v
is specified, the name refers to a variable; if a variable by
that name does not exist, a function by that name, if any,
shall be unset.'' */
if ((tem == -1) && !unset_function && !unset_variable)
tem = makunbound (name, shell_functions);
if (tem == -1)
any_failed++;
else if (!unset_function)
stupidly_hack_special_variables (name);
}
list = list->next;
}
if (any_failed)
return (EXECUTION_FAILURE);
else
return (EXECUTION_SUCCESS);
}

View File

@@ -0,0 +1,238 @@
This file is setattr.def, from which is created setattr.c.
It implements the builtins "export" and "readonly", in Bash.
Copyright (C) 1987, 1989, 1991 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 1, 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; see the file COPYING. If not, write to the Free Software
Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
$PRODUCES setattr.c
#include "../shell.h"
$BUILTIN export
$FUNCTION export_builtin
$SHORT_DOC export [-n] [-p] [-f] [name ...]
NAMEs are marked for automatic export to the environment of
subsequently executed commands. If the -f option is given,
the NAMEs refer to functions. If no NAMEs are given, or if `-p'
is given, a list of all names that are exported in this shell is
printed. An argument of `-n' says to remove the export property
from subsequent NAMEs. An argument of `--' disables further option
processing.
$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. */
export_builtin (list)
register WORD_LIST *list;
{
return (set_or_show_attributes (list, att_exported));
}
$BUILTIN readonly
$FUNCTION readonly_builtin
$SHORT_DOC readonly [-p] [-f] [name ...]
The given NAMEs are marked readonly and the values of these NAMEs may
not be changed by subsequent assignment. If the -f option is given,
then functions corresponding to the NAMEs are so marked. If no
arguments are given, or if `-p' is given, a list of all readonly names
is printed. An argument of `--' disables further option processing.
$END
/* For each variable name in LIST, make that variable readonly. Given an
empty LIST, print out all existing readonly variables. */
readonly_builtin (list)
register WORD_LIST *list;
{
return (set_or_show_attributes (list, att_readonly));
}
/* 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. */
int
set_or_show_attributes (list, attribute)
register WORD_LIST *list;
int attribute;
{
register SHELL_VAR *var;
int assign, undo = 0, functions_only = 0;
extern int array_needs_making;
/* Read arguments from the front of the list. */
while (list)
{
register char *name = list->word->word;
if (strcmp (name, "-n") == 0)
{
undo = 1;
list = list->next;
}
else if (strcmp (name, "-f") == 0)
{
functions_only = 1;
list = list->next;
}
else if (strcmp (name, "-p") == 0)
{
list = list->next;
continue;
}
else if (strcmp (name, "--") == 0)
{
list = list->next;
break;
}
else if (*name == '-')
{
bad_option (name);
return (EXECUTION_FAILURE);
}
else
break;
}
if (list)
{
if (attribute & att_exported)
array_needs_making = 1;
while (list)
{
register char *name = list->word->word;
if (functions_only)
{
var = find_function (name);
if (!var)
{
builtin_error ("%s: not a function", name);
}
else
{
if (undo)
var->attributes &= ~attribute;
else
var->attributes |= attribute;
}
list = list->next;
if (attribute == att_exported)
array_needs_making++;
continue;
}
assign = assignment (name);
if (assign)
{
/* 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. */
do_assignment_no_expand (name);
name[assign] = '\0';
}
if (undo)
{
var = find_variable (name);
if (var)
var->attributes &= ~attribute;
}
else
{
SHELL_VAR *find_tempenv_variable (), *tv;
if (tv = find_tempenv_variable (name))
{
var = bind_variable (tv->name, tv->value);
dispose_variable (tv);
}
else
var = find_variable (name);
if (!var)
{
var = bind_variable (name, (char *)NULL);
var->attributes |= att_invisible;
}
var->attributes |= attribute;
}
array_needs_making++; /* XXX */
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 (variable_list)
{
for (i = 0; var = variable_list[i]; i++)
{
if ((var->attributes & attribute) && !invisible_p (var))
{
char flags[6];
flags[0] = '\0';
if (exported_p (var))
strcat (flags, "x");
if (readonly_p (var))
strcat (flags, "r");
if (function_p (var))
strcat (flags, "f");
if (integer_p (var))
strcat (flags, "i");
if (flags[0])
{
printf ("declare -%s ", flags);
if (!function_p (var))
printf ("%s=%s\n", var->name, value_cell (var));
else
{
char *named_function_string ();
printf ("%s\n", named_function_string
(var->name, function_cell (var), 1));
}
}
}
}
free (variable_list);
}
}
return (EXECUTION_SUCCESS);
}

View File

@@ -0,0 +1,90 @@
This file is shift.def, from which is created shift.c.
It implements the builtin "shift" in Bash.
Copyright (C) 1987, 1989, 1991 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 1, 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; see the file COPYING. If not, write to the Free Software
Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
$PRODUCES shift.c
#include "../shell.h"
$BUILTIN shift
$FUNCTION shift_builtin
$SHORT_DOC shift [n]
The positional parameters from $N+1 ... are renamed to $1 ... If N is
not given, it is assumed to be 1.
$END
/* Shift the arguments ``left''. Shift DOLLAR_VARS down then take one
off of REST_OF_ARGS and place it into DOLLAR_VARS[9]. If LIST has
anything in it, it is a number which says where to start the
shifting. Return > 0 if `times' > $#, otherwise 0. */
int
shift_builtin (list)
WORD_LIST *list;
{
int times = get_numeric_arg (list);
int number, r;
WORD_LIST *args;
extern WORD_LIST *list_rest_of_args ();
if (!times)
return (EXECUTION_SUCCESS);
if (times < 0)
{
builtin_error ("shift count must be >= 0");
return (EXECUTION_FAILURE);
}
args = list_rest_of_args ();
number = list_length (args);
dispose_words (args);
r = EXECUTION_SUCCESS;
if (times > number)
{
times = number;
r = EXECUTION_FAILURE;
}
while (times-- > 0)
{
register int count;
if (dollar_vars[1])
free (dollar_vars[1]);
for (count = 1; count < 9; count++)
dollar_vars[count] = dollar_vars[count + 1];
if (rest_of_args)
{
WORD_LIST *temp = rest_of_args;
dollar_vars[9] = savestring (temp->word->word);
rest_of_args = rest_of_args->next;
dispose_word (temp->word);
}
else
dollar_vars[9] = (char *)NULL;
}
return (r);
}

View File

@@ -0,0 +1,148 @@
This file is source.def, from which is created source.c.
It implements the builtins "." and "source" in Bash.
Copyright (C) 1987, 1989, 1991 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 1, 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; see the file COPYING. If not, write to the Free Software
Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
$PRODUCES source.c
$BUILTIN source
$FUNCTION source_builtin
$SHORT_DOC source filename
Read and execute commands from FILENAME and return. The pathnames
in $PATH are used to find the directory containing FILENAME.
$END
$BUILTIN .
$DOCNAME dot
$FUNCTION source_builtin
$SHORT_DOC . [filename]
Read and execute commands from FILENAME and return. The pathnames
in $PATH are used to find the directory containing FILENAME.
$END
/* source.c - Implements the `.' and `source' builtins. */
#include <sys/types.h>
#include <sys/file.h>
#include <errno.h>
#include "../shell.h"
#include "../posixstat.h"
#include "../filecntl.h"
extern int errno;
/* 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. */
source_builtin (list)
WORD_LIST *list;
{
extern int return_catch_flag, return_catch_value;
extern jmp_buf return_catch;
int result, return_val;
/* Assume the best. */
result = EXECUTION_SUCCESS;
if (list)
{
extern char *find_path_file ();
char *string, *filename, *tempfile;
struct stat finfo;
int fd, tt;
tempfile = find_path_file (list->word->word);
if (!tempfile)
tempfile = savestring (list->word->word);
filename = (char *)alloca (1 + strlen (tempfile));
strcpy (filename, tempfile);
free (tempfile);
if (stat (filename, &finfo) == -1 ||
(fd = open (filename, O_RDONLY)) == -1)
goto file_error_exit;
string = (char *)xmalloc (1 + finfo.st_size);
tt = read (fd, string, finfo.st_size);
string[finfo.st_size] = '\0';
/* Close the open file, preserving the state of errno. */
{ int temp = errno; close (fd); errno = temp; }
if (tt != finfo.st_size)
{
free (string);
file_error_exit:
file_error (filename);
#if defined (ALLOW_RIGID_POSIX_COMPLIANCE)
/* POSIX shells exit if non-interactive and file error. */
if (getenv ("POSIX_PENDANTIC"))
{
extern int interactive_shell;
if (!interactive_shell)
longjmp (top_level, EXITPROG);
}
#endif /* ALLOW_RIGID_POSIX_COMPLIANCE */
return (EXECUTION_FAILURE);
}
if (tt > 80)
tt = 80;
if (check_binary_file (string, tt))
{
free (string);
builtin_error ("%s: cannot execute binary file", filename);
return (EX_BINARY_FILE);
}
begin_unwind_frame ("File Sourcing");
if (list->next)
{
extern void pop_dollar_vars (), push_dollar_vars ();
push_dollar_vars ();
add_unwind_protect ((Function *)pop_dollar_vars, (char *)NULL);
remember_args (list->next, 1);
}
unwind_protect_int (return_catch_flag);
unwind_protect_jmp_buf (return_catch);
return_catch_flag++;
return_val = setjmp (return_catch);
if (return_val)
parse_and_execute_cleanup ();
else
result = parse_and_execute (string, filename);
run_unwind_frame ("File Sourcing");
/* If RETURN_VAL is non-zero, then we return the value given
to return_builtin (), since that is how we got here. */
if (return_val)
result = return_catch_value;
}
return (result);
}

View File

@@ -0,0 +1,83 @@
This file is suspend.def, from which is created suspend.c.
It implements the builtin "suspend" in Bash.
Copyright (C) 1987, 1989, 1991 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 1, 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; see the file COPYING. If not, write to the Free Software
Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
$PRODUCES suspend.c
$BUILTIN suspend
$DEPENDS_ON JOB_CONTROL
$FUNCTION suspend_builtin
$SHORT_DOC suspend [-f]
Suspend the execution of this shell until it receives a SIGCONT
signal. The `-f' if specified says not to complain about this
being a login shell if it is; just suspend anyway.
$END
#include <signal.h>
#include <sys/types.h>
#include "../shell.h"
#include "../jobs.h"
#if defined (JOB_CONTROL)
extern int job_control;
static SigHandler *old_cont, *old_tstp;
/* Continue handler. */
sighandler
suspend_continue (sig)
int sig;
{
signal (SIGCONT, old_cont);
signal (SIGTSTP, old_tstp);
}
/* Suspending the shell. If -f is the arg, then do the suspend
no matter what. Otherwise, complain if a login shell. */
int
suspend_builtin (list)
WORD_LIST *list;
{
if (!job_control)
{
builtin_error ("Cannot suspend a shell without job control");
return (EXECUTION_FAILURE);
}
if (list)
if (strcmp (list->word->word, "-f") == 0)
goto do_suspend;
no_args (list);
if (login_shell)
{
builtin_error ("Can't suspend a login shell");
return (EXECUTION_FAILURE);
}
do_suspend:
old_cont = (SigHandler *)signal (SIGCONT, suspend_continue);
old_tstp = (SigHandler *)signal (SIGTSTP, SIG_DFL);
killpg (shell_pgrp, SIGTSTP);
return (EXECUTION_SUCCESS);
}
#endif /* JOB_CONTROL */

View File

@@ -0,0 +1,138 @@
This file is test.def, from which is created test.c.
It implements the builtin "test" in Bash.
Copyright (C) 1987, 1989, 1991 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 1, 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; see the file COPYING. If not, write to the Free Software
Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
$PRODUCES test.c
$BUILTIN test
$FUNCTION test_builtin
$SHORT_DOC test [expr]
Exits with a status of 0 (trueness) or 1 (falseness) 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:
-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.
-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 is not empty.
-S FILE True if file is a socket.
-t [FD] True if FD is opened on a terminal. If FD
is omitted, it defaults to 1 (stdout).
-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.
FILE1 -nt FILE2 True if file1 is newer than (according to
modification date) file2.
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
or STRING True if string is not empty.
STRING1 = STRING2
True if the strings are equal.
STRING1 != STRING2
True if the strings are not equal.
Other operators:
! 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.
$END
$BUILTIN [
$DOCNAME test_bracket
$FUNCTION test_builtin
$SHORT_DOC [ arg... ]
This is a synonym for the "test" shell builtin, excepting that the
last argument must be literally `]', to match the `[' which invoked
the test.
$END
#include "../shell.h"
extern char *this_command_name;
/* TEST/[ builtin. */
int
test_builtin (list)
WORD_LIST *list;
{
char **argv;
int argc, result;
WORD_LIST *t = list;
/* 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 his code wants. */
if (!list)
{
if (strcmp (this_command_name, "[") == 0)
builtin_error ("missing `]'");
return (EXECUTION_FAILURE);
}
/* Get the length of the argument list. */
for (argc = 0; t; t = t->next, argc++);
/* Account for argv[0] being a command name. This makes our life easier. */
argc++;
argv = (char **)xmalloc ((1 + argc) * sizeof (char *));
argv[argc] = (char *)NULL;
/* this_command_name is the name of the command that invoked this
function. So you can't call test_builtin () directly from
within this code, there are too many things to worry about. */
argv[0] = savestring (this_command_name);
for (t = list, argc = 1; t; t = t->next, argc++)
argv[argc] = savestring (t->word->word);
result = test_command (argc, argv);
free_array (argv);
return (result);
}

View File

@@ -0,0 +1,88 @@
This file is times.def, from which is created times.c.
It implements the builtin "times" in Bash.
Copyright (C) 1987, 1989, 1991 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 1, 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; see the file COPYING. If not, write to the Free Software
Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
$PRODUCES times.c
$BUILTIN times
$FUNCTION times_builtin
$SHORT_DOC times
Print the accumulated user and system times for processes run from
the shell.
$END
#include "../shell.h"
#include <sys/types.h>
#if defined (HAVE_RESOURCE) && !defined (hpux) && !defined (USGr4)
#include <sys/time.h>
#include <sys/resource.h>
#else /* !HAVE_RESOURCE || !hpux || !USGr4 */
#include <sys/times.h>
#endif /* !HAVE_RESOURCE || !hpux || !USGr4 */
/* Print the totals for system and user time used. The
information comes from variables in jobs.c used to keep
track of this stuff. */
times_builtin (list)
WORD_LIST *list;
{
#if defined (HAVE_RESOURCE) && defined (RUSAGE_SELF)
struct rusage self, kids;
no_args (list);
getrusage (RUSAGE_SELF, &self);
getrusage (RUSAGE_CHILDREN, &kids); /* terminated child processes */
print_timeval (&self.ru_utime);
putchar (' ');
print_timeval (&self.ru_stime);
putchar ('\n');
print_timeval (&kids.ru_utime);
putchar (' ');
print_timeval (&kids.ru_stime);
putchar ('\n');
#else /* !HAVE_RESOURCE || !RUSAGE_SELF */
# if !defined (BrainDeath)
struct tms t;
no_args (list);
times (&t);
/* As of System V.3, HP-UX 6.5, and other ATT-like systems, this stuff is
returned in terms of clock ticks (HZ from sys/param.h). C'mon, guys.
This kind of stupid clock-dependent stuff is exactly the reason 4.2BSD
introduced the `timeval' struct. */
print_time_in_hz (t.tms_utime);
putchar (' ');
print_time_in_hz (t.tms_stime);
putchar ('\n');
print_time_in_hz (t.tms_cutime);
putchar (' ');
print_time_in_hz (t.tms_cstime);
putchar ('\n');
# endif /* BrainDeath */
#endif /* !HAVE_RESOURCE || !RUSAGE_SELF */
return (EXECUTION_SUCCESS);
}

View File

@@ -0,0 +1,187 @@
This file is trap.def, from which is created trap.c.
It implements the builtin "trap" in Bash.
Copyright (C) 1987, 1989, 1991 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 1, 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; see the file COPYING. If not, write to the Free Software
Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
$PRODUCES trap.c
$BUILTIN trap
$FUNCTION trap_builtin
$SHORT_DOC trap [arg] [signal_spec]
The command ARG is to be read and executed when the shell receives
signal(s) SIGNAL_SPEC. If ARG is absent all specified signals are
reset to their original values. If ARG is the null string this
signal is ignored by the shell and by the commands it invokes. If
SIGNAL_SPEC is EXIT (0) the command ARG is executed on exit from
the shell. The trap command with no arguments prints the list of
commands associated with each signal number. SIGNAL_SPEC is either
a signal name in <signal.h>, or a signal number. The syntax `trap -l'
prints a list of signal names and their corresponding numbers.
Note that a signal can be sent to the shell with "kill -signal $$".
$END
#include <sys/types.h>
#include <signal.h>
#include "../shell.h"
#include "../trap.h"
/* The trap command:
trap <arg> <signal ...>
trap <signal ...>
trap -l
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. */
trap_builtin (list)
WORD_LIST *list;
{
register int i;
int list_signal_names = 0;
while (list)
{
if (strcmp (list->word->word, "-l") == 0)
{
list_signal_names++;
list = list->next;
}
else if (strcmp (list->word->word, "--") == 0)
{
list = list->next;
break;
}
else if ((*list->word->word == '-') && (list->word->word[1] != '\0'))
{
bad_option (list->word->word);
return (EXECUTION_FAILURE);
}
else
break;
}
if (!list && !list_signal_names)
{
for (i = 0; i < NSIG; i++)
if (trap_list[i] != (char *)DEFAULT_SIG)
printf ("trap -- '%s' %s\n",
(trap_list[i] == (char *)IGNORE_SIG) ? "" : trap_list[i],
signal_name (i));
return (EXECUTION_SUCCESS);
}
if (list_signal_names)
{
int column = 0;
for (i = 0; i < NSIG; i++)
{
printf ("%2d) %s", i, signal_name (i));
if (++column < 4)
printf ("\t");
else
{
printf ("\n");
column = 0;
}
}
if (column != 0)
printf ("\n");
return (EXECUTION_SUCCESS);
}
if (list)
{
char *first_arg = list->word->word;
int operation = SET, any_failed = 0;
if (signal_object_p (first_arg))
operation = REVERT;
else
{
list = list->next;
if (*first_arg == '\0')
operation = IGNORE;
else if (strcmp (first_arg, "-") == 0)
operation = REVERT;
}
while (list)
{
extern int interactive;
int sig;
sig = decode_signal (list->word->word);
if (sig == NO_SIG)
{
builtin_error ("%s: not a signal specification",
list->word->word);
any_failed++;
}
else
{
switch (operation)
{
case SET:
set_signal (sig, first_arg);
break;
case REVERT:
restore_default_signal (sig);
/* Always ignore SIGQUIT. */
if (sig == SIGQUIT)
signal (SIGQUIT, SIG_IGN);
/* Ignore some other signals if we are interactive. */
if (interactive)
{
if (sig == SIGTERM)
signal (SIGTERM, SIG_IGN);
#if defined (JOB_CONTROL)
if (sig == SIGTTIN ||
sig == SIGTTOU ||
sig == SIGTSTP)
signal (sig, SIG_IGN);
#endif /* JOB_CONTROL */
}
break;
case IGNORE:
ignore_signal (sig);
break;
}
}
list = list->next;
}
return ((!any_failed) ? EXECUTION_SUCCESS : EXECUTION_FAILURE);
}
}

View File

@@ -0,0 +1,264 @@
This file is type.def, from which is created type.c.
It implements the builtin "type" in Bash.
Copyright (C) 1987, 1989, 1991 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 1, 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; see the file COPYING. If not, write to the Free Software
Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
$PRODUCES type.c
$BUILTIN type
$FUNCTION type_builtin
$SHORT_DOC type [-all] [-type | -path] [name ...]
For each NAME, indicate how it would be interpreted if used as a
command name.
If the -type flag is used, returns a single word which is one of
`alias', `keyword', `function', `builtin', `file' or `', if NAME is an
alias, shell reserved word, shell function, shell builtin, disk file,
or unfound, respectively.
If the -path flag is used, either returns the name of the disk file
that would be exec'ed, or nothing if -type wouldn't return `file'.
If the -all flag is used, displays all of the places that contain an
executable named `file'. This includes aliases and functions, if and
only if the -path flag is not also used.
$END
#include <stdio.h>
#include "../shell.h"
#if defined (ALIAS)
#include "../alias.h"
#endif /* ALIAS */
/* For each word in LIST, find out what the shell is going to do with
it as a simple command. i.e., which file would this shell use to
execve, or if it is a builtin command, or an alias. Possible flag
arguments:
-type Returns the "type" of the object, one of
`alias', `keyword', `function', `builtin',
or `file'.
-path Returns the pathname of the file if -type is
a file.
-all Returns all occurrences of words, whether they
be a filename in the path, alias, function,
or builtin.
Order of evaluation:
alias
keyword
function
builtin
file
*/
type_builtin (list)
WORD_LIST *list;
{
int path_only, type_only, all;
int found_any, successful_finds;
char *command;
path_only = type_only = all = 0;
while (list && *(list->word->word) == '-')
{
char *flag = &(list->word->word[1]);
if ((strcmp (flag, "type") == 0) || (strcmp (flag, "t") == 0))
{
type_only = 1;
path_only = 0;
}
else if ((strcmp (flag, "path") == 0) || (strcmp (flag, "p") == 0))
{
path_only = 1;
type_only = 0;
}
else if ((strcmp (flag, "all") == 0) || (strcmp (flag, "a") == 0))
{
all = 1;
}
else
{
bad_option (flag);
return (EXECUTION_FAILURE);
}
list = list->next;
}
while (list)
{
SHELL_VAR *func;
int found = 0;
command = list->word->word;
func = find_function (command);
#if defined (ALIAS)
{
/* Command is an alias? */
ASSOC *alias = find_alias (command);
if (alias)
{
if (type_only)
printf ("alias\n");
else if (!path_only)
printf ("%s is aliased to `%s'\n", command, alias->value);
found++;
if (!all)
goto next_item;
}
}
#endif /* ALIAS */
/* Command is a shell reserved word? */
{
extern STRING_INT_ALIST word_token_alist[];
register int i;
for (i = 0; word_token_alist[i].word; i++)
{
if (strcmp (word_token_alist[i].word, command) == 0)
{
if (type_only)
printf ("keyword\n");
else if (!path_only)
printf ("%s is a shell keyword\n", command);
found++;
if (!all)
goto next_item;
break;
}
}
}
/* Command is a function? */
if (func)
{
if (type_only)
printf ("function\n");
else if (!path_only)
{
#define PRETTY_PRINT_FUNC 1
extern char *named_function_string ();
char *result;
printf ("%s is a function\n", command);
/* We're blowing away THE_PRINTED_COMMAND here... */
result = named_function_string (command,
(COMMAND *) function_cell (func),
PRETTY_PRINT_FUNC);
printf ("%s\n", result);
#undef PRETTY_PRINT_FUNC
}
found++;
if (!all)
goto next_item;
}
/* Command is a builtin? */
{
extern Function *find_shell_builtin ();
if (find_shell_builtin (command))
{
if (type_only)
printf ("builtin\n");
else if (!path_only)
printf ("%s is a shell builtin\n", command);
found++;
if (!all)
goto next_item;
}
}
/* Command is a disk file? */
{
extern char *user_command_matches ();
int found_file = 0;
char *full_path = (char *)NULL;
/* If the user isn't doing "-all", then we might care about
whether the file is present in our hash table. */
if (!all)
{
extern char *find_hashed_filename ();
if ((full_path = find_hashed_filename (command)) != (char *)NULL)
{
if (type_only)
printf ("file\n");
else if (path_only)
printf ("%s\n", full_path);
else
printf ("%s is hashed (%s)\n", command, full_path);
found++;
goto next_item;
}
}
while (full_path =
user_command_matches (command, FS_EXEC_PREFERRED, found_file))
{
found_file++;
found++;
if (type_only)
printf ("file\n");
else if (path_only)
printf ("%s\n", full_path);
else
printf ("%s is %s\n", command, full_path);
free (full_path);
full_path = (char *)NULL;
if (!all)
break;
}
}
if (!found && !path_only && !type_only)
builtin_error ("%s: not found", command);
next_item:
successful_finds += found;
list = list->next;
}
fflush (stdout);
if (successful_finds != 0)
return (EXECUTION_SUCCESS);
else
return (EXECUTION_FAILURE);
}

View File

@@ -0,0 +1,580 @@
This file is ulimit.def, from which is created ulimit.c.
It implements the builtin "ulimit" in Bash.
Copyright (C) 1987, 1989, 1991 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 1, 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; see the file COPYING. If not, write to the Free Software
Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
$PRODUCES ulimit.c
$BUILTIN ulimit
$FUNCTION ulimit_builtin
$SHORT_DOC ulimit [-SHacdmstfpn [limit]]
Ulimit provides control over the resources available to processes
started by the shell, on systems that allow such control. If an
option is given, it is interpreted as follows:
-S use the `soft' resource limit
-H use the `hard' resource limit
-a all current limits are reported
-c the maximum size of core files created
-d the maximum size of a process's data segment
-m the maximum resident set size
-s the maximum stack size
-t the maximum amount of cpu time in seconds
-f the maximum size of files created by the shell
-p the pipe buffer size
-n the maximum number of open file descriptors
If LIMIT is given, it is the new value of the specified resource.
Otherwise, the current value of the specified resource is printed.
If no option is given, then -f is assumed. Values are in 1k
increments, except for -t, which is in seconds, and -p, which is in
increments of 512 bytes.
$END
#include <stdio.h>
#include <sys/types.h>
#include <sys/param.h>
#include <errno.h>
#include "../shell.h"
#include "pipesize.h"
#if !defined (errno)
extern int errno;
#endif
#if defined (HAVE_RESOURCE)
#include <sys/time.h>
#include <sys/resource.h>
#else
#include <sys/times.h>
#endif
#if defined (_POSIX_VERSION)
#include <limits.h>
#endif
/* Check for the most basic synbols. If they aren't present, this
system's <sys/resource.h> isn't very useful to us. */
#if !defined RLIMIT_FSIZE
# undef HAVE_RESOURCE
#endif
/* **************************************************************** */
/* */
/* Ulimit builtin and Hacks. */
/* */
/* **************************************************************** */
/* Block size for ulimit operations. */
#define ULIMIT_BLOCK_SIZE ((long)1024)
#define u_FILE_SIZE 0x001
#define u_MAX_BREAK_VAL 0x002
#define u_PIPE_SIZE 0x004
#define u_CORE_FILE_SIZE 0x008
#define u_DATA_SEG_SIZE 0x010
#define u_PHYS_MEM_SIZE 0x020
#define u_CPU_TIME_LIMIT 0x040
#define u_STACK_SIZE 0x080
#define u_NUM_OPEN_FILES 0x100
#define u_ALL_LIMITS 0x7ff
#ifndef RLIM_INFINITY
# define RLIM_INFINITY 0x7fffffff
#endif
#define LIMIT_HARD 0x01
#define LIMIT_SOFT 0x02
static long shell_ulimit ();
static long pipesize ();
static int open_files ();
static void print_specific_limits ();
static void print_all_limits ();
static char t[2];
/* Report or set limits associated with certain per-process resources.
See the help documentation in builtins.c for a full description.
Rewritten by Chet Ramey 6/30/91. */
int
ulimit_builtin (list)
register WORD_LIST *list;
{
register char *s;
int c, setting, cmd, mode, verbose_print, opt_eof;
int all_limits, specific_limits;
long current_limit, real_limit, limit = -1L;
long block_factor;
c = mode = verbose_print = opt_eof = 0;
do
{
cmd = setting = all_limits = specific_limits = 0;
block_factor = ULIMIT_BLOCK_SIZE;
/* read_options: */
if (list && !opt_eof && *list->word->word == '-')
{
s = &(list->word->word[1]);
list = list->next;
while (*s && (c = *s++))
{
switch (c)
{
#define ADD_CMD(x) { if (cmd) specific_limits++; cmd |= (x); }
case '-': /* ulimit -- */
opt_eof++;
break;
case 'a':
all_limits++;
break;
case 'f':
ADD_CMD (u_FILE_SIZE);
break;
#if defined (HAVE_RESOURCE)
/* -S and -H are modifiers, not real options. */
case 'S':
mode |= LIMIT_SOFT;
break;
case 'H':
mode |= LIMIT_HARD;
break;
case 'c':
ADD_CMD (u_CORE_FILE_SIZE);
break;
case 'd':
ADD_CMD (u_DATA_SEG_SIZE);
break;
#if !defined (USGr4)
case 'm':
ADD_CMD (u_PHYS_MEM_SIZE);
break;
#endif /* USGr4 */
case 't':
ADD_CMD (u_CPU_TIME_LIMIT);
block_factor = 1; /* seconds */
break;
case 's':
ADD_CMD (u_STACK_SIZE);
break;
#endif /* HAVE_RESOURCE */
case 'p':
ADD_CMD (u_PIPE_SIZE);
block_factor = 512;
break;
case 'n':
ADD_CMD (u_NUM_OPEN_FILES);
block_factor = 1;
break;
default: /* error_case: */
t[0] = c;
t[1] = '\0';
bad_option (t);
#if !defined (HAVE_RESOURCE)
builtin_error("usage: ulimit [-afnp] [new limit]");
#else
builtin_error("usage: ulimit [-SHacmdstfnp] [new limit]");
#endif
return (EXECUTION_FAILURE);
}
}
}
if (all_limits)
{
print_all_limits (mode);
return (EXECUTION_SUCCESS);
}
if (specific_limits)
{
print_specific_limits (cmd, mode);
if (list)
verbose_print++;
continue;
}
if (cmd == 0)
cmd = u_FILE_SIZE;
/* If an argument was supplied for the command, then we want to
set the limit. Note that `ulimit something' means a command
of -f with argument `something'. */
if (list)
{
if (opt_eof || (*list->word->word != '-'))
{
s = list->word->word;
list = list->next;
if (sscanf (s, "%ld", &limit) != 1)
{
if (strcmp (s, "unlimited") == 0)
limit = RLIM_INFINITY;
else
{
builtin_error ("bad non-numeric arg `%s'", s);
return (EXECUTION_FAILURE);
}
}
setting++;
}
else if (!opt_eof)
verbose_print++;
}
if (limit == RLIM_INFINITY)
block_factor = 1;
real_limit = limit * block_factor;
/* If more than one option is given, list each in a verbose format,
the same that is used for -a. */
if (!setting && verbose_print)
{
print_specific_limits (cmd, mode);
continue;
}
current_limit = shell_ulimit (cmd, real_limit, 0, mode);
if (setting)
{
#if !defined (HAVE_RESOURCE)
/* USG systems do not allow limits to be raised by any user
other than root. */
if ((current_limit < real_limit) && (getuid () != 0))
{
builtin_error ("cannot raise limit: %s", strerror (EPERM));
return (EXECUTION_FAILURE);
}
#endif /* !HAVE_RESOURCE */
if (shell_ulimit (cmd, real_limit, 1, mode) == -1)
{
builtin_error ("cannot raise limit: %s", strerror(errno));
return (EXECUTION_FAILURE);
}
continue;
}
else
{
if (current_limit != RLIM_INFINITY)
printf ("%ld\n", (current_limit / block_factor));
else
printf ("unlimited\n");
}
}
while (list);
return (EXECUTION_SUCCESS);
}
/* The ulimit that we call from within Bash.
WHICH says which limit to twiddle; SETTING is non-zero if NEWLIM
contains the desired new limit. Otherwise, the existing limit is
returned. If mode & LIMIT_HARD, the hard limit is used; if
mode & LIMIT_SOFT, the soft limit. Both may be set by specifying
-H and -S; if both are specified, or if neither is specified, the
soft limit will be returned.
Systems without BSD resource limits can specify only u_FILE_SIZE.
This includes most USG systems.
Chet Ramey supplied the BSD resource limit code. */
static long
shell_ulimit (which, newlim, setting, mode)
int which, setting, mode;
long newlim;
{
#if defined (HAVE_RESOURCE)
struct rlimit limit;
int cmd;
if (mode == 0)
mode |= LIMIT_SOFT;
#endif
switch (which)
{
#if !defined (HAVE_RESOURCE)
case u_FILE_SIZE:
if (!setting)
{
/* ulimit () returns a number that is in 512 byte blocks, thus we
must multiply it by 512 to get back to bytes. This is false
only under HP/UX 6.x. */
long result;
result = ulimit (1, 0L);
# if defined (hpux) && !defined (_POSIX_VERSION)
return (result);
# else
return (result * 512);
# endif /* hpux 6.x */
}
else
return (ulimit (2, newlim / 512L));
break;
#else /* defined (HAVE_RESOURCE) */
case u_FILE_SIZE:
cmd = RLIMIT_FSIZE;
goto do_ulimit;
case u_CORE_FILE_SIZE:
cmd = RLIMIT_CORE;
goto do_ulimit;
case u_DATA_SEG_SIZE:
cmd = RLIMIT_DATA;
goto do_ulimit;
#if !defined (USGr4)
case u_PHYS_MEM_SIZE:
cmd = RLIMIT_RSS;
goto do_ulimit;
#endif /* USGr4 */
case u_CPU_TIME_LIMIT:
cmd = RLIMIT_CPU;
goto do_ulimit;
case u_STACK_SIZE:
cmd = RLIMIT_STACK;
do_ulimit:
if (getrlimit (cmd, &limit) != 0)
return ((long) -1);
if (!setting)
{
if (mode & LIMIT_SOFT)
return (limit.rlim_cur);
else
return (limit.rlim_max);
}
else
{
if (mode & LIMIT_SOFT)
limit.rlim_cur = newlim;
if (mode & LIMIT_HARD)
limit.rlim_max = newlim;
return (setrlimit (cmd, &limit));
}
break;
#endif /* HAVE_RESOURCE */
/* You can't get or set the pipe size with getrlimit, so we have to
cheat. */
case u_PIPE_SIZE:
if (setting)
{
errno = EINVAL;
return ((long) -1);
}
return (pipesize ());
case u_NUM_OPEN_FILES:
if (setting)
{
#if defined (HAVE_RESOURCE) && defined (RLIMIT_NOFILE)
cmd = RLIMIT_NOFILE;
goto do_ulimit;
#else
# if defined (HAVE_SETDTABLESIZE)
return (setdtablesize (newlim));
# else
errno = EINVAL;
return ((long) -1);
# endif /* HAVE_SETDTABLESIZE */
#endif /* !HAVE_RESOURCE || !RLIMIT_NOFILE */
}
else
return ((long) open_files (mode));
default:
errno = EINVAL;
return ((long) -1);
}
}
static int
open_files (mode)
int mode;
{
#if !defined (RLIMIT_NOFILE)
return (getdtablesize ());
#else
struct rlimit rl;
getrlimit (RLIMIT_NOFILE, &rl);
if (mode & LIMIT_SOFT)
return (rl.rlim_cur);
else
return (rl.rlim_max);
#endif
}
static long
pipesize ()
{
#if defined (PIPE_BUF)
/* This is defined on Posix systems. */
return ((long) PIPE_BUF);
#else
# if defined (PIPESIZE)
/* This is defined by running a program from the Makefile. */
return ((long) PIPESIZE);
# else
errno = EINVAL;
return ((long) -1);
# endif /* PIPESIZE */
#endif /* PIPE_BUF */
}
/* ulimit(2) returns information about file size limits in terms of 512-byte
blocks. This is the factor by which to divide to turn it into information
in terms of 1024-byte blocks. Except for hpux 6.x, which returns it in
terms of bytes. */
#if !defined (hpux) || defined (_POSIX_VERSION)
# define ULIMIT_DIVISOR 2
#else
# define ULIMIT_DIVISOR 1024
#endif
#if defined (HAVE_RESOURCE)
#if !defined (RLIM_NLIMITS)
# define RLIM_NLIMITS 6 /* Number of resource limits. */
#endif
typedef struct {
int option_cmd; /* The ulimit command for this limit. */
int parameter; /* Parameter to pass to getrlimit (). */
int block_factor; /* Blocking factor for specific limit. */
char *description; /* Descriptive string to output. */
} BSD_RESOURCE_LIMITS;
static BSD_RESOURCE_LIMITS limits[RLIM_NLIMITS + 1] = {
{ u_CORE_FILE_SIZE, RLIMIT_CORE, 1024, "core file size (blocks)" },
{ u_DATA_SEG_SIZE, RLIMIT_DATA, 1024, "data seg size (kbytes)" },
{ u_FILE_SIZE, RLIMIT_FSIZE, 1024, "file size (blocks)" },
#if !defined (USGr4)
{ u_PHYS_MEM_SIZE, RLIMIT_RSS, 1024, "max memory size (kbytes)" },
#endif /* USGr4 */
{ u_STACK_SIZE, RLIMIT_STACK, 1024, "stack size (kbytes)" },
{ u_CPU_TIME_LIMIT, RLIMIT_CPU, 1, "cpu time (seconds)" },
{ 0, 0, 0, (char *)NULL }
};
static void
print_bsd_limit (i, mode)
int i, mode;
{
struct rlimit rl;
long limit;
getrlimit (limits[i].parameter, &rl);
if (mode & LIMIT_HARD)
limit = rl.rlim_max;
else
limit = rl.rlim_cur;
printf ("%-25s", limits[i].description);
if (limit == RLIM_INFINITY)
printf ("unlimited\n");
else
printf ("%ld\n", limit / limits[i].block_factor);
}
static void
print_specific_bsd_limits (cmd, mode)
int cmd, mode;
{
register int i;
for (i = 0; limits[i].option_cmd; i++)
if (cmd & limits[i].option_cmd)
print_bsd_limit (i, mode);
}
#endif /* HAVE_RESOURCE */
/* Print the limits corresponding to a specific set of resources. This is
called when an option string contains more than one character (e.g. -at),
because limits may not be specified with that kind of argument. */
static void
print_specific_limits (cmd, mode)
int cmd, mode;
{
if (mode == 0)
mode |= LIMIT_SOFT;
#if defined (HAVE_RESOURCE)
print_specific_bsd_limits (cmd, mode);
#else
if (cmd & u_FILE_SIZE)
printf ("%-25s%ld\n", "file size (blocks)", ulimit (1, 0L) / ULIMIT_DIVISOR);
#endif
if (cmd & u_PIPE_SIZE)
printf ("%-25s%ld\n", "pipe size (512 bytes)", (pipesize () / 512));
if (cmd & u_NUM_OPEN_FILES)
printf ("%-25s%ld\n", "open files", open_files (mode));
}
static void
print_all_limits (mode)
int mode;
{
if (mode == 0)
mode |= LIMIT_SOFT;
print_specific_limits (u_ALL_LIMITS, mode);
}

View File

@@ -0,0 +1,283 @@
This file is umask.def, from which is created umask.c.
It implements the builtin "umask" in Bash.
Copyright (C) 1987, 1989, 1991 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 1, 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; see the file COPYING. If not, write to the Free Software
Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
$PRODUCES umask.c
$BUILTIN umask
$FUNCTION umask_builtin
$SHORT_DOC umask [-S] [mode]
The user file-creation mask is set to MODE. If MODE is omitted, or if
`-S' is supplied, the current value of the mask is printed. The `-S'
option makes the output symbolic; otherwise an octal number is output.
If MODE begins with a digit, it is interpreted as an octal number,
otherwise it is a symbolic mode string like that accepted by chmod(1).
$END
#include <stdio.h>
#include <sys/types.h>
#include <sys/file.h>
#include "../shell.h"
#include "../posixstat.h"
/* **************************************************************** */
/* */
/* UMASK Builtin and Helpers */
/* */
/* **************************************************************** */
static void print_symbolic_umask ();
static int symbolic_umask ();
/* Set or display the mask used by the system when creating files. Flag
of -S means display the umask in a symbolic mode. */
umask_builtin (list)
WORD_LIST *list;
{
while (list)
{
if (strcmp (list->word->word, "-S") == 0)
{
int um;
um = umask (022);
umask (um);
print_symbolic_umask (um);
list = list->next;
continue;
}
else if (strcmp (list->word->word, "--") == 0)
{
list = list->next;
break;
}
else if (*(list->word->word) == '-')
{
bad_option (list->word->word);
return (-1);
}
else
break;
}
if (list)
{
int new_umask;
if (digit (*list->word->word))
{
new_umask = read_octal (list->word->word);
/* Note that other shells just let you set the umask to zero
by specifying a number out of range. This is a problem
with those shells. We don't change the umask if the input
is lousy. */
if (new_umask == -1)
{
builtin_error ("`%s' is not an octal number from 000 to 777",
list->word->word);
return (EXECUTION_FAILURE);
}
}
else
{
new_umask = symbolic_umask (list);
if (new_umask == -1)
return (EXECUTION_FAILURE);
}
umask (new_umask);
}
else
{
/* Display the UMASK for this user. */
int old_umask = umask (022);
umask (old_umask);
printf ("%03o\n", old_umask);
}
fflush (stdout);
return (EXECUTION_SUCCESS);
}
/* Print the umask in a symbolic form. In the output, a letter is
printed if the corresponding bit is clear in the umask. */
static void
print_symbolic_umask (um)
int um;
{
char ubits[4], gbits[4], obits[4]; /* u=rwx,g=rwx,o=rwx */
int i;
i = 0;
if ((um & S_IRUSR) == 0)
ubits[i++] = 'r';
if ((um & S_IWUSR) == 0)
ubits[i++] = 'w';
if ((um & S_IXUSR) == 0)
ubits[i++] = 'x';
ubits[i] = '\0';
i = 0;
if ((um & S_IRGRP) == 0)
gbits[i++] = 'r';
if ((um & S_IWGRP) == 0)
gbits[i++] = 'w';
if ((um & S_IXGRP) == 0)
gbits[i++] = 'x';
gbits[i] = '\0';
i = 0;
if ((um & S_IROTH) == 0)
obits[i++] = 'r';
if ((um & S_IWOTH) == 0)
obits[i++] = 'w';
if ((um & S_IXOTH) == 0)
obits[i++] = 'x';
obits[i] = '\0';
printf ("u=%s,g=%s,o=%s\n", ubits, gbits, obits);
}
/* Set the umask from a symbolic mode string similar to that accepted
by chmod. If the -S argument is given, then print the umask in a
symbolic form. */
static int
symbolic_umask (list)
WORD_LIST *list;
{
int um, umc, c;
int who, op, perm, mask;
char *s;
/* Get the initial umask. Don't change it yet. */
um = umask (022);
umask (um);
/* All work below is done with the complement of the umask -- its
more intuitive and easier to deal with. It is complemented
again before being returned. */
umc = ~um;
s = list->word->word;
for (;;)
{
who = op = perm = mask = 0;
/* Parse the `who' portion of the symbolic mode clause. */
while (member (*s, "agou"))
{
switch (c = *s++)
{
case 'u':
who |= S_IRWXU;
continue;
case 'g':
who |= S_IRWXG;
continue;
case 'o':
who |= S_IRWXO;
continue;
case 'a':
who |= S_IRWXU | S_IRWXG | S_IRWXO;
continue;
default:
break;
}
}
/* The operation is now sitting in *s. */
op = *s++;
switch (op)
{
case '+':
case '-':
case '=':
break;
default:
builtin_error ("bad symbolic mode operator: %c", op);
return (-1);
}
/* Parse out the `perm' section of the symbolic mode clause. */
while (member (*s, "rwx"))
{
c = *s++;
switch (c)
{
case 'r':
perm |= S_IRUGO;
break;
case 'w':
perm |= S_IWUGO;
break;
case 'x':
perm |= S_IXUGO;
break;
}
}
/* Now perform the operation or return an error for a
bad permission string. */
if (!*s || *s == ',')
{
if (who)
perm &= who;
switch (op)
{
case '+':
umc |= perm;
break;
case '-':
umc &= ~perm;
break;
case '=':
umc &= ~who;
umc |= perm;
break;
default:
builtin_error ("bad operation character: %c", op);
return (-1);
}
if (!*s)
{
um = ~umc & 0777;
break;
}
else
s++; /* skip past ',' */
}
else
{
builtin_error ("bad character in symbolic mode: %c", *s);
return (-1);
}
}
return (um);
}

View File

@@ -0,0 +1,133 @@
This file is wait.def, from which is created wait.c.
It implements the builtin "wait" in Bash.
Copyright (C) 1987, 1989, 1991 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 1, 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; see the file COPYING. If not, write to the Free Software
Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
$BUILTIN wait
$FUNCTION wait_builtin
$DEPENDS_ON JOB_CONTROL
$PRODUCES wait.c
$SHORT_DOC wait [n]
Wait for the specified process and report its termination status. If
N is not given, all currently active child processes are waited for,
and the return code is zero. N may be a process ID or a job
specification; if a job spec is given, all processes in the job's
pipeline are waited for.
$END
$BUILTIN wait
$FUNCTION wait_builtin
$DEPENDS_ON !JOB_CONTROL
$SHORT_DOC wait [n]
Wait for the specified process and report its termination status. If
N is not given, all currently active child processes are waited for,
and the return code is zero. N is a process ID; if it is not given,
all child processes of the shell are waited for.
$END
#include <sys/types.h>
#include <signal.h>
#include "../shell.h"
#include "../jobs.h"
#if defined (JOB_CONTROL)
extern int job_control;
#endif /* JOB_CONTROL */
/* Wait for the pid in LIST to stop or die. If no arguments are given, then
wait for all of the active background processes of the shell and return
0. If a list of pids or job specs are given, return the exit status of
the last one waited for. */
wait_builtin (list)
WORD_LIST *list;
{
extern void wait_for_background_pids ();
extern int wait_for_single_pid ();
extern int interrupt_immediately;
int status = EXECUTION_SUCCESS;
begin_unwind_frame ("wait_builtin");
unwind_protect_int (interrupt_immediately);
interrupt_immediately++;
/* We support jobs or pids.
wait <pid-or-job> [pid-or-job ...] */
/* But wait without any arguments means to wait for all of the shell's
currently active background processes. */
if (!list)
{
wait_for_background_pids ();
status = EXECUTION_SUCCESS;
goto return_status;
}
while (list)
{
pid_t pid;
if (digit (*(list->word->word)))
{
if (sscanf (list->word->word, "%d", &pid) == 1)
status = wait_for_single_pid (pid);
else
{
builtin_error
("`%s' is not a pid or job spec", list->word->word);
status = EXECUTION_FAILURE;
goto return_status;
}
}
#if defined (JOB_CONTROL)
else if (job_control)
/* Must be a job spec. Check it out. */
{
int job;
sigset_t set, oset;
BLOCK_CHILD (set, oset);
job = get_job_spec (list);
if (job < 0 || job >= job_slots || !jobs[job])
{
if (job != DUP_JOB)
builtin_error ("No such job %s", list->word->word);
UNBLOCK_CHILD (oset);
status = EXECUTION_FAILURE;
list = list->next;
continue;
}
/* Job spec used. Wait for the last pid in the pipeline. */
UNBLOCK_CHILD (oset);
status = wait_for_job (job);
}
#endif /* JOB_CONTROL */
else
{
builtin_error ("%s is not a pid or legal job spec",
list->word->word);
status = EXECUTION_FAILURE;
}
list = list->next;
}
return_status:
run_unwind_frame ("wait_builtin");
return (status);
}

124
bin/old/bash-1.11/config.h Normal file
View File

@@ -0,0 +1,124 @@
/* config.h -- Configuration file for bash. */
/* Copyright (C) 1987,1991 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 1, 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; see the file COPYING. If not, write to the Free
Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
#ifndef _CONFIG_
#define _CONFIG_
#ifndef VOID
#ifdef NO_VOID
#define VOID char
#else
#define VOID void
#endif
#endif
#if defined (__GNUC__)
# if !defined (HAVE_ALLOCA)
# define HAVE_ALLOCA
# endif /* HAVE_ALLOCA */
# if !defined (BUILDING_MAKEFILE)
# define alloca __builtin_alloca
# endif
#else
# if defined (HAVE_ALLOCA_H)
# if !defined (HAVE_ALLOCA)
# define HAVE_ALLOCA
# endif /* HAVE_ALLOCA */
# if !defined (BUILDING_MAKEFILE)
# include <alloca.h>
# endif
# endif /* HAVE_ALLOCA_H */
#endif /* __GNUC__ */
#if defined (HPUX) || defined (UNIXPC) || defined (Xenix)
# if !defined (USG)
# define USG
# endif
#endif
#if defined (HAVE_UNISTD_H) && !defined (BUILDING_MAKEFILE)
#include <unistd.h>
#endif
/* Define JOB_CONTROL if your operating system supports
BSD-like job control. */
#define JOB_CONTROL
/* Note that vanilla System V machines don't support BSD job control,
although some do support Posix job control. */
#if defined (USG) && !defined (_POSIX_JOB_CONTROL)
#undef JOB_CONTROL
#endif /* USG */
/* Define ALIAS if you want the alias features. */
#define ALIAS
/* Define PUSHD_AND_POPD if you want those commands to be compiled in.
(Also the `dirs' commands.) */
#define PUSHD_AND_POPD
/* Define READLINE to get the nifty/glitzy editing features.
This is on by default. You can turn it off interactively
with the -nolineediting flag. */
#define READLINE
/* If READLINE is defined, right now we assume that you have the full
source code. If you simply have the library and header files installed,
then undefine HAVE_READLINE_SOURCE. */
#if defined (READLINE)
# define HAVE_READLINE_SOURCE
#endif /* READLINE */
/* The default value of the PATH variable. */
#define DEFAULT_PATH_VALUE \
":/usr/gnu/bin:/usr/local/bin:/usr/ucb:/bin:/usr/bin:/etc:/usr/etc"
/* The value for PATH when invoking `command -p'. This is only used when
the Posix.2 confstr () function, or CS_PATH define are not present. */
#define STANDARD_UTILS_PATH \
"/bin:/usr/bin:/usr/ucb:/usr/sbin:/etc:/usr/etc"
/* Define V9_ECHO if you want to give the echo builtin backslash-escape
interpretation using the -e option, in the style of the Bell Labs 9th
Edition version of echo. */
#define V9_ECHO
/* Define CONTINUE_AFTER_KILL_ERROR if you want the kill command to
continue processing arguments after one of them fails. */
#define CONTINUE_AFTER_KILL_ERROR
/* Define BREAK_COMPLAINS if you want the non-standard, but useful
error messages about `break' and `continue' out of context. */
#define BREAK_COMPLAINS
/* Define GETOPTS_BUILTIN if you want the Posix.2 `getopts' shell builtin
compiled into the shell. */
#define GETOPTS_BUILTIN
/* When ALLOW_RIGID_POSIX_COMPLIANCE is defined, you can turn on strictly
Posix compliant behaviour by setting the environment variable
POSIX_PEDANTIC. */
#define ALLOW_RIGID_POSIX_COMPLIANCE
/* Define DISABLED_BUILTINS if you want "builtin foo" to always run the
shell builtin "foo", even if it has been disabled with "enable -n foo". */
/* #define DISABLED_BUILTINS */
#endif /* _CONFIG_ */

8
bin/old/bash-1.11/configure vendored Executable file
View File

@@ -0,0 +1,8 @@
#!/bin/sh
#
# This shell script does nothing since Bash doesn't require
# configuration to be forced on it; it auto-configures. You can
# change the location of the source directory with +srcdir.
#
echo "Bash is configured to auto configure."
exit 0

View File

@@ -0,0 +1,279 @@
/* copy_command.c -- copy a COMMAND structure. This is needed
primarily for making function definitions, but I'm not sure
that anyone else will need it. */
/* Copyright (C) 1987,1991 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 1, 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; see the file COPYING. If not, write to the Free
Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
#include <stdio.h>
#include "shell.h"
/* Forward declaration. */
extern COMMAND *copy_command ();
WORD_DESC *
copy_word (word)
WORD_DESC *word;
{
WORD_DESC *new_word = (WORD_DESC *)xmalloc (sizeof (WORD_DESC));
bcopy (word, new_word, sizeof (WORD_DESC));
new_word->word = savestring (word->word);
return (new_word);
}
/* Copy the chain of words in LIST. Return a pointer to
the new chain. */
WORD_LIST *
copy_word_list (list)
WORD_LIST *list;
{
WORD_LIST *new_list = NULL;
while (list)
{
WORD_LIST *temp = (WORD_LIST *)xmalloc (sizeof (WORD_LIST));
temp->next = new_list;
new_list = temp;
new_list->word = copy_word (list->word);
list = list->next;
}
return ((WORD_LIST *)reverse_list (new_list));
}
PATTERN_LIST *
copy_case_clause (clause)
PATTERN_LIST *clause;
{
PATTERN_LIST *new_clause = (PATTERN_LIST *)xmalloc (sizeof (PATTERN_LIST));
new_clause->patterns = copy_word_list (clause->patterns);
new_clause->action = copy_command (clause->action);
return (new_clause);
}
PATTERN_LIST *
copy_case_clauses (clauses)
PATTERN_LIST *clauses;
{
PATTERN_LIST *new_list = (PATTERN_LIST *)NULL;
while (clauses)
{
PATTERN_LIST *new_clause = copy_case_clause (clauses);
new_clause->next = new_list;
new_list = new_clause;
clauses = clauses->next;
}
return ((PATTERN_LIST *)reverse_list (new_list));
}
/* Copy a single redirect. */
REDIRECT *
copy_redirect (redirect)
REDIRECT *redirect;
{
REDIRECT *new_redirect = (REDIRECT *)xmalloc (sizeof (REDIRECT));
bcopy (redirect, new_redirect, (sizeof (REDIRECT)));
switch (redirect->instruction)
{
case r_reading_until:
case r_deblank_reading_until:
new_redirect->here_doc_eof = savestring (redirect->here_doc_eof);
/* There is NO BREAK HERE ON PURPOSE!!!! */
case r_appending_to:
case r_output_direction:
case r_input_direction:
case r_inputa_direction:
case r_err_and_out:
case r_input_output:
case r_output_force:
case r_duplicating_input_word:
case r_duplicating_output_word:
new_redirect->redirectee.filename =
copy_word (redirect->redirectee.filename);
break;
}
return (new_redirect);
}
REDIRECT *
copy_redirects (list)
REDIRECT *list;
{
REDIRECT *new_list = NULL;
while (list)
{
REDIRECT *temp = copy_redirect (list);
temp->next = new_list;
new_list = temp;
list = list->next;
}
return ((REDIRECT *)reverse_list (new_list));
}
FOR_COM *
copy_for_command (com)
FOR_COM *com;
{
FOR_COM *new_for = (FOR_COM *)xmalloc (sizeof (FOR_COM));
new_for->flags = com->flags;
new_for->name = copy_word (com->name);
new_for->map_list = copy_word_list (com->map_list);
new_for->action = copy_command (com->action);
return (new_for);
}
GROUP_COM *
copy_group_command (com)
GROUP_COM *com;
{
GROUP_COM *new_group = (GROUP_COM *)xmalloc (sizeof (GROUP_COM));
new_group->command = copy_command (com->command);
return (new_group);
}
CASE_COM *
copy_case_command (com)
CASE_COM *com;
{
CASE_COM *new_case = (CASE_COM *)xmalloc (sizeof (CASE_COM));
new_case->flags = com->flags;
new_case->word = copy_word (com->word);
new_case->clauses = copy_case_clauses (com->clauses);
return (new_case);
}
WHILE_COM *
copy_while_command (com)
WHILE_COM *com;
{
WHILE_COM *new_while = (WHILE_COM *)xmalloc (sizeof (WHILE_COM));
new_while->flags = com->flags;
new_while->test = copy_command (com->test);
new_while->action = copy_command (com->action);
return (new_while);
}
IF_COM *
copy_if_command (com)
IF_COM *com;
{
IF_COM *new_if = (IF_COM *)xmalloc (sizeof (IF_COM));
new_if->flags = com->flags;
new_if->test = copy_command (com->test);
new_if->true_case = copy_command (com->true_case);
new_if->false_case = copy_command (com->false_case);
return (new_if);
}
SIMPLE_COM *
copy_simple_command (com)
SIMPLE_COM *com;
{
SIMPLE_COM *new_simple = (SIMPLE_COM *)xmalloc (sizeof (SIMPLE_COM));
new_simple->flags = com->flags;
new_simple->words = copy_word_list (com->words);
new_simple->redirects = copy_redirects (com->redirects);
return (new_simple);
}
FUNCTION_DEF *
copy_function_def (com)
FUNCTION_DEF *com;
{
FUNCTION_DEF *new_def = (FUNCTION_DEF *)xmalloc (sizeof (FUNCTION_DEF));
new_def->name = copy_word (com->name);
new_def->command = copy_command (com->command);
return (new_def);
}
/* Copy the command structure in COMMAND. Return a pointer to the
copy. Don't you forget to dispose_command () on this pointer
later! */
COMMAND *
copy_command (command)
COMMAND *command;
{
COMMAND *new_command = (COMMAND *)NULL;
if (command)
{
new_command = (COMMAND *)xmalloc (sizeof (COMMAND));
bcopy (command, new_command, sizeof (COMMAND));
new_command->flags = command->flags;
if (command->redirects)
new_command->redirects = copy_redirects (command->redirects);
switch (command->type)
{
case cm_for:
new_command->value.For = copy_for_command (command->value.For);
break;
case cm_group:
new_command->value.Group = copy_group_command (command->value.Group);
break;
case cm_case:
new_command->value.Case = copy_case_command (command->value.Case);
break;
case cm_until:
case cm_while:
new_command->value.While = copy_while_command (command->value.While);
break;
case cm_if:
new_command->value.If = copy_if_command (command->value.If);
break;
case cm_simple:
new_command->value.Simple = copy_simple_command (command->value.Simple);
break;
case cm_connection:
{
CONNECTION *new_connection;
new_connection = (CONNECTION *)xmalloc (sizeof (CONNECTION));
new_connection->connector = command->value.Connection->connector;
new_connection->first =
copy_command (command->value.Connection->first);
new_connection->second =
copy_command (command->value.Connection->second);
new_command->value.Connection = new_connection;
break;
}
/* Pathological case. I'm not even sure that you can have a
function definition as part of a function definition. */
case cm_function_def:
new_command->value.Function_def =
copy_function_def (command->value.Function_def);
break;
}
}
return (new_command);
}

View File

@@ -0,0 +1,811 @@
/* This -*- C -*- file (cpp-Makefile) is run through the C preprocessor
to produce bash-Makefile which is machine specific.
If you have Gcc and/or Bison, you might wish to mention that right
below here.
Since this is to become a Makefile, blank lines which appear outside
of comments may not contain a TAB character.
Copyright (C) 1987,1991 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 1, 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; see the file COPYING. If not, write to the Free Software
Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
/**/# This Makefile is automagically made from cpp-Makefile. You should
/**/# not be editing this file; edit cpp-Makefile, machines.h, or
/**/# support/mksysdefs instead. Then, assuming the edits were required
/**/# to compile Bash on your system, mail the changes you had to make to
/**/# bash-maintainers@ai.mit.edu. We will do our best to incorporate
/**/# them into the next release.
/* **************************************************************** */
/* */
/* Which compiler are you using? */
/* */
/* **************************************************************** */
/* Define HAVE_GCC if you have the GNU C compiler. */
/* #define HAVE_GCC */
/* Define HAVE_FIXED_INCLUDES if you are using GCC with the fixed
header files. */
#if defined (HAVE_GCC) && !defined (HAVE_FIXED_INCLUDES)
/* #define HAVE_FIXED_INCLUDES */
#endif /* HAVE_GCC && !HAVE_FIXED_INCLUDES */
/* Define HAVE_BISON if you have the GNU replacement for Yacc. */
/**/# We would like you to use Bison instead of Yacc since some
/**/# versions of Yacc cannot handle reentrant parsing. Unfortunately,
/**/# this includes the Yacc currently being shipped with SunOS4.x.
/**/# If you do use Yacc, please make sure that any bugs in parsing
/**/# are not really manifestations of Yacc bugs before you report
/**/# them.
#define HAVE_BISON
/**/# Can be overidden on invocation.
MAKE = make
DESTDIR = /usr/gnu/bin
/* This includes the appropriate description for the machine that you are
using (we hope). If the compilation doesn't work correctly, then you
will have to edit the file `machines.h' to include a description for the
machine that your Cpp uniquely identifies this as. For example, Sun 4's
are recognized by the Cpp identifier `sparc', Vax is recognized with `vax',
etc. The order of these files is very important. Config.h must come last,
since it is capable of undef'ing various things. */
#define BUILDING_MAKEFILE /* Tell config.h to avoid #including anything. */
#include "sysdefs.h"
#include "machines.h"
#include "config.h"
/**/# Here is a rule for making .o files from .c files that does not
/**/# force the type of the machine (like -M_MACHINE) into the flags.
.c.o:
$(RM) $@
$(CC) $(CFLAGS) $(CPPFLAGS) -c $*.c
#if defined (HAVE_BISON)
BISON = bison -y
#else
BISON = yacc
#endif
#if defined (HAVE_GCC)
# if defined (GCC_FLAGS)
GCC_EXTRAS = GCC_FLAGS
# endif /* GCC_FLAGS */
# if !defined (HAVE_FIXED_INCLUDES)
/* This is guaranteed to work, even if you have the fixed includes!
(Unless, of course, you have the fixed include files installed in
/usr/include. Then it will break.) */
# if defined (isc386)
CC = gcc -traditional -posix -I/usr/include $(GCC_EXTRAS)
# else
CC = gcc -traditional -I/usr/include $(GCC_EXTRAS)
# endif /* isc386 */
# else /* HAVE_FIXED_INCLUDES */
# if defined (isc386)
CC = gcc -posix $(GCC_EXTRAS)
# else /* !isc386 */
CC = gcc $(GCC_EXTRAS)
# endif /* isc386 */
# endif /* HAVE_FIXED_INCLUDES */
#else /* !HAVE_GCC */
CC = CPP_CC
#endif /* !HAVE_GCC */
/**/# Of course, you cannot do this the first time through...
/**/#SHELL=$(DESTDIR)/bash
SHELL=/bin/sh
RM = rm -f
AR = ar
MACHINE = M_MACHINE
OS = M_OS
/**/# PROFILE_FLAGS is either -pg, to generate profiling info for use
/**/# with gprof, or nothing (the default).
PROFILE_FLAGS=
#if defined (HAVE_SHARED_LIBS) && defined (sun)
# if !defined (HAVE_GCC)
/**/# On Sun systems, we compile without shared libraries so we
/**/# can debug the shell with gdb.
NOSHARE = -Bstatic
# endif
#endif
#if defined (SYSDEP_CFLAGS)
/**/# This system has some peculiar flags that must be passed to the
/**/# the C compiler (or to cpp).
SYSDEP = SYSDEP_CFLAGS
#endif /* SYSDEP_CFLAGS */
#if defined (SYSDEP_LDFLAGS)
/**/# This system has some peculiar flags that must be passed to the
/**/# link editor (ld).
SYSDEP_LD = SYSDEP_LDFLAGS
#endif /* SYSDEP_LDFLAGS */
#if defined (HAVE_SETLINEBUF)
/**/# This system has the setlinebuf () call.
LINEBUF = -DHAVE_SETLINEBUF
#endif
#if defined (HAVE_VFPRINTF)
/**/# This system has the vprintf () and vfprintf () calls.
VPRINTF = -DHAVE_VFPRINTF
#endif /* HAVE_VFPRINTF */
#if defined (HAVE_UNISTD_H)
/**/# This system has <unistd.h>.
UNISTD = -DHAVE_UNISTD_H
#endif
#if defined (HAVE_GETGROUPS)
/**/# This system has multiple groups.
GROUPS = -DHAVE_GETGROUPS
#endif
#if defined (HAVE_RESOURCE)
/**/# This system has <sys/resource.h>
RESOURCE = -DHAVE_RESOURCE
#endif
#if defined (VOID_SIGHANDLER)
/**/# This system's signal () call returns a pointer to a function returning
/**/# void. The signal handlers themselves are thus void functions.
SIGHANDLER = -DVOID_SIGHANDLER
#endif
#if defined (HAVE_STRERROR)
/**/# This system has the strerror () function.
STRERROR = -DHAVE_STRERROR
#endif
#if defined (HAVE_WAIT_H)
/**/# This system has <sys/wait.h>
WAITH = -DHAVE_WAIT_H
#endif
#if defined (HAVE_GETWD)
/**/# This system has the getwd () call.
GETWD = -DHAVE_GETWD
#endif
#if defined (HAVE_DUP2)
/**/# This system has a working version of dup2 ().
DUP2 = -DHAVE_DUP2
#endif /* HAVE_DUP2 */
SYSTEM_FLAGS = $(LINEBUF) $(VPRINTF) $(UNISTD) $(GROUPS) $(RESOURCE) \
$(SIGHANDLER) $(SYSDEP) $(WAITH) $(GETWD) $(DUP2) $(STRERROR) \
-D$(MACHINE) -D$(OS)
DEBUG_FLAGS = $(PROFILE_FLAGS) -g
LDFLAGS = $(NOSHARE) $(SYSDEP_LD) $(EXTRA_LD_PATH) $(DEBUG_FLAGS)
CFLAGS = $(DEBUG_FLAGS) $(SYSTEM_FLAGS) -DSHELL $(ALLOCA_CFLAGS)
CPPFLAGS= -I$(LIBSRC)
/* It is conceviable that you wish to edit some things beyond this point,
but I guess that it is highly unlikely, and may give you a headache. */
/* **************************************************************** */
/* */
/* How to Build a Library */
/* */
/* **************************************************************** */
/* Defines used when building libraries. */
#define LIB_CFLAGS_DECL CFLAGS='$(LIBRARY_CFLAGS) '$(LIBINC_USAGE)
#define LIB_CPPFLAGS_DECL CPPFLAGS='$(CPPFLAGS)'
#define LIB_LDFLAGS_DECL LDFLAGS='$(LDFLAGS)'
#define LIBMAKE_FLAGS LIB_CFLAGS_DECL LIB_CPPFLAGS_DECL LIB_LDFLAGS_DECL \
RANLIB='$(RANLIB)' AR='$(AR)' CC='$(CC)'
/* Macro does library building. */
#define build_lib_in_dir(directory) \
@echo "Building in " directory "..."; \
($(LIBINC_DECL); cd directory; $(MAKE) $(MFLAGS) LIBMAKE_FLAGS)
/* The builtins are somewhat special in that more information is needed
to compile them correctly. */
#define build_builtins_in_dir(directory) \
($(LIBINC_DECL); cd directory; \
$(MAKE) $(MFLAGS) CPPFLAGS='$(CPPFLAGS)' \
CFLAGS='$(CFLAGS) '$(LIBINC_USAGE)' -I.' LDFLAGS='$(LDFLAGS)' \
RANLIB='$(RANLIB)' AR='$(AR)' CC='$(CC)' DIRECTDEFINE='-D 'directory)
/* Flags used when building libraries. */
LIBRARY_CFLAGS = $(DEBUG_FLAGS) $(SIGHANDLER) $(ALLOCA_CFLAGS) \
$(SYSDEP) -D$(MACHINE) -D$(OS) $(UNISTD) -DSHELL
/**/# These are required for sending bug reports.
SYSTEM_NAME = $(MACHINE)
OS_NAME = $(OS)
/**/# The name of this program.
PROGRAM = bash
/**/# The type of machine Bash is being compiled on.
HOSTTYPE_DECL = -DHOSTTYPE='$(SYSTEM_NAME)'
/**/# The default primary and secondary prompts.
PPROMPT = '"${PROGRAM}\\$$ "'
SPROMPT = '"> "'
#if defined (MAINTAINER)
bash_maintainer = MAINTAINER
MAINTAIN_DEFINE = -DMAINTAINER='"$(bash_maintainer)"'
#endif
/**/# The group of configuration flags. These are for shell.c
CFG_FLAGS = -DPPROMPT=$(PPROMPT) -DSPROMPT=$(SPROMPT) -DOS_NAME='"$(OS_NAME)"'\
-DSYSTEM_NAME='$(SYSTEM_NAME)' $(SIGLIST_FLAG) $(MAINTAIN_DEFINE)
/**/# The directory which contains the source for malloc. The name must
/**/# end in a slash, as in "./lib/malloc/".
ALLOC_DIR = ./lib/malloc/
/**/# Our malloc.
#if defined (USE_GNU_MALLOC)
MALLOC = $(ALLOC_DIR)malloc.o
MALLOC_DEP = $(ALLOC_DIR)malloc.c $(ALLOC_DIR)getpagesize.h
MALLOC_FLAGS = -Drcheck -Dbotch=programming_error
#endif /* USE_GNU_MALLOC */
/* If this user doesn't have alloca (), then we must try to supply them
with a working one. */
#if !defined (HAVE_ALLOCA)
ALLOCA = $(ALLOC_DIR)alloca.o
# if defined (ALLOCA_ASM)
ALLOCA_SOURCE = $(ALLOC_DIR)ALLOCA_ASM
# else
ALLOCA_SOURCE = $(ALLOC_DIR)alloca.c
# endif /* ALLOCA_ASM */
#endif /* !HAVE_ALLOCA */
/* Compilation flags to use in the shell directory and to pass to builds
in subdirectories (readline, termcap) to ensure that alloca is treated
in a consistent fashion. */
#if defined (HAVE_ALLOCA_H)
ALLOCA_H_DEFINE = -DHAVE_ALLOCA_H
#else
ALLOCA_H_DEFINE =
#endif /* HAVE_ALLOCA_H */
#if defined (HAVE_ALLOCA)
ALLOCA_DEFINE = -DHAVE_ALLOCA
#else
ALLOCA_DEFINE =
#endif /* HAVE_ALLOCA */
ALLOCA_CFLAGS = $(ALLOCA_DEFINE) $(ALLOCA_H_DEFINE)
/* Protect the `i386' used in the definition of ALLOC_FILES. */
#if defined (i386)
# undef i386
# define i386_defined
#endif /* i386 */
ALLOC_HEADERS = $(ALLOC_DIR)getpagesize.h
ALLOC_FILES = $(ALLOC_DIR)malloc.c $(ALLOC_DIR)alloca.c $(ALLOC_DIR)xmalloc.c \
$(ALLOC_DIR)i386-alloca.s $(ALLOC_DIR)x386-alloca.s
/* Perhaps restore the `i386' define. */
#if defined (i386_defined)
# define i386
# undef i386_defined
#endif /* i386_defined */
#if !defined (HAVE_SYS_SIGLIST)
/**/# Since this system does not have sys_siglist, we define SIGLIST
/**/# as siglist.o.
SIGLIST = siglist.o
SIGLIST_FLAG=-DINITIALIZE_SIGLIST
#endif /* HAVE_SYS_SIGLIST */
#if !defined (HAVE_GETCWD)
/**/# Since this system does not have a correctly working getcwd (), we
/**/# define GETCWD as getcwd.o.
GETCWD = getcwd.o
#endif /* !HAVE_GETCWD */
/**/# The location of ranlib on your system.
#if defined (RANLIB_LOCATION)
RANLIB = RANLIB_LOCATION
#else
RANLIB = ranlib
#endif /* RANLIB_LOCATION */
/**/# Support for the libraries required. Termcap, Glob, and Readline.
/**/# The location of sources for the support libraries.
LIBSRC = ./lib/
LIBINC_DECL = LIBINCDIR=`pwd`; export LIBINCDIR
LIBINC_USAGE = "-I$${LIBINCDIR} -I$${LIBINCDIR}/$(LIBSRC)"
/* Does this machine's linker need a space after -L? */
#if defined (HAVE_GCC)
# undef SEARCH_LIB_NEEDS_SPACE
#endif /* HAVE_GCC */
#if defined (SEARCH_LIB_NEEDS_SPACE)
/**/# The native compiler for this machines requires a space after '-L'.
SEARCH_LIB = -L $(UNSET_VARIABLE_CREATES_SPACE)
#else
SEARCH_LIB = -L
#endif /* !SEARCH_LIB_NEEDS_SPACE */
#if defined (EXTRA_LIB_SEARCH_PATH)
LOCAL_LD_PATH = EXTRA_LIB_SEARCH_PATH
EXTRA_LD_PATH = $(SEARCH_LIB)$(LOCAL_LD_PATH)
#endif /* EXTRA_LIB_SEARCH_PATH */
RLIBSRC = $(LIBSRC)readline/
RLIBDOC = $(RLIBSRC)doc/
/**/# The source, object and documentation of the history library.
HISTORY_SOURCE = $(RLIBSRC)history.c $(RLIBSRC)history.h
HISTORY_OBJ = $(RLIBSRC)history.o
HISTORY_DOC = $(RLIBDOC)hist.texinfo $(RLIBDOC)hsuser.texinfo \
$(RLIBDOC)hstech.texinfo
/**/# The source, object and documentation of the GNU Readline library.
/**/# The source to the history library is inherently part of this.
READLINE_SOURCE = $(RLIBSRC)readline.c $(RLIBSRC)readline.h\
$(RLIBSRC)chardefs.h $(RLIBSRC)keymaps.h\
$(RLIBSRC)funmap.c $(RLIBSRC)emacs_keymap.c\
$(RLIBSRC)vi_keymap.c $(RLIBSRC)keymaps.c\
$(RLIBSRC)vi_mode.c $(GLIBSRC)tilde.c $(HISTORY_SOURCE)
READLINE_OBJ = $(RLIBSRC)readline.o $(RLIBSRC)funmap.o \
$(RLIBSRC)keymaps.o $(GLIBSRC)tilde.o $(HISTORY_OBJ)
READLINE_DOC = $(RLIBDOC)rlman.texinfo $(RLIBDOC)rluser.texinfo \
$(RLIBDOC)rltech.texinfo
READLINE_DOC_SUPPORT = $(RLIBDOC)Makefile $(RLIBDOC)texinfo.tex \
$(RLIBDOC)texindex.c $(RLIBDOC)readline.dvi \
$(RLIBDOC)readline.info $(RLIBDOC)history.dvi \
$(RLIBDOC)history.info
/**/# This has to be written funny to avoid looking like a C comment starter.
READLINE_EXAMPLES = $(RLIBSRC)examples/[a-zA-Z]*.[ch] \
$(RLIBSRC)examples/Makefile $(RLIBSRC)examples/Inputrc
/**/# Support files for GNU Readline.
READLINE_SUPPORT = $(RLIBSRC)Makefile $(RLIBSRC)ChangeLog $(RLIBSRC)COPYING \
$(READLINE_EXAMPLES) $(READLINE_DOC_SUPPORT)
#if defined (HAVE_READLINE_SOURCE)
READLINE_CFLAGS = $(DEBUG_FLAGS) $(SIGHANDLER) $(ALLOCA_CFLAGS) \
$(SYSDEP) -D$(MACHINE) -D$(OS) $(UNISTD)
#define READLINE_LIBRARY ./lib/readline/libreadline.a
#else
#define READLINE_LIBRARY -lreadline
#endif
#if defined (USE_GNU_TERMCAP)
#define HAVE_TERMCAP_SOURCE
/**/# The source, object and documentation for the GNU Termcap library.
TLIBSRC = $(LIBSRC)termcap/
#define TERMCAP_LIBRARY ./lib/termcap/libtermcap.a
TERMCAP_SOURCE = $(TLIBSRC)termcap.c $(TLIBSRC)tparam.c
TERMCAP_OBJ = $(TLIBSRC)libtermcap.a
TERMCAP_DOC = $(TLIBSRC)termcap.texinfo
TERMCAP_SUPPORT = $(TLIBSRC)Makefile $(TLIBSRC)ChangeLog
TERMCAP_LDFLAGS = $(SEARCH_LIB)$(TLIBSRC)
#endif /* USE_GNU_TERMCAP */
/* The glob library is always used. */
#define USE_GLOB_LIBRARY
/* If we have the source to the glob library, then compile it. */
#if defined (USE_GLOB_LIBRARY)
GLIBSRC = $(LIBSRC)glob/
#define GLOB_LIBRARY ./lib/glob/libglob.a
/* Sometime in the future, we will have the finished GNU C Library globber. */
#if defined (POSIX_GLOBBING_SOURCE)
GLOB_SOURCE = $(GLIBSRC)glob.c $(GLIBSRC)fnmatch.c $(GLIBSRC)tilde.c \
$(GLIBSRC)glob.h $(GLIBSRC)ndir.h $(GLIBSRC)fnmatch.h
#else
GLOB_SOURCE = $(GLIBSRC)glob.c $(GLIBSRC)tilde.c \
$(GLIBSRC)fnmatch.c $(GLIBSRC)fnmatch.h
#endif /* POSIX_GLOBBING_SOURCE */
GLOB_OBJ = $(GLIBSRC)libglob.a
GLOB_DOC = $(GLIBSRC)glob.texinfo
GLOB_SUPPORT = $(GLIBSRC)Makefile $(GLIBSRC)ChangeLog
GLOB_LDFLAGS = $(SEARCH_LIB)$(GLIBSRC)
GLOB_LIB = -lglob
#endif /* USE_GLOB_LIBRARY */
/**/# Declare all of the sources for the libraries that we have.
LIBRARY_SOURCE = $(READLINE_SOURCE) $(TERMCAP_SOURCE) $(GLOB_SOURCE)
LIBRARY_DOC = $(READLINE_DOC) $(HISTORY_DOC) $(TERMCAP_DOC) $(GLOB_DOC)
LIBRARY_SUPPORT = $(READLINE_SUPPORT) $(TERMCAP_SUPPORT) $(GLOB_SUPPORT)
LIBRARY_TAR = $(LIBRARY_SOURCE) $(LIBRARY_DOC) $(LIBRARY_SUPPORT)
#if defined (READLINE)
/**/# You wish to compile with the line editing features installed.
READLINE_LIB = -lreadline
/**/# You only need termcap for readline.
#if defined (USE_TERMCAP_EMULATION)
TERMCAP_LIB = -lcurses
#else
TERMCAP_LIB = -ltermcap
#endif /* USE_TERMCAP_EMULATION */
/**/# Directory list for -L so that the link editor (ld) can find -lreadline.
#if defined (HAVE_READLINE_SOURCE)
READLINE_LDFLAGS = $(SEARCH_LIB)$(RLIBSRC) $(TERMCAP_LDFLAGS)
#else
READLINE_LDFLAGS = $(TERMCAP_LDFLAGS) $(SEARCH_LIB)/usr/gnu/lib \
$(SEARCH_LIB)/usr/local/lib
#endif /* HAVE_READLINE_SOURCE */
/**/# The source and object of the bash<->readline interface code.
RL_SUPPORT_SRC = bashline.c
RL_SUPPORT_OBJ = bashline.o
#endif /* READLINE */
#if defined (REQUIRED_LIBRARIES)
/**/# Locally required libraries.
LOCAL_LIBS = REQUIRED_LIBRARIES
#endif /* REQUIRED_LIBRARIES */
/**/# The order is important. Most dependent first.
LIBRARIES = $(READLINE_LIB) $(TERMCAP_LIB) $(GLOB_LIB) $(LOCAL_LIBS)
#if defined (HAVE_TERMCAP_SOURCE)
TERMCAP_DEP = TERMCAP_LIBRARY
#endif
#if defined (HAVE_READLINE_SOURCE)
READLINE_DEP = READLINE_LIBRARY
#endif
#if defined (USE_GLOB_LIBRARY)
GLOB_DEP = GLOB_LIBRARY
#else
GLOBC = glob.c tilde.c
GLOBO = glob.o tilde.o
#endif /* USE_GLOB_LIBRARY */
/**/# Source files for libraries that Bash depends on.
LIBDEP = $(READLINE_DEP) $(TERMCAP_DEP) $(GLOB_DEP)
/**/# Rules for cleaning the readline and termcap sources.
#if defined (HAVE_READLINE_SOURCE)
# define CLEAN_READLINE (cd $(RLIBSRC); $(MAKE) $(MFLAGS) clean)
#else
# define CLEAN_READLINE :
#endif /* HAVE_READLINE_SOURCE */
#if defined (HAVE_TERMCAP_SOURCE)
# define CLEAN_TERMCAP (cd $(TLIBSRC); $(MAKE) $(MFLAGS) clean)
#else
# define CLEAN_TERMCAP :
#endif /* HAVE_TERMCAP_SOURCE */
#if defined (USE_GLOB_LIBRARY)
# define CLEAN_GLOB (cd $(GLIBSRC); $(MAKE) $(MFLAGS) clean)
#else
# define CLEAN_GLOB :
#endif /* USE_GLOB_LIBRARY */
BUILTINS_LIB = builtins/libbuiltins.a
/**/# The main source code for the Bourne Again SHell.
CSOURCES = shell.c parse.y general.c make_cmd.c print_cmd.c y.tab.c \
dispose_cmd.c execute_cmd.c variables.c $(GLOBC) version.c \
expr.c copy_cmd.c flags.c subst.c hash.c mailcheck.c \
test.c trap.c jobs.c nojobs.c $(ALLOC_FILES) braces.c \
unwind_prot.c siglist.c getcwd.c $(RL_SUPPORT_SRC)
HSOURCES = shell.h flags.h trap.h hash.h jobs.h builtins.h alias.c y.tab.h \
general.h variables.h config.h $(ALLOC_HEADERS) alias.h maxpath.h \
quit.h machines.h posixstat.h filecntl.h unwind_prot.h
SOURCES = $(CSOURCES) $(HSOURCES) $(BUILTIN_DEFS)
/**/# Matching object files.
OBJECTS = shell.o y.tab.o general.o make_cmd.o print_cmd.o $(GLOBO) \
dispose_cmd.o execute_cmd.o variables.o copy_cmd.o \
expr.o flags.o jobs.o subst.o hash.o mailcheck.o test.o \
trap.o alias.o $(MALLOC) $(ALLOCA) braces.o unwind_prot.o \
$(SIGLIST) $(GETCWD) version.o $(RL_SUPPORT_OBJ) $(BUILTINS_LIB)
/**/# Where the source code of the shell builtins resides.
DEFDIR = builtins/
BUILTIN_DEFS = $(DEFDIR)alias.def $(DEFDIR)bind.def $(DEFDIR)break.def \
$(DEFDIR)builtin.def $(DEFDIR)cd.def $(DEFDIR)colon.def \
$(DEFDIR)command.def $(DEFDIR)declare.def \
$(DEFDIR)echo.def $(DEFDIR)enable.def $(DEFDIR)eval.def \
$(DEFDIR)exec.def $(DEFDIR)exit.def $(DEFDIR)fc.def \
$(DEFDIR)fg_bg.def $(DEFDIR)hash.def $(DEFDIR)help.def \
$(DEFDIR)history.def $(DEFDIR)jobs.def $(DEFDIR)kill.def \
$(DEFDIR)let.def $(DEFDIR)read.def $(DEFDIR)return.def \
$(DEFDIR)set.def $(DEFDIR)setattr.def $(DEFDIR)shift.def \
$(DEFDIR)source.def $(DEFDIR)suspend.def $(DEFDIR)test.def \
$(DEFDIR)times.def $(DEFDIR)trap.def $(DEFDIR)type.def \
$(DEFDIR)ulimit.def $(DEFDIR)umask.def $(DEFDIR)wait.def \
$(DEFDIR)getopts.def $(DEFDIR)reserved.def
BUILTIN_C_CODE = $(DEFDIR)mkbuiltins.c $(DEFDIR)common.c \
$(DEFDIR)hashcom.h $(GETOPT_SOURCE)
GETOPT_SOURCE = $(DEFDIR)getopt.c $(DEFDIR)getopt.h
PSIZE_SOURCE = $(DEFDIR)psize.sh $(DEFDIR)psize.c
BUILTIN_SUPPORT = $(DEFDIR)Makefile $(DEFDIR)ChangeLog $(PSIZE_SOURCE) \
$(BUILTIN_C_CODE)
/**/# Documentation for the shell.
DOCDIR = ./documentation/
BASH_TEXINFO = $(DOCDIR)*.texi $(DOCDIR)*.tex $(DOCDIR)texindex.c \
$(DOCDIR)*.dvi $(DOCDIR)Makefile
BASH_MAN = $(DOCDIR)bash.1
BASHDOCS = $(BASH_TEXINFO) $(BASH_MAN) INSTALL README RELEASE
DOCUMENTATION = $(BASHDOCS) $(LIBRARY_DOC)
/**/# Some example files demonstrating use of the shell.
/* This has to be written funny to avoid looking like a comment starter. */
EXAMPLES = examples/[a-zA-Z]*
ENDIAN_SUPPORT = endian.c
SDIR = ./support/
MKTARFILE = $(SDIR)mktarfile
SCRIPTS_SUPPORT = $(SDIR)mksysdefs $(SDIR)cppmagic $(SDIR)cat-s \
$(MKTARFILE) $(SDIR)mail-shell $(SDIR)inform
TEST_SUITE = ./test-suite/
TEST_SUITE_SUPPORT = $(TEST_SUITE)[a-zA-Z0-9]*
CREATED_SUPPORT = endian.aux endian.h sysdefs.h $(SDIR)getcppsyms
SUPPORT = configure $(ENDIAN_SUPPORT) $(SCRIPTS_SUPPORT) $(BUILTIN_SUPPORT) \
COPYING Makefile cpp-Makefile ChangeLog .distribution newversion.c \
$(EXAMPLES) $(SDIR)bash.xbm $(SDIR)getcppsyms.c $(TEST_SUITE_SUPPORT)
/**/# BAGGAGE consists of things that you want to keep with the shell for some
/**/# reason, but do not actually use; old source code, etc.
BAGGAGE = longest_sig.c
/**/# Things that the world at large needs.
THINGS_TO_TAR = $(SOURCES) $(LIBRARY_TAR) $(BASHDOCS) $(SUPPORT) $(BAGGAGE)
all: .made
/**/# Keep GNU Make from exporting the entire environment for small machines.
.NOEXPORT:
.made: $(PROGRAM)
cp .machine .made
$(PROGRAM): .build $(OBJECTS) $(LIBDEP) .distribution
$(RM) $@
$(CC) $(LDFLAGS) $(READLINE_LDFLAGS) $(GLOB_LDFLAGS) \
-o $(PROGRAM) $(OBJECTS) $(LIBRARIES)
.build: $(SOURCES) cpp-Makefile newversion.aux
if ./newversion.aux -build; then mv -f newversion.h version.h; fi
@echo
@echo " ***************************************************"
@echo " * *"
@echo " * Making Bash-`cat .distribution` for a $(MACHINE) running $(OS)."
@echo " * *"
@echo " ***************************************************"
@echo
@echo "$(PROGRAM) last made for a $(MACHINE) running $(OS)" >.machine
version.h: newversion.aux
if ./newversion.aux -build; then mv -f newversion.h version.h; fi
y.tab.c: parse.y shell.h
-if test -f y.tab.h; then mv -f y.tab.h old-y.tab.h; fi
@echo "Expect 12 reduce/reduce errors. No Problem."
$(BISON) -d parse.y
-if cmp -s old-y.tab.h y.tab.h; then mv old-y.tab.h y.tab.h; fi
#if defined (HAVE_READLINE_SOURCE)
READLINE_LIBRARY: $(READLINE_SOURCE)
build_lib_in_dir ($(RLIBSRC))
#endif /* HAVE_READLINE_SOURCE */
#if defined (HAVE_TERMCAP_SOURCE)
TERMCAP_LIBRARY: $(TERMCAP_SOURCE)
build_lib_in_dir ($(TLIBSRC))
#endif /* HAVE_TERMCAP_SOURCE */
#if defined (USE_GLOB_LIBRARY)
GLOB_LIBRARY: $(GLOB_SOURCE)
build_lib_in_dir ($(GLIBSRC))
#endif /* USE_GLOB_LIBRARY */
version.o: version.h version.c
shell.o: shell.h flags.h shell.c posixstat.h filecntl.h endian.h
$(CC) $(CFG_FLAGS) $(CFLAGS) $(CPPFLAGS) -c shell.c
endian.h: endian.aux
./endian.aux endian.h
endian.aux: endian.c
$(CC) $(CFLAGS) -o $@ endian.c
#if defined (USE_GNU_MALLOC)
/* Note that gcc correctly leaves the output file in the source directory. */
#if !defined (__GNUC__)
$(MALLOC): $(MALLOC_DEP)
$(CC) -I$(ALLOC_DIR) $(CFLAGS) $(MALLOC_FLAGS) -c $*.c
@-mv `basename $*`.o $(MALLOC) 2>/dev/null
#else
$(MALLOC): $(MALLOC_DEP)
$(CC) -I$(ALLOC_DIR) $(CFLAGS) $(MALLOC_FLAGS) \
-o $(MALLOC) -c $*.c
#endif /* __GNUC__ */
#endif /* USE_GNU_MALLOC */
#if !defined (HAVE_ALLOCA)
/* Note that gcc correctly leaves the output file in the source directory. */
$(ALLOCA): $(ALLOCA_SOURCE)
$(CC) -I$(ALLOC_DIR) $(CFLAGS) -c $(ALLOCA_SOURCE)
@-mv `basename $*`.o $(ALLOCA) >/dev/null 2>&1
#endif /* !HAVE_ALLOCA */
variables.o: shell.h hash.h flags.h variables.h variables.c
$(CC) -c $(CFLAGS) $(CPPFLAGS) $(HOSTTYPE_DECL) variables.c
builtins/libbuiltins.a: $(BUILTIN_DEFS) $(BUILTIN_C_CODE)
build_builtins_in_dir ($(DEFDIR))
/* Dependencies for the main bash source. */
shell.h: general.h variables.h config.h quit.h
jobs.h: endian.h quit.h
variables.h: hash.h
braces.o: general.h
copy_cmd.o: shell.h hash.h
copy_cmd.o: general.h variables.h config.h quit.h
dispose_cmd.o: shell.h
dispose_cmd.o: general.h variables.h config.h quit.h
execute_cmd.o: shell.h y.tab.h posixstat.h flags.h jobs.h
execute_cmd.o: general.h variables.h config.h quit.h hash.h endian.h
execute_cmd.o: unwind_prot.h
expr.o: shell.h hash.h
expr.o: general.h variables.h config.h quit.h
flags.o: flags.h config.h general.h quit.h
general.o: shell.h maxpath.h
general.o: general.h variables.h config.h quit.h
hash.o: shell.h hash.h
hash.o: general.h variables.h config.h quit.h
jobs.o: shell.h hash.h trap.h jobs.h
jobs.o: general.h variables.h config.h endian.h quit.h
mailcheck.o: posixstat.h maxpath.h variables.h
mailcheck.o: hash.h quit.h
make_cmd.o: shell.h flags.h
make_cmd.o: general.h variables.h config.h quit.h
y.tab.o: shell.h flags.h maxpath.h
y.tab.o: general.h variables.h config.h quit.h
print_cmd.o: shell.h y.tab.h
print_cmd.o: general.h variables.h config.h quit.h
shell.o: shell.h flags.h
shell.o: general.h variables.h config.h quit.h
subst.o: shell.h flags.h alias.h jobs.h
subst.o: general.h variables.h config.h endian.h quit.h
test.o: posixstat.h
trap.o: trap.h shell.h hash.h unwind_prot.h
trap.o: general.h variables.h config.h quit.h
unwind_prot.o: config.h general.h unwind_prot.h
#if !defined (JOB_CONTROL)
jobs.o: nojobs.c
#endif
#if defined (READLINE)
bashline.o: shell.h hash.h builtins.h
bashline.o: general.h variables.h config.h quit.h alias.h
#endif
/* Dependencies which rely on the user using the source to READLINE. */
#if defined (HAVE_READLINE_SOURCE)
bashline.o: $(RLIBSRC)chardefs.h $(RLIBSRC)history.h $(RLIBSRC)readline.h
bashline.o: $(RLIBSRC)keymaps.h $(RLIBSRC)history.h
y.tab.o: $(RLIBSRC)keymaps.h $(RLIBSRC)chardefs.h $(RLIBSRC)history.h
y.tab.o: $(RLIBSRC)readline.h
subst.o: $(RLIBSRC)history.h
#endif /* HAVE_READLINE_SOURCE */
#if defined (USE_GLOB_LIBRARY)
subst.o: $(GLIBSRC)fnmatch.h
execute_cmd.o: $(GLIBSRC)fnmatch.h
# if defined (POSIX_GLOBBING_SOURCE)
subst.o: $(GLIBSRC)glob.h
# endif /* POSIX_GLOBBING_SOURCE */
#endif /* USE_GLOB_LIBRARY */
$(PROGRAM).tar: $(THINGS_TO_TAR) .distribution
@$(MKTARFILE) $(PROGRAM) `cat .distribution` $(THINGS_TO_TAR)
$(PROGRAM).tar.Z: $(PROGRAM).tar
compress -f $(PROGRAM).tar
clone: $(THINGS_TO_TAR)
@$(MKTARFILE) +notar $(MACHINE) $(OS) $(THINGS_TO_TAR)
install: .made
-if [ -f $(DESTDIR)/$(PROGRAM) ]; \
then mv $(DESTDIR)/$(PROGRAM) $(DESTDIR)/$(PROGRAM).old; \
fi
cp $(PROGRAM) $(DESTDIR)/$(PROGRAM)
$(RM) installed-$(PROGRAM)
ln -s $(DESTDIR)/$(PROGRAM) installed-$(PROGRAM)
mailable: distribution
/bin/rm -rf uuencoded
mkdir uuencoded
$(SHELL) -c 'f=$(PROGRAM)-`cat .distribution`.tar.Z;uuencode $$f $$f | split -800 - uuencoded/$$f.uu.'
.distribution:
./newversion.aux -dist `$(PROGRAM) -c 'echo $$BASH_VERSION'`
distribution: $(PROGRAM) $(PROGRAM).tar.Z .distribution
@echo cp $(PROGRAM).tar.Z $(PROGRAM)-`cat .distribution`.tar.Z
@cp $(PROGRAM).tar.Z $(PROGRAM)-`cat .distribution`.tar.Z
newversion.aux: newversion.c
$(CC) $(DEBUG_FLAGS) -o newversion.aux newversion.c -lm
newversion: newversion.aux
$(RM) .build
./newversion.aux -dist
mv -f newversion.h version.h
$(MAKE) $(MFLAGS)
documentation: documentation-frob
(cd $(DOCDIR); make)
documentation-frob:
tags: $(SOURCES) $(BUILTIN_C_CODE) $(LIBRARY_SOURCE)
etags $(SOURCES) $(BUILTIN_C_CODE) $(LIBRARY_SOURCE)
INDEX: $(SOURCES) $(BUILTIN_C_CODE) $(LIBRARY_SOURCE)
ctags -x $(SOURCES) $(BUILTIN_C_CODE) $(LIBRARY_SOURCE) > $@
clean:
$(RM) $(OBJECTS) $(PROGRAM) aix-Makefile *.aux
$(RM) .build .made version.h
$(RM) $(CREATED_SUPPORT) bash-Makefile
(cd $(DOCDIR); $(MAKE) $(MFLAGS) clean)
(cd builtins; $(MAKE) $(MFLAGS) clean)
CLEAN_READLINE;CLEAN_TERMCAP;CLEAN_GLOB
/**/# Here is a convenient rule when you arrive at a new site and wish to
/**/# install bash on several different architectures. It creates a new
/**/# directory to hold the results of compilatation. The directory is
/**/# named MACHINE-OS.
architecture: $(MACHINE)-$(OS)/$(PROGRAM)
$(MACHINE)-$(OS):
-mkdir $(MACHINE)-$(OS)
$(MACHINE)-$(OS)/$(PROGRAM): $(MACHINE)-$(OS) $(PROGRAM)
mv $(PROGRAM) $(MACHINE)-$(OS)
mv sysdefs.h $(MACHINE)-$(OS)
mv $(SDIR)getcppsyms $(MACHINE)-$(OS)
$(MAKE) $(MFLAGS) clean

View File

@@ -0,0 +1,184 @@
/* dispose_command.c -- dispose of a COMMAND structure. */
/* Copyright (C) 1987,1991 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 1, 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; see the file COPYING. If not, write to the Free
Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
#include "shell.h"
/* Dispose of the command structure passed. */
void
dispose_command (command)
register COMMAND *command;
{
if (!command) return;
if (command->redirects)
dispose_redirects (command->redirects);
switch (command->type)
{
case cm_for:
{
register FOR_COM *c = command->value.For;
dispose_word (c->name);
dispose_words (c->map_list);
dispose_command (c->action);
free (c);
break;
}
case cm_group:
{
dispose_command (command->value.Group->command);
break;
}
case cm_case:
{
register CASE_COM *c = command->value.Case;
PATTERN_LIST *t, *p = c->clauses;
dispose_word (c->word);
while (p) {
dispose_words (p->patterns);
dispose_command (p->action);
t = p;
p = p->next;
free (t);
}
break;
}
case cm_until:
case cm_while:
{
register WHILE_COM *c = command->value.While;
dispose_command (c->test);
dispose_command (c->action);
free (c);
break;
}
case cm_if:
{
register IF_COM *c = command->value.If;
dispose_command (c->test);
dispose_command (c->true_case);
dispose_command (c->false_case);
free (c);
break;
}
case cm_simple:
{
register SIMPLE_COM *c = command->value.Simple;
dispose_words (c->words);
dispose_redirects (c->redirects);
free (c);
break;
}
case cm_connection:
{
register CONNECTION *c = command->value.Connection;
dispose_command (c->first);
dispose_command (c->second);
free (c);
break;
}
case cm_function_def:
{
register FUNCTION_DEF *c = command->value.Function_def;
dispose_word (c->name);
dispose_command (c->command);
free (c);
break;
}
default:
report_error ("Attempt to free unknown command type `%d'.\n", command->type);
break;
}
free (command);
}
/* How to free a WORD_DESC. */
dispose_word (word)
WORD_DESC *word;
{
free (word->word);
free (word);
}
/* How to get rid of a linked list of words. A WORD_LIST. */
dispose_words (list)
WORD_LIST *list;
{
WORD_LIST *t;
while (list)
{
t = list;
list = list->next;
dispose_word (t->word);
free (t);
}
}
/* How to dispose of an array of pointers to char. */
dispose_word_array (array)
char **array;
{
register int count;
for (count = 0; array[count]; count++)
free (array[count]);
free (array);
}
/* How to dispose of an list of redirections. A REDIRECT. */
dispose_redirects (list)
REDIRECT *list;
{
register REDIRECT *t;
while (list)
{
t = list;
list = list->next;
switch (t->instruction)
{
case r_reading_until:
case r_deblank_reading_until:
free (t->here_doc_eof);
/* ... */
case r_output_direction:
case r_input_direction:
case r_inputa_direction:
case r_appending_to:
case r_err_and_out:
case r_input_output:
case r_output_force:
case r_duplicating_input_word:
case r_duplicating_output_word:
dispose_word (t->redirectee.filename);
break;
}
free (t);
}
}

View File

@@ -0,0 +1,29 @@
# This Makefile is for the Bash/documentation directory -*- text -*-.
#
all: features.dvi features.info bash.txt
features.dvi: features.texi
tex features.texi
texindex features.??
tex features.texi
features.info: features.texi
makeinfo features.texi
bash.dvi: bash.texinfo
tex bash.texinfo
texindex bash.??
tex bash.texinfo
bash.txt: bash.1
nroff -man bash.1 >bash.txt
clean:
rm -f *.aux *.cp *.fn *.ky *.log *.pg *.toc *.tp *.vr *.cps *.pgs \
*.fns *.kys *.tps *.vrs *.o core texindex
squeaky-clean:
rm -f *.aux *.cp *.fn *.ky *.log *.pg *.toc *.tp *.vr *.cps *.pgs \
*.dvi *.info *.info-* *.fns *.kys *.tps *.vrs *.o core texindex

File diff suppressed because it is too large Load Diff

Binary file not shown.

View File

@@ -0,0 +1,851 @@
\input texinfo.tex @c -*- texinfo -*-
@c %**start of header
@setfilename features.info
@settitle Bash Features
@c %**end of header
@setchapternewpage odd
@synindex fn cp
@set BashFeatures
@ifinfo
@format
This text is a cursory description of the features that are present in
the Bash shell.
Copyright (C) 1991 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 1, 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; see the file COPYING. If not, write to the Free
Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
@end format
@end ifinfo
@titlepage
@sp 10
@center @titlefont{Bash Features}
@center Cursory Documentation for Bash
@center Brian Fox, Free Software Foundation
@page
@vskip 0pt plus 1filll
Copyright @copyright{} 1991 Free Software Foundation, Inc.
@end titlepage
@ifinfo
@node Top
@top Bash Features
Bash contains features that appear in other popular shells, and some
features that only appear in Bash. Some of the shells that Bash has
borrowed concepts from are the Bourne Shell (@file{sh}), the Korn Shell
(@file{ksh}), and the C-shell (@file{csh} and its successor,
@file{tcsh}). The following menu breaks the features up into
categories based upon which one of these other shells inspired the
feature.
@menu
* Bourne Shell Features:: Features originally found in the
Bourne shell.
* T-Csh Features:: Features originally found in the
Berkeley C-Shell.
* Korn Shell Features:: Features originally found in the Korn
Shell.
* Bash Specific Features:: Features found only in the Bash Shell.
* Using History Interactively:: Chapter dealing with history expansion
rules.
* Command Line Editing:: Chapter describing the command line
editing features.
* Variable Index:: Quick reference helps you find the
variable you want.
* Concept Index:: General index for this manual.
@end menu
@end ifinfo
@node Bourne Shell Features
@chapter Bourne Shell Style Features
Bash is an acronym for Bourne Again SHell, the traditional Unix shell
written by Stephen Bourne. All of the Bourne shell builtin commands are
available in Bash, and the rules for evaluation and quoting are taken
from the Posix 1003 specification for the `standard' Unix shell.
The shell builtin control features are briefly discussed here.
@menu
* Looping Constructs:: Shell commands for iterative action.
* Conditional Constructs:: Shell commands for conditional execution.
@end menu
@node Looping Constructs
@section Looping Constructs
Note that wherever you see an @samp{;} in the description of a
command's syntax, it can be replaced indiscriminately with newlines.
Bash supports the following looping constructs.
@ftable @code
@item until
The syntax of the @code{until} command is:
@example
until @var{test-commands}; do @var{consequent-commands}; done
@end example
Execute @var{consequent-commands} as long as the final command in
@var{test-commands} has an exit status which is not zero.
@item while
The syntax of the @code{while} command is:
@example
while @var{test-commands}; do @var{consequent-commands}; done
@end example
Execute @var{consequent-commands} as long as the final command in
@var{test-commands} has an exit status of zero.
@item for
The syntax of the for command is:
@example
for @var{name} [in @var{words} ...]; do @var{commands}; done
@end example
Execute @var{commands} for each member in @var{words}, with @var{name}
bound to the current member. If ``@code{in @var{words}}'' is not
present, ``@code{in "$@@"}'' is assumed.
@end ftable
@node Conditional Constructs
@section Conditional Constructs
@ftable @code
@item if
The syntax of the @code{if} command is:
@example
if @var{test-commands}; then
@var{consequent-commands};
[else @var{alternate-consequents};]
fi
@end example
Execute @var{consequent-commands} only if the final command in
@var{test-commands} has an exit status of zero. If ``@code{else
@var{alternate-consequents}}'' is present, and the final command in
@var{test-commands} has a non-zero exit status, then execute
@var{alternate-consequents}.
@item case
The syntax of the @code{case} command is:
@example
@code{case @var{word} in [@var{pattern} [| @var{pattern}]...) @var{commands} ;;]... esac}
@end example
Selectively execute @var{commands} based upon @var{word} matching
@var{pattern}. The `@code{|}' is used to separate multiple patterns.
Here is an example using @code{case} in a script that could be used to
describe an interesting feature of an animal:
@example
echo -n "Enter the name of an animal:"
read ANIMAL
echo -n "The $ANIMAL has "
case $ANIMAL in
horse | dog | cat) echo -n "four";;
man | kangaroo ) echo -n "two";;
*) echo -n "an unknown number of";;
esac
echo "legs."
@end example
@end ftable
@node T-Csh Features
@chapter (T)C-Shell Style Features
The C-Shell @dfn{@code{csh}} was created by Bill Joy at UC Berkeley. It
is generally considered to have better features for interactive use than
the Bourne shell. Some of the @code{csh} features present in Bash
include job control, history expansion, `protected' redirection, and
several variables for controlling the interactive behaviour of the shell
(e.g. @code{ignoreeof}).
For details on history expansion, @pxref{Using History Interactively}.
Bash has tilde (~) expansion, similar, but not identical, to that of
@code{csh}. The following table shows what unquoted words beginning
with a tilde expand to.
@table @code
@item ~
The current value of @code{$HOME}.
@item ~/foo
@code{$HOME}/foo
@item ~fred/foo
The subdirectory @code{foo} of the home directory of the user named
@code{fred}.
@item ~+/foo
@code{$PWD}/foo
@item ~-
@code{$OLDPWD}/foo
@end table
Here is a list of the commands and variables whose meanings were taken
from @code{csh}.
@ftable @code
@item pushd
@example
pushd [@var{dir} | @var{+n}]
@end example
Save the current directory on a list and then CD to DIR. With no
arguments, exchanges the top two directories.
@table @code
@item +@var{n}
Brings the @var{n}th directory to the top of the list by rotating.
@item @var{dir}
Makes the current working directory be the top of the stack, and then
cd's to DIR. You can see the saved directory list with the `dirs'
command.
@end table
@item popd
@example
popd [+@var{n}]
@end example
Pops the directory stack, and cd's to the new top directory. The
elements are numbered from 0 starting at the first directory listed with
@code{dirs}; i.e. @code{popd} is equivalent to @code{popd 0}.
@item dirs
@example
dirs
@end example
Display the list of currently remembered directories. Directories
find their way onto the list with the @code{pushd} command; you can get
back up through the list with the @code{popd} command.
@item history
@example
history [@var{n}] [ [-w -r] [@var{filename}]]
@end example
Display the history list with line numbers. Lines listed with
with a @code{*} have been modified. Argument of @var{n} says to list only
the last @var{n} lines. Argument @code{-w} means write out the current
history file. @code{-r} means to read it instead. If @var{filename} is
given, then use that file, else if @code{$HISTFILE} has a value, use
that, else use @file{~/.bash_history}.
@item ignoreeof
If this variable is set, it represents the number of consecutive
@code{EOF}s Bash will read before exiting. By default, Bash will exit
upon reading an @code{EOF} character.
@end ftable
@node Korn Shell Features
@chapter Korn Shell Style Features
@ftable @code
@item fc
@example
@code{fc [-e @var{ename}] [-nlr] [@var{first}] [@var{last}]}
@code{fc -s [@var{pat=rep}] [@var{command}]}
@end example
Fix Command. In the first form, a range of commands from @var{first} to
@var{last} is selected from the history list. @var{First} and/or
@var{last} may be specified as a string (to locate the most recent
command beginning with that string) or as a number (an index into the
history list, where a negative number is used as an offset from the
current command number). If @var{last} is not specified it is set to
@var{first}. If @var{first} is not specified it is set to the previous
command for editing and -16 for listing. If the @code{-l} flag is
given, the commands are listed on standard output. The @code{-n} flag
suppresses the command numbers when listing. The @code{-r} flag
reverses the order of the listing. Otherwise, the editor given by
@var{ename} is invoked on a file containing those commands. If
@var{ename} is not given, the value of the following variable expansion
is used: @code{$@{FCEDIT:-$@{EDITOR:-vi@}}. This says to use the
value of the @code{FCEDIT} variable if set, or the value of the
@code{EDITOR} variable if that is set, or @code{vi} if neither is set.
When editing is complete, the edited commands are echoed and executed.
In the second form, @var{command} is re-executed after the substitution
@var{old=new} is performed.
A useful alias to use with the @code{fc} command is @code{r='fc -s'}, so
that typing @code{r cc} runs the last command beginning with @code{cc}
and typing @code{r} re-executes the last command.
@item typeset
The @code{typeset} command is supplied for compatibility with the Korn
shell; however, it has been made obsolete by the presence of the
@code{declare} command, documented with the Bash specific features.
@item type
Bash's @code{type} command is a superset of the @code{type} found in
Korn shells; @xref{Bash Builtins} for details.
@end ftable
@node Bash Specific Features
@chapter Bash Specific Features
@menu
* Command Line Options:: Command line options that you can give
to Bash.
* The Set Builtin:: This builtin is so overloaded it
deserves its own section.
* Is This Shell Interactive?:: Determining the state of a running Bash.
* Printing a Prompt:: Controlling the PS1 string.
* Bash Startup Files:: When and how Bash executes scripts.
* Bash Builtins:: Table of builtins specific to Bash.
* Bash Variables:: List of variables that exist in Bash.
@end menu
@node Command Line Options
@section Shell Command Line Options
Along with the single character shell command-line options (@xref{The
Set Builtin,,,}) there are several other options that you can use.
These options must appear on the command line before the single
character command options to be recognized.
@table @code
@item -norc
Don't load ~/.bashrc init file. (Default if shell name is `sh').
@item -rcfile @var{filename}
Load @var{filename} init file (instead @file{~/.bashrc}).
@item -noprofile
Don't load @file{~/.bash_profile} (nor @file{/etc/profile}).
@item -version
Display the version number of this shell.
@item -login
Make this shell act as if it were directly invoked from login.
This is equivalent to ``exec - bash'' but can be issued from
another shell, such as csh. If you wanted to replace your
current login shell with a bash login shell, you would say
``exec bash -login''.
@item -nobraceexpansion
Do not perform curly brace expansion (foo@{a,b@} @var{->} fooa foob).
@item -nolinediting
Do not use the GNU Readline library to read interactive text lines.
@end table
@node The Set Builtin
@section The Set Builtin
This builtin is so overloaded that it deserves its own section. So here
it is.
@ftable @code
@item set
@example
set [-aefhknotuvxldH] [@var{arg} ...]
@end example
@table @code
@item -a
Mark variables which are modified or created for export.
@item -e
Exit immediately if a command exits with a non-zero status.
@item -f
Disable file name generation (globbing).
@item -k
All keyword arguments are placed in the environment for a command, not
just those that precede the command name.
@item -m
Job control is enabled.
@item -n
Read commands but do not execute them.
@item -o @var{option-name}
Set the variable corresponding to @var{option-name}:
@table @code
@item allexport
same as -a.
@item braceexpand
the shell will perform brace expansion.
@item emacs
use an emacs-style line editing interface.
@item errexit
same as -e.
@item histexpand
same as -H.
@item ignoreeof
the shell will not exit upon reading EOF.
@item monitor
same as -m.
@item noclobber
disallow redirection to existing files.
@item noexec
same as -n.
@item noglob
same as -f.
@item nohash
same as -d.
@item notify
notify of job termination immediately.
@item nounset
same as -u.
@item verbose
same as -v.
@item vi
use a vi-style line editing interface.
@item xtrace
same as -x.
@end table
@item -t
Exit after reading and executing one command.
@item -u
Treat unset variables as an error when substituting.
@item -v
Print shell input lines as they are read.
@item -x
Print commands and their arguments as they are executed.
@item -l
Save and restore the binding of the @var{name} in a @code{for} command.
@item -d
Disable the hashing of commands that are looked up for execution.
Normally, commands are remembered in a hash table, and once found, do
not have to be looked up again.
@item -H
Enable ! style history substitution. This flag is on by default.
@end table
Using @samp{+} rather than @samp{-} causes these flags to be turned off.
The flags can also be used upon invocation of the shell. The current
set of flags may be found in @code{$-}. The remaining @var{arg}s are
positional parameters and are assigned, in order, to @code{$1},
@code{$2}, .. @code{$9}. If no @var{arg}s are given, all shell
variables are printed.
@end ftable
@node Is This Shell Interactive?
@section Is This Shell Interactive?
You may wish to determine within a startup script whether Bash is
running interactively or not. To do this, you examine the variable
@code{$PS1}; it is unset in non-interactive shells, and set in
interactive shells. Thus:
@example
if [ "$PS1" = "" ]; then
echo "This shell is not interactive"
else
echo "This shell is interactive"
fi
@end example
You can ask an interactive Bash to not run your @file{~/.bashrc} file
with the @code{-norc} flag. You can change the name of the
@file{~/.bashrc} file to any other file name with @code{-rcfile
@var{filename}}. You can ask Bash to not run your
@file{~/.bash_profile} file with the @code{-noprofile} flag.
@node Printing a Prompt
@section Controlling the Prompt
The value of the variable @code{$PROMPT_COMMAND} is examined just before
Bash prints each toplevel prompt. If it is set and non-null, then the
value is executed just as if you had typed it on the command line.
In addition, the following table describes the special characters which
can appear in the @code{PS1} variable:
@table @code
@item \t
the time.
@item \d
the date.
@item \n
CRLF.
@item \s
the name of the shell.
@item \w
the current working directory.
@item \W
the last element of PWD.
@item \u
your username.
@item \h
the hostname.
@item \#
the command number of this command.
@item \!
the history number of this command.
@item \<octal>
the character code in octal.
@item \\
a backslash.
@end table
@node Bash Startup Files
@section Bash Startup Files
When and how Bash executes @file{~/.bash_profile}, @file{~/.bashrc}, and
@file{~/.bash_logout}.
@example
For Login shells:
On logging in:
If @file{/etc/profile} exists, then source it.
If @file{~/.bash_profile} exists, then source it,
else if @file{~/.bash_login} exists, then source it,
else if @file{~/.profile} exists, then source it.
On logging out:
If @file{~/.bash_logout} exists, source it.
For non-login interactive shells:
On starting up:
If @file{~/.bashrc} exists, then source it.
For non-interactive shells:
On starting up:
If the environment variable @code{ENV} is non-null, source the
file mentioned there.
@end example
So, typically, your @code{~/.bash_profile} contains the line
@example
@code{if [ -f @file{~/.bashrc} ]; then source @file{~/.bashrc}; fi}
@end example
@noindent
after (or before) any login specific initializations.
@node Bash Builtins
@section Bash Builtin Commands
@ftable @code
@item builtin
@example
builtin [@var{shell-builtin} [@var{args}]]
@end example
Run a shell builtin. This is useful when you wish to rename a
shell builtin to be a function, but need the functionality of the
builtin within the function itself.
@item declare
@example
declare [-[frxi]] @var{name}[=@var{value}]
@end example
Declare variables and/or give them attributes. If no @var{name}s are
given, then display the values of variables instead. @code{-f} means to
use function names only. @code{-r} says to make @var{name}s readonly.
@code{-x} says to make @var{name}s export. @code{-i} says that the variable
is to be treated as an integer; arithmetic evaluation (see @code{let}) will
be done when the variable is assigned to. Using @code{+} instead of @code{-}
turns off the attribute instead. When used in a function, makes @var{name}s
local, as with the @code{local} command.
@item type
@example
type [-all] [-type | -path] [@var{name} ...]
@end example
For each @var{name}, indicate how it would be interpreted if used as a
command name.
If the @code{-type} flag is used, @code{type} returns a single word
which is one of ``alias'', ``function'', ``builtin'', ``file'' or
``'', if @var{name} is an alias, shell function, shell builtin, disk
file, or unfound, respectively.
If the @code{-path} flag is used, @code{type} either returns the name
of the disk file that would be exec'ed, or nothing if @code{-type} wouldn't
return ``file''.
If the @code{-all} flag is used, returns all of the places that contain
an executable named @var{file}. This includes aliases and functions,
if and only if the @code{-path} flag is not also used.
@item enable
@example
enable [-n] [@var{name} ...]
@end example
Enable and disable builtin shell commands. This allows you to use a
disk command which has the same name as a shell builtin. If @code{-n}
is used, the @var{name}s become disabled. Otherwise @var{name}s are
enabled. For example, to use the @code{test} found on your path instead
of the shell builtin version, you type @w{@code{enable -n test}}.
@item help
@example
help [@var{pattern}]
@end example
Display helpful information about builtin commands. If
@var{pattern} is specified, gives detailed help on all commands
matching @var{pattern}, otherwise a list of the builtins is
printed.
@item command
@example
command [@var{command} [@var{args} ...]]
@end example
Runs @var{command} with @var{arg} ignoring shell functions. If you have
a shell function called @code{ls}, and you wish to call the command
@code{ls}, you can say ``command ls''.
@item hash
@example
hash [-r] [@var{name}]
@end example
For each @var{name}, the full pathname of the command is determined
and remembered. The @code{-r} option causes the shell to forget all
remembered locations. If no arguments are given, information
about remembered commands is presented.
@item local
@example
local @var{name}[=@var{value}]
@end example
Create a local variable called @var{name}, and give it @var{value}.
@code{local} can only be used within a function; it makes the variable
@var{name} have a visible scope restricted to that function and its
children.
@item readonly
@example
readonly [-f] [@var{name} ...]
@end example
The given @var{name}s are marked readonly and the values of these
@var{name}s may not be changed by subsequent assignment. If the -f
option is given, the functions corresponding to the @var{name}s are so
marked. If no arguments are given, a list of all readonly names is
printed.
@item ulimit
@example
ulimit [-acdmstfpn [limit]]
@end example
Ulimit provides control over the resources available to processes
started by the shell, on systems that allow such control. If an
option is given, it is interpreted as follows:
@table @code
@item -a
all current limits are reported.
@item -c
the maximum size of core files created.
@item -d
the maximum size of a process's data segment.
@item -m
the maximum resident set size.
@item -s
the maximum stack size.
@item -t
the maximum amount of cpu time in seconds.
@item -f
the maximum size of files created by the shell.
@item -p
the pipe buffer size.
@item -n
the maximum number of open file descriptors.
@end table
If @var{limit} is given, it is the new value of the specified resource.
Otherwise, the current value of the specified resource is printed. If
no option is given, then @code{-f} is assumed. Values are in 1k
increments, except for @code{-t}, which is in seconds, and @code{-p},
which is in increments of 512 bytes.
@end ftable
@node Bash Variables
@section Bash Variables
@table @code
@vindex history_control
@item history_control
Set to a value of "ignorespace", it means don't enter lines which begin
with a SPC on the history list. Set to a value of "ignoredups", it
means don't enter lines which match the last entered line. Unset, or
any other value than those above mean to save all lines on the history
list.
@vindex HISTFILE
@item HISTFILE
The name of the file that the command history is saved in.
@vindex HISTSIZE
@item HISTSIZE
If set, this is the maximum number of commands to remember in the
history.
@vindex histchars
@item histchars
Up to three characters which control history expansion, quick
substitution, and tokenization. The first character is the
@dfn{history-expansion-char}, that is, the character which signifies the
start of a history expansion, normally `!'. The second character is the
character which signifies `quick substitution' when seen as the first
character on a line, normally `^'. The optional third character is the
character which signifies the remainder of the line is a comment, when
found as the first character of a word, usually `#'.
@vindex hostname_completion_file
@item hostname_completion_file
Contains the name of a file in the same format as @file{/etc/hosts} that
should be read when the shell needs to complete a hostname. You can
change the file interactively; the next time you want to complete a
hostname Bash will add the contents of the new file to the already
existing database.
@vindex MAILCHECK
@item MAILCHECK
How often (in seconds) that the shell should check for mail
in the file(s) specified in @code{MAILPATH}.
@vindex MAILPATH
@item MAILPATH
Colon separated list of pathnames to check for mail in. You can
also specify what message is printed by separating the pathname from
the message with a @samp{?}. @code{$_} stands for the name of the current
mailfile. For example:
@example
MAILPATH='/usr/spool/mail/bfox?"You have mail":~/shell-mail?"$_ has mail!"'
@end example
@vindex ignoreeof
@item ignoreeof
@vindex IGNOREEOF
@itemx IGNOREEOF
Controls the action of the shell on receipt of an @code{EOF} character
as the sole input. If set, then the value of it is the number
of @code{EOF} characters that can be seen in a row as sole input characters
before the shell will exit. If the variable exists but does not
have a numeric value (or has no value) then the default is 10.
if the variable does not exist, then @code{EOF} signifies the end of
input to the shell. This is only in effect for interactive shells.
@vindex auto_resume
@item auto_resume
This variable controls how the shell interacts with the user and
job control. If this variable exists then single word simple
commands without redirects are treated as candidates for resumption
of an existing job. There is no ambiguity allowed; if you have
more than one job beginning with the string that you have typed, then
the most recently accessed job will be selected.
@vindex no_exit_on_failed_exec
@item no_exit_on_failed_exec
If this variable exists, the shell will not exit in the case that it
couldn't execute the file specified in the @code{exec} command.
@vindex PROMPT_COMMAND
@item PROMPT_COMMAND
If present, this contains a string which is a command to execute
before the printing of each toplevel prompt.
@vindex nolinks
@item nolinks
If present, says not to follow symbolic links when doing commands
that change the current working directory. By default, bash follows
the logical chain of directories when performing @code{cd} type commands.
For example, if @file{/usr/sys} is a link to @file{/usr/local/sys} then:
@example
cd /usr/sys; echo $PWD -> /usr/sys
cd ..; pwd -> /usr
@end example
@noindent
If @code{nolinks} exists, then:
@example
cd /usr/sys; echo $PWD -> /usr/local/sys
cd ..; pwd -> /usr/local
@end example
@end table
@cindex History, how to use
@include ../lib/readline/doc/hsuser.texinfo
@cindex Readline, how to use
@include ../lib/readline/doc/rluser.texinfo
@node Variable Index
@appendix Variable Index
@printindex vr
@node Concept Index
@appendix Concept Index
@printindex cp
@contents
@bye

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,89 @@
/* endian.c -- A trick for determining the byte order of a machine. */
#include <stdio.h>
/* The name of this program, as taken from argv[0]. */
char *progname;
/* The name of the source file that this code is made from. */
char source_name[256];
/* The name of the define. Either "BIG_ENDIAN" or "LITTLE_ENDIAN". */
char *endian_define;
/* Stuffed value of "ABCD" in a long, followed by a 0. */
long int str[2] = { 0x41424344, 0x0 };
/* Stuff "ABCD" into a long, and compare it against a character string
"ABCD". If the results are EQ, the machine is big endian like a 68000
or Sparc, otherwise it is little endian, like a Vax, or 386. */
main (argc, argv)
int argc;
char **argv;
{
register int i;
FILE *stream = (FILE *)NULL;
char *stream_name = "stdout";
progname = argv[0];
for (i = strlen (progname); i > 0; i--)
if (progname[i] == '/')
{
progname = progname + i + 1;
break;
}
strcpy (source_name, progname);
for (i = strlen (source_name); i > 0; i--)
if (source_name[i] == '.')
{
source_name[i] = '\0';
break;
}
strcat (source_name, ".c");
if (argc == 1)
{
stream_name = "stdout";
stream = stdout;
}
else if (argc == 2)
{
stream_name = argv[1];
stream = fopen (stream_name, "w");
}
else
{
fprintf (stderr, "Usage: %s [output-file]\n", progname);
exit (1);
}
if (!stream)
{
fprintf (stderr, "%s: %s Cannot be opened or written to.\n",
progname, stream_name);
exit (2);
}
if (strcmp ((char *)&str[0], "ABCD") == 0)
endian_define = "BIG_ENDIAN";
else
endian_define = "LITTLE_ENDIAN";
fprintf (stream, "/* %s - Define BIG or LITTLE endian. */\n\n", stream_name);
fprintf (stream,
"/* This file was automatically created by `%s'. You shouldn't\n\
edit this file, because your changes will be overwritten. Instead,\n\
edit the source code file `%s'. */\n\n",
progname, source_name);
fprintf (stream, "#if !defined (%s)\n", endian_define);
fprintf (stream, "# define %s\n", endian_define);
fprintf (stream, "#endif /* %s */\n", endian_define);
if (stream != stdout)
fclose (stream);
exit (0);
}

View File

@@ -0,0 +1,22 @@
#! /bin/sh
#
# Convert Csh aliases to Bash aliases. Adapted from a similar program
# supplied with zsh.
#
# This is a quick script to convert csh aliases to bash aliases/functions.
# Pipe the output of csh's alias command through this; it will generate
# a series of alias/function definitions on stdout, suitable for
# processing by bash.
#
# This is not perfect, but it gets most common aliases; it should manage to
# cut down a lot of the busy work.
#
sed -e 's/ (\(.*\))/ \1/' >/tmp/cz$$.1
grep ! /tmp/cz$$.1 >/tmp/cz$$.2
grep -v ! /tmp/cz$$.1 >/tmp/cz$$.3
sed -e "s/'/'"\\\\"''"/g -e 's/^\([^ ]*\) \(.*\)$/alias \1='"'\2'/" \
/tmp/cz$$.3
sed -e 's/![:#]*/$/g' -e 's/^\([^ ]*\) \(.*\)$/\1 () { \2 }/' /tmp/cz$$.2
rm /tmp/cz$$.?
exit 0

View File

@@ -0,0 +1,103 @@
#
# An almost ksh-compatible `autoload'. A function declared as `autoload' will
# be read in from a file the same name as the function found by searching the
# $FPATH (which works the same as $PATH), then that definition will be run.
#
# To do this without source support, we define a dummy function that, when
# executed, will load the file (thereby re-defining the function), then
# execute that newly-redefined function with the original arguments.
#
# It's not identical to ksh because ksh apparently does lazy evaluation
# and looks for the file to load from only when the function is referenced.
# This one requires that the file exist when the function is declared as
# `autoload'.
#
# usage: autoload func [func...]
#
# The first cut of this was by Bill Trost, trost@reed.bitnet
#
# Chet Ramey
# chet@ins.CWRU.Edu
#
# Declare a function ($1) to be autoloaded from a file ($2) when it is first
# called. This defines a `temporary' function that will `.' the file
# containg the real function definition, then execute that new definition with
# the arguments given to this `fake' function. The autoload function defined
# by the file and the file itself *must* be named identically.
#
aload()
{
eval $1 '() { . '$2' ; '$1' "$@" ; return $? }'
}
#
# Search $FPATH for a file the same name as the function given as $1, and
# autoload the function from that file. There is no default $FPATH.
#
autoload()
{
#
# Save the list of functions; we're going to blow away the arguments
# in a second. If any of the names contain white space, TFB.
#
local args="$*"
#
# This should, I think, list the functions marked as autoload and not
# yet defined, but we don't have enough information to do that here.
#
if [ $# -eq 0 ] ; then
echo "usage: autoload function [function...]"
return 1
fi
#
# If there is no $FPATH, there is no work to be done
#
if [ -z "$FPATH" ] ; then
echo autoload: FPATH not set
return 1
fi
#
# This treats FPATH exactly like PATH: a null field anywhere in the
# FPATH is treated the same as the current directory.
#
# The path splitting command is taken from Kernighan and Pike
#
fp=$(echo $FPATH | sed 's/^:/.:/
s/::/:.:/g
s/:$/:./
s/:/ /g')
for FUNC in $args ; do
#
# We're blowing away the arguments to autoload here...
# We have to; there are no arrays.
#
set $fp
while [ $# -ne 0 ] ; do
if [ -f $1/$FUNC ] ; then
break # found it!
fi
shift
done
if [ $# -eq 0 ] ; then
echo "$FUNC: autoload function not found"
continue
fi
# echo auto-loading $FUNC from $1/$FUNC
aload $FUNC $1/$FUNC
done
return 0
}

View File

@@ -0,0 +1,23 @@
# Date: Fri, 11 Oct 91 11:22:36 edt
# From: friedman@gnu.ai.mit.edu
# To: bfox@gnu.ai.mit.edu
# A replacement for basename(1). Not all the systems I use have this
# program. Usage: basename [path] {extension}
function basename ()
{
local path="$1"
local suffix="$2"
local tpath="${path%/}"
# Strip trailing '/' characters from path (unusual that this should
# ever occur, but basename(1) seems to deal with it.)
while [ "${tpath}" != "${path}" ]; do
tpath="${path}"
path="${tpath%/}"
done
path="${path##*/}" # Strip off pathname
echo ${path%${suffix}} # Also strip off extension, if any.
}

View File

@@ -0,0 +1,36 @@
# C-shell compatabilty package.
# setenv VAR VALUE
function setenv () {
export $1="$2"
}
function unsetenv () {
unset $1
}
function alias () {
local name=$1
shift
local value="$*"
if [ "$name" = "" ]; then
builtin alias
elif [ "$value" = "" ]; then
builtin alias $name
else
builtin alias $name="$value"
fi
}
# Can't write foreach yet. Need pattern matching, and a few extras.
function foreach () {
echo 'Can'\''t do `foreach'\'' yet. Type "help for".'
}
# Make this work like csh's. Special case "term" and "path".
#set () {
#}
chdir () {
builtin cd $*
}

View File

@@ -0,0 +1,21 @@
# Date: Fri, 11 Oct 91 11:22:36 edt
# From: friedman@gnu.ai.mit.edu
# To: bfox@gnu.ai.mit.edu
# A replacement for dirname(1). This one appears less often on some
# systems I use than basename(1), and I really depend on it for some
# things. Usage: dirname [path]
function dirname ()
{
local dir="$1"
local tdir="${dir%/}"
# Strip trailing '/' characters from dir (unusual that this should
# ever occur, but dirname(1) seems to deal with it.)
while [ "${tdir}" != "${dir}" ]; do
tdir="${dir}"
dir="${tdir%/}"
done
echo "${dir%/*}"
}

View File

@@ -0,0 +1,22 @@
# Contributed by Noah Friedman and Roland McGrath.
# To be run by the PROMPT_COMMAND variable, so that one can see what
# the exit status of processes are.
function check_exit_status ()
{
local status="$?"
local signal=""
if [ ${status} -ne 0 -a ${status} != 128 ]; then
# If process exited by a signal, determine name of signal.
if [ ${status} -gt 128 ]; then
signal="$(builtin kill -l $[${status} - 128] 2>/dev/null)"
if [ "$signal" ]; then signal="($signal)"; fi
fi
echo "[Exit ${status} ${signal}]" 1>&2
fi
return 0
}
PROMPT_COMMAND=check_exit_status

View File

@@ -0,0 +1,50 @@
# Contributed by Noah Friedman.
# To avoid using a function in bash, you can use the `builtin' or
# `command' builtins, but neither guarantees that you use an external
# program instead of a bash builtin if there's a builtin by that name. So
# this function can be used like `command' except that it guarantees the
# program is external by first disabling any builtin by that name. After
# the command is done executing, the state of the builtin is restored.
function external ()
{
local state=""
local exit_status
if builtin_p "$1"; then
state="builtin"
enable -n "$1"
fi
command "$@"
exit_status=$?
if [ "$state" = "builtin" ]; then
enable "$1"
fi
return ${exit_status}
}
# What is does is tell you if a particular keyword is currently enabled as
# a shell builtin. It does NOT tell you if invoking that keyword will
# necessarily run the builtin. For that, do something like
#
# test "$(builtin type -type [keyword])" = "builtin"
#
# Note also, that disabling a builtin with "enable -n" will make builtin_p
# return false, since the builtin is no longer available.
function builtin_p ()
{
local word
set $(builtin type -all -type "$1")
for word in "$@" ; do
if [ "${word}" = "builtin" ]; then
return 0
fi
done
return 1
}

View File

@@ -0,0 +1,13 @@
# Who said shells can't use recursion? Here is a factorial function.
# You call it with a number as an argument, and it returns the factorial
# of that number.
fact ()
{
local num=$1;
if [ "$num" = 1 ] ; then
echo 1
return ;
fi;
echo $[ $num * $(fact $[ $num - 1 ])]
}

View File

@@ -0,0 +1,63 @@
#
# fstty
#
# A function that works as a front end for both stty and the `bind'
# builtin, so the tty driver and readline see the same changes
#
# chet@ins.cwru.edu
#
#
# Convert between the stty ^H control character form and the readline \C-H
# form
#
cvt()
{
echo "$@" | cat -v | sed 's/\^/\\C-/'
}
#
# stty front-end. Parses the argument list and creates two command strings,
# one for stty, another for bind.
#
fstty()
{
local cmd="" bargs=""
local e
while [ $# -gt 0 ]
do
case "$1" in
-a) cmd="$cmd everything"
;;
erase) shift;
e=$(cvt "$1")
cmd="$cmd erase $1"
bargs="$bargs '$e: backward-delete-char'"
;;
kill) shift
e=$(cvt "$1")
cmd="$cmd kill $1"
bargs="$bargs '$e: unix-line-discard'"
;;
werase) shift;
e=$(cvt "$1")
cmd="$cmd erase $1"
bargs="$bargs '$e: backward-kill-word'"
;;
lnext) shift;
e=$(cvt "$1")
cmd="$cmd erase $1"
bargs="$bargs '$e: quoted-insert'"
;;
*) cmd="$cmd $1"
;;
esac
shift
done
command stty $cmd
if [ -n "$bargs" ]; then
builtin bind $bargs
fi
}

View File

@@ -0,0 +1,148 @@
#
# ksh-compat -- functions and aliases to provide the beginnings of a ksh
# environment for bash.
#
# Chet Ramey
# chet@ins.CWRU.Edu
#
#
# These are definitions for the ksh compiled-in `exported aliases'. There
# are others, but we already have substitutes for them: "history", "type",
# and "hash".
#
alias r="fc -e -"
alias functions="typeset -f"
alias integer="typeset -i"
alias nohup="nohup "
alias true=":"
alias false="let 0"
#
# An almost-ksh compatible `whence' command. This is as hairy as it is
# because of the desire to exactly mimic ksh (whose behavior was determined
# empirically).
#
# This depends somewhat on knowing the format of the output of the bash
# `builtin type' command.
#
whence ()
{
local vflag
local path
vflag=
path=
if [ "$#" = "0" ]; then
echo "whence: argument expected"
return 1
fi
case "$1" in
-v) vflag=1
shift 1
;;
-*) echo "whence: bad option: $1"
return 1
;;
*) ;;
esac
if [ "$#" = "0" ]; then
echo "whence: bad argument count"
return 1
fi
for cmd; do
if [ "$vflag" ]; then
echo $(builtin type $cmd | sed 1q)
else
path=$(builtin type -path $cmd)
if [ "$path" ]; then
echo $path
else
case "$cmd" in
/*) echo ""
;;
*)
case "$(builtin type -type $cmd)" in
"") echo ""
;;
*) echo "$cmd"
;;
esac
;;
esac
fi
fi
done
return 0
}
#
# For real ksh homeboy fanatics, redefine the `type' builtin with a ksh
# version.
#
#type()
#{
# whence -v "$*"
#}
cd ()
{
case $# in
0) builtin cd "$HOME" ;;
1) builtin cd "$@" ;;
2) old="$1"
new="$2"
dir=$(echo "$PWD" | sed "s:$old:$new:g")
case "$dir" in
"$PWD") echo "bash: cd: bad substitution" >&2 ;;
*) echo "$dir"
builtin cd "$dir"
;;
esac
;;
*) echo "cd: wrong arg count" >&2 ;;
esac
}
#
# ksh print emulation
#
# print [-Rnprsu[n]] [arg ...]
#
# - end of options
# -R BSD-style -- only accept -n, no escapes
# -n do not add trailing newline
# -p no-op (no coprocesses)
# -r no escapes
# -s no-op (print to the history file)
# -u n redirect output to fd n
#
print()
{
local eflag=-e
local nflag=
local fd=1
OPTIND=1
while getopts "Rnprsu:" c; do
case $c in
R|r) eflag= ;;
n) nflag=-n ;;
u) redir=">&$OPTARG"
fd=$OPTARG
;;
p|s) ;;
esac
done
shift $[ $OPTIND - 1 ]
echo $eflag $nflag "$@" >&$fd
}

View File

@@ -0,0 +1,88 @@
#
# .kshenv -- functions and aliases to provide the beginnings of a ksh
# environment for bash.
#
# Chet Ramey
# chet@ins.CWRU.Edu
#
#
# These are definitions for the ksh compiled-in `exported aliases'. There
# are others, but we already have substitutes for them: "history", "type",
# and "hash".
#
alias r="fc -e -"
alias functions="typeset -f"
alias integer="typeset -i"
alias nohup="nohup "
alias true=":"
alias false="let 0"
#
# An almost-ksh compatible `whence' command. This is as hairy as it is
# because of the desire to exactly mimic ksh (whose behavior was determined
# empirically).
#
# This depends somewhat on knowing the format of the output of the bash
# `builtin type' command.
#
whence()
{
local vflag
local path
vflag=
path=
if [ "$#" = "0" ] ; then
echo "whence: argument expected"
return 1
fi
case "$1" in
-v) vflag=1
shift 1
;;
-*) echo "whence: bad option: $1"
return 1
;;
*) ;;
esac
if [ "$#" = "0" ] ; then
echo "whence: bad argument count"
return 1
fi
for cmd
do
if [ "$vflag" ] ; then
echo $(builtin type $cmd | sed 1q)
else
path=$(builtin type -path $cmd)
if [ "$path" ] ; then
echo $path
else
case "$cmd" in
/*) echo ""
;;
*) case "$(builtin type -type $cmd)" in
"") echo ""
;;
*) echo "$cmd"
;;
esac
;;
esac
fi
fi
done
return 0
}
#
# For real ksh homeboy fanatics, redefine the `type' builtin with a ksh
# version.
#
#type()
#{
# whence -v "$*"
#}

View File

@@ -0,0 +1,7 @@
shcat()
{
while read line
do
echo "$line"
done
}

View File

@@ -0,0 +1,79 @@
#
# substr -- a function to emulate the ancient ksh builtin
#
#
# -l == shortest from left
# -L == longest from left
# -r == shortest from right (the default)
# -R == longest from right
substr()
{
local flag pat str
local usage="usage: substr -lLrR pat string or substr string pat"
case "$1" in
-l | -L | -r | -R)
flag="$1"
pat="$2"
shift 2
;;
-*)
echo "substr: unknown option: $1"
echo "$usage"
return 1
;;
*)
flag="-r"
pat="$2"
;;
esac
if [ "$#" -eq 0 -o "$#" -gt 2 ] ; then
echo "substr: bad argument count"
return 2
fi
str="$1"
#
# We don't want -f, but we don't want to turn it back on if
# we didn't have it already
#
case "$-" in
"*f*")
;;
*)
fng=1
set -f
;;
esac
case "$flag" in
-l)
str="${str#$pat}" # substr -l pat string
;;
-L)
str="${str##$pat}" # substr -L pat string
;;
-r)
str="${str%$pat}" # substr -r pat string
;;
-R)
str="${str%%$pat}" # substr -R pat string
;;
*)
str="${str%$2}" # substr string pat
;;
esac
echo "$str"
#
# If we had file name generation when we started, re-enable it
#
if [ "$fng" = "1" ] ; then
set +f
fi
}

View File

@@ -0,0 +1,81 @@
#
# substr -- a function to emulate the ancient ksh builtin
#
# -l == remove shortest from left
# -L == remove longest from left
# -r == remove shortest from right (the default)
# -R == remove longest from right
substr()
{
local flag pat str
local usage="usage: substr -lLrR pat string or substr string pat"
local options="l:L:r:R:"
OPTIND=1
while getopts "$options" c
do
case "$c" in
l | L | r | R)
flag="-$c"
pat="$OPTARG"
;;
'?')
echo "$usage"
return 1
;;
esac
done
if [ "$OPTIND" -gt 1 ] ; then
shift $[ $OPTIND -1 ]
fi
if [ "$#" -eq 0 -o "$#" -gt 2 ] ; then
echo "substr: bad argument count"
return 2
fi
str="$1"
#
# We don't want -f, but we don't want to turn it back on if
# we didn't have it already
#
case "$-" in
"*f*")
;;
*)
fng=1
set -f
;;
esac
case "$flag" in
-l)
str="${str#$pat}" # substr -l pat string
;;
-L)
str="${str##$pat}" # substr -L pat string
;;
-r)
str="${str%$pat}" # substr -r pat string
;;
-R)
str="${str%%$pat}" # substr -R pat string
;;
*)
str="${str%$2}" # substr string pat
;;
esac
echo "$str"
#
# If we had file name generation when we started, re-enable it
#
if [ "$fng" = "1" ] ; then
set +f
fi
}

View File

@@ -0,0 +1,35 @@
#
# term -- a shell function to set the terminal type interactively or not.
#
term()
{
local t
if [ $# != 0 ] ; then
eval $(tset -sQ $1)
else # interactive
if [ -z "$TERM" ] ; then
TERM="unknown"
fi
case "$TERM" in
network|dialup|unknown|lat)
TERM=unknown
;;
*)
eval $(tset -sQ)
;;
esac
while [ "$TERM" = "unknown" ] ; do
echo -n "Terminal type: "
read t
if [ -n "$t" ] ; then
eval $(tset -sQ $t)
fi
done
fi
}

View File

@@ -0,0 +1,51 @@
#
# whatis -- and implementation of the 10th Edition Unix sh builtin `whatis'
# command.
#
# usage: whatis arg [...]
#
# For each argument, whatis prints the associated value as a parameter,
# builtin, function, alias, or executable file as appropriate. In each
# case, the value is printed in a form which would yield the same value
# if typed as input to the shell itself.
#
whatis()
{
local wusage='usage: whatis arg [arg...]'
local fail=0
if [ $# -eq 0 ] ; then
echo "$wusage"
return 1
fi
for arg
do
case $(builtin type -type $arg) in
"alias")
echo "$(alias $arg)"
;;
"function")
builtin type "$arg" | sed 1d
;;
"builtin")
echo builtin "$arg"
;;
"file")
echo $(type -path "$arg")
;;
*)
# OK, we could have a variable, or we could have nada
if [ "$(eval echo \${$arg+set})" = "set" ] ; then
# It is a variable, and it is set
echo -n "$arg="
eval echo \$$arg
else
fail=1
fi
;;
esac
done
return $fail
}

View File

@@ -0,0 +1,63 @@
#
# An almost-ksh compatible `whence' command. This is as hairy as it is
# because of the desire to exactly mimic ksh.
#
# This depends somewhat on knowing the format of the output of the bash
# `builtin type' command.
#
# Chet Ramey
# chet@ins.CWRU.Edu
#
whence()
{
local vflag
local path
vflag=
path=
if [ "$#" = "0" ] ; then
echo "whence: argument expected"
return 1
fi
case "$1" in
-v) vflag=1
shift 1
;;
-*) echo "whence: bad option: $1"
return 1
;;
*) ;;
esac
if [ "$#" = "0" ] ; then
echo "whence: bad argument count"
return 1
fi
for cmd
do
if [ "$vflag" ] ; then
echo $(builtin type $cmd | sed 1q)
else
path=$(builtin type -path $cmd)
if [ "$path" ] ; then
echo $path
else
case "$cmd" in
/*) echo ""
;;
*) case "$(builtin type -type $cmd)" in
"") echo ""
;;
*) echo "$cmd"
;;
esac
;;
esac
fi
fi
done
return 0
}

View File

@@ -0,0 +1,57 @@
#
# An almost-ksh compatible `whence' command. The one difference between this
# and the real ksh `whence' is that this version, when the "-v" flag is not
# given and presented with something that is not in the path, simply echos it
# without more checking to see if it is a function, builtin, or alias.
#
# Chet Ramey
# chet@ins.CWRU.Edu
#
whence()
{
local vflag
local path
vflag=
path=
if [ $# = "0" ] ; then
echo "whence: argument expected"
return 1
fi
case "$1" in
-v) vflag=1
shift 1
;;
-*) echo "whence: bad option: $1"
return 1
;;
*) ;;
esac
if [ $# = "0" ] ; then
echo "whence: bad argument count"
return 1
fi
for cmd
do
if [ "$vflag" ] ; then
echo $(builtin type $cmd | sed 1q)
else
path=$(builtin type -path $cmd)
if [ "$path" ] ; then
echo $path
else
case "$cmd" in
/*) echo ""
;;
*) echo "$cmd"
;;
esac
fi
fi
done
return 0
}

View File

@@ -0,0 +1,12 @@
dir
info dir
dir /usr/gnu/src/bash:/usr/gnu/src/bash/builtins
where
frame
where
up
up
down
down
where
quit

View File

@@ -0,0 +1,137 @@
#
# shprompt -- give a prompt and get an answer satisfying certain criteria
#
# shprompt [-dDfFsy] prompt
# s = prompt for string
# f = prompt for filename
# F = prompt for full pathname to a file or directory
# d = prompt for a directory name
# D = prompt for a full pathname to a directory
# y = prompt for y or n answer
#
# Chet Ramey
# chet@ins.CWRU.Edu
type=file
OPTS=dDfFsy
succeed()
{
echo "$1"
exit 0
}
while getopts "$OPTS" c
do
case "$c" in
s) type=string
;;
f) type=file
;;
F) type=path
;;
d) type=dir
;;
D) type=dirpath
;;
y) type=yesno
;;
?) echo "usage: $0 [-$OPTS] prompt" 1>&2
exit 2
;;
esac
done
if [ "$OPTIND" -gt 1 ] ; then
shift $[$OPTIND - 1]
fi
while :
do
case "$type" in
string)
echo -n "$1" 1>&2
read ans || exit 1
if [ -n "$ans" ] ; then
succeed "$ans"
fi
;;
file|path)
echo -n "$1" 1>&2
read ans || exit 1
#
# use `fn' and eval so that bash will do tilde expansion for
# me
#
eval fn="$ans"
case "$fn" in
/*) if test -e "$fn" ; then
succeed "$fn"
else
echo "$0: '$fn' does not exist" 1>&2
fi
;;
*) if [ "$type" = "path" ] ; then
echo "$0: must give full pathname to file" 1>&2
else
if test -e "$fn" ; then
succeed "$fn"
else
echo "$0: '$fn' does not exist" 1>&2
fi
fi
;;
esac
;;
dir|dirpath)
echo -n "$1" 1>&2
read ans || exit 1
#
# use `fn' and eval so that bash will do tilde expansion for
# me
#
eval fn="$ans"
case "$fn" in
/*) if test -d "$fn" ; then
succeed "$fn"
elif test -e "$fn" ; then
echo "$0 '$fn' is not a directory" 1>&2
else
echo "$0: '$fn' does not exist" 1>&2
fi
;;
*) if [ "$type" = "dirpath" ] ; then
echo "$0: must give full pathname to directory" 1>&2
else
if test -d "$fn" ; then
succeed "$fn"
elif test -e "$fn" ; then
echo "$0 '$fn' is not a directory" 1>&2
else
echo "$0: '$fn' does not exist" 1>&2
fi
fi
;;
esac
;;
yesno)
echo -n "$1" 1>&2
read ans || exit 1
case "$ans" in
y|Y|[yY][eE][sS])
succeed "yes"
;;
n|N|[nN][oO])
succeed "no"
exit 0
;;
*)
echo "$0: yes or no required" 1>&2
;;
esac
;;
esac
done
exit 1

View File

@@ -0,0 +1,63 @@
# Some useful aliases.
alias texclean='rm -f *.toc *.aux *.log *.cp *.fn *.tp *.vr *.pg *.ky'
alias clean='echo -n "Really clean this directory?";
read yorn;
if test "$yorn" = "y"; then
rm -f \#* *~ .*~ *.bak .*.bak *.tmp .*.tmp core a.out;
echo "Cleaned.";
else
echo "Not cleaned.";
fi'
alias h='history'
alias j="jobs -l"
alias l="ls -l "
alias ll="ls -l"
alias ls="ls -F"
alias term='set noglob; eval `tset -Q -s `'
alias pu="pushd"
alias po="popd"
#
# Csh compatability:
#
alias unsetenv=unset
function setenv () {
export $1="$2"
}
# Function which adds an alias to the current shell and to
# the ~/.bash_aliases file.
add-alias ()
{
local name=$1 value="$2"
echo alias $name=\'$value\' >>~/.bash_aliases
eval alias $name=\'$value\'
alias $name
}
# "repeat" command. Like:
#
# repeat 10 echo foo
repeat ()
{
local count="$1" i;
shift;
for i in $(seq 1 "$count");
do
eval "$@";
done
}
# Subfunction needed by `repeat'.
seq ()
{
local lower upper output;
lower=$1 upper=$2;
while [ $lower -le $upper ];
do
output="$output $lower";
lower=$[ $lower + 1 ];
done;
echo $output
}

View File

@@ -0,0 +1,20 @@
# Startup file for bash login shells.
#
default_dir=/usr/local/lib/
if [ "$PS1" ]; then
PS1='\u@\h(\#)$ '
ignoreeof=3
fi
LOGIN_SHELL=true
# If the user has her own init file, then use that one, else use the
# canonical one.
if [ -f ~/.bashrc ]; then
source ~/.bashrc
else if [ -f ${default_dir}Bashrc ]; then
source ${default_dir}Bashrc;
fi
fi

View File

@@ -0,0 +1,72 @@
# Bourne Again SHell init file.
#
# Files you make look like rw-rw-r
umask 002
# Don't make useless coredump files. If you want a coredump,
# say "ulimit -c unlimited" and then cause a segmentation fault.
ulimit -c 0
# Sometimes, there are lots of places that one can find tex inputs.
export TEXINPUTS=.:$HOME/bin:/usr/lib/tex/inputs:/usr/local/lib/tex/inputs
# Where's the Gnu stuff at?
GNU=/usr/gnu/bin
X11=/usr/bin/X11
UTIL_PATH=$GNU:$X11
STANDARD_PATH=/usr/local/bin:/usr/ucb:/bin:/usr/bin:/usr/etc:/etc:/usr/games
if [ "$HOSTTYPE" = "sony" ]; then STANDARD_PATH=STANDARD_PATH:/usr/sony/bin; fi
if [ -d $HOME/bin/$HOSTTYPE ]; then
MY_PATH=$HOME/bin/$HOSTTYPE
fi
if [ -d $HOME/bin ]; then
MY_PATH=$MY_PATH:$HOME/bin
fi
if [ -d /usr/hosts ]; then
STANDARD_PATH=$STANDARD_PATH:/usr/hosts
fi
PATH=.:$MY_PATH:$UTIL_PATH:$STANDARD_PATH
# If running interactively, then:
if [ "$PS1" ]; then
# Set ignoreeof if you don't want EOF as the sole input to the shell to
# immediately signal a quit condition. This only happens at the start
# of a line if the line is empty, and you haven't just deleted a character
# with C-d. I turn this on in ~/.bash_profile so that only login shells
# have the right to be obnoxious.
# ignoreeof=
# Set auto_resume if you want to resume on "emacs", as well as on
# "%emacs".
auto_resume=
# Set notify if you want to be asynchronously notified about background
# job completion.
notify=
# Make it so that failed `exec' commands don't flush this shell.
no_exit_on_failed_exec=
if [ ! "$LOGIN_SHELL" ]; then
PS1="\u@\h\$ "
fi
HISTSIZE=256
MAILCHECK=60
# A couple of default aliases.
alias j='jobs -l'
alias po=popd
alias pu=pushd
alias ls='ls -F'
if [ -f ~/.bash_aliases ]; then
source ~/.bash_aliases
fi
fi

View File

@@ -0,0 +1,30 @@
#Posted-Date: Fri, 9 Mar 90 18:34:29 EST
#Date: Fri, 9 Mar 90 18:34:29 EST
#From: "Eirik Fuller" <wonton.tn.cornell.edu!eirik@ucsbcsl.UUCP>
#To: bfox@ai.mit.edu (Brian Fox)
#Subject: Patch to bash 1.05 for SunView
#
#I think this works:
#
Mu|sun-cmd:am:bs:km:pt:li#34:co#80:cl=^L:ce=\E[K:cd=\E[J:rs=\E[s:
#
#Another alternative is to send the ti string at startup time (and, I
#guess, the te string at exit time); that is how vi works in a cmdtool.
#The best reason to not do this is that this also disables scrolling
#which, as I understand it, is why anyone would use cmdtool in the
#first place. Sending the ti string at startup time would do strange
#things on other systems too; in xterm it would use the alternate
#screen.
#
#The problem with cmdtool, in case that is less than obvious, is that
#almost none of the capabilities advertised in /etc/termcap are enabled
#while scrolling is enabled. It has other problems too, like being
#part of an outdated proprietary windowing system, but there's probably
#no need to dwell on that. In a sense, though, the sun-cmd termcap
#entry doesn't lie about the capabilities; I think the termcap man page
#does warn about some terminals having cursor motion capabilities only
#in the "ti/te window".
#
#A general solution to this problem would require a termcap capability
#which somehow tells which features are available outside of the ti/te
#window. There is no such capability in termcap now, of course.

View File

@@ -0,0 +1,50 @@
#
# whatis -- and implementation of the 10th Edition Unix sh builtin `whatis'
# command.
#
# usage: whatis arg [...]
#
# For each argument, whatis prints the associated value as a parameter,
# builtin, function, alias, or executable file as appropriate. In each
# case, the value is printed in a form which would yield the same value
# if typed as input to the shell itself.
#
whatis ()
{
local fail=0
if [ $# -eq 0 ] ; then
echo 'usage: whatis arg [arg...]'
return 1
fi
for arg; do
case $(builtin type -type $arg 2>/dev/null) in
"alias")
builtin alias "$arg"
;;
"function")
builtin type "$arg" | sed 1d
;;
"builtin")
echo builtin "$arg"
;;
"file")
builtin type -path "$arg"
;;
*)
# OK, we could have a variable, or we could have nada.
if [ "$(eval echo \${$arg+set})" = "set" ] ; then
# It is a variable, and it is set.
echo -n "$arg="
eval echo '\"'\$$arg'\"'
else
echo whatis: $arg: not found
fail=1
fi
;;
esac
done
return $fail
}

File diff suppressed because it is too large Load Diff

616
bin/old/bash-1.11/expr.c Normal file
View File

@@ -0,0 +1,616 @@
/* expr.c -- arithmetic expression evaluation.
Copyright (C) 1990, 1991 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 1, 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; see the file COPYING. If not, write to the Free
Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
All arithmetic is done as long integers with no checking for overflow
(though division by 0 is caught and flagged as an error).
The following operators are handled, grouped into a set of levels in
order of decreasing precedence.
"-" [level 0 (unary negation)]
"!" [level 1]
"*", "/", "%" [level 2]
"+", "-" [level 3]
"<=", ">=", "<", ">" [level 4]
"==", "!=" [level 5]
"=" [level 6 (assignment)]
(Note that most of these operators have special meaning to bash, and an
entire expression should be quoted, e.g. "a=$a+1" or "a=a+1" to ensure
that it is passed intact to the evaluator when using `let'. When using
the $[] form, the text between the `[' and `]' is treated as if in double
quotes.)
Sub-expressions within parentheses have a precedence level greater than
all of the above levels and are evaluated first. Within a single prece-
dence group, evaluation is left-to-right, except for the arithmetic
assignment operator (`='), which is evaluated right-to-left (as in C).
The expression evaluator returns the value of the expression (assignment
statements have as a value what is returned by the RHS). The `let'
builtin, on the other hand, returns 0 if the last expression evaluates to
a non-zero, and 1 otherwise.
Implementation is a recursive-descent parser.
Chet Ramey
chet@ins.CWRU.Edu
*/
#include <stdio.h>
#include "shell.h"
#define variable_starter(c) (isletter(c) || (c == '_'))
#define variable_character(c) (isletter(c) || (c == '_') || digit(c))
#if defined (NULL)
#undef NULL
#endif
#define NULL 0
static char *expression = (char *) NULL; /* The current expression */
static char *tp = (char *) NULL; /* token lexical position */
static int curtok = 0; /* the current token */
static int lasttok = 0; /* the previous token */
static char *tokstr = (char *) NULL; /* current token string */
static int tokval = 0; /* current token value */
static jmp_buf evalbuf;
static void readtok(); /* lexical analyzer */
static long assignment(), exp0(), exp1(), exp2(), exp3(), exp4(), exp5();
static long strlong();
static void evalerror();
/*
* Because of the $[...] construct, expressions may include newlines. This
* redefines `whitespace' so that a newline is added.
*/
#ifdef whitespace
#undef whitespace
#endif
#define whitespace(c) ((c) == ' ' || (c) == '\t' || (c) == '\n')
/* A structure defining a single expression context. */
typedef struct {
int curtok, lasttok;
char *expression, *tp;
int tokval;
char *tokstr;
} EXPR_CONTEXT;
/* Global var which contains the stack of expression contexts. */
static EXPR_CONTEXT **expr_stack;
static int expr_depth = 0; /* Location in the stack. */
static int expr_stack_size = 0; /* Number of slots already allocated. */
/* Size be which the expression stack grows when neccessary. */
#define EXPR_STACK_GROW_SIZE 10
/* Maximum amount of recursion allowed. This prevents a non-integer
variable such as "num=num+2" from infinitely adding to itself when
"let num=num+2" is given. I have to talk to Chet about this hack. */
#define MAX_EXPR_RECURSION_LEVEL 1024
extern long atol ();
/* The Tokens. Singing "The Lion Sleeps Tonight". */
#define EQEQ 1 /* "==" */
#define NEQ 2 /* "!=" */
#define LEQ 3 /* "<=" */
#define GEQ 4 /* ">=" */
#define STR 5 /* string */
#define NUM 6 /* number */
#define EQ '='
#define GT '>'
#define LT '<'
#define PLUS '+'
#define MINUS '-'
#define MUL '*'
#define DIV '/'
#define MOD '%'
#define NOT '!'
#define LPAR '('
#define RPAR ')'
/* Push and save away the contents of the globals describing the
current expression context. */
static void
pushexp ()
{
EXPR_CONTEXT *context;
context = (EXPR_CONTEXT *)xmalloc (sizeof (EXPR_CONTEXT));
if (expr_depth >= MAX_EXPR_RECURSION_LEVEL)
evalerror ("expression recursion level exceeded");
if (expr_depth >= expr_stack_size)
{
expr_stack = (EXPR_CONTEXT **)
xrealloc (expr_stack, (expr_stack_size += EXPR_STACK_GROW_SIZE)
* sizeof (EXPR_CONTEXT *));
}
context->curtok = curtok;
context->lasttok = lasttok;
context->expression = expression;
context->tp = tp;
context->tokval = tokval;
context->tokstr = tokstr;
expr_stack[expr_depth++] = context;
}
/* Pop the the contents of the expression context stack into the
globals describing the current expression context. */
static void
popexp ()
{
EXPR_CONTEXT *context;
if (expr_depth == 0)
evalerror ("Recursion stack underflow");
context = expr_stack[--expr_depth];
curtok = context->curtok;
lasttok = context->lasttok;
expression = context->expression;
tp = context->tp;
tokval = context->tokval;
tokstr = context->tokstr;
free (context);
}
/* Evaluate EXPR, and return the arithmetic result.
The `while' loop after the longjmp is caught relies on the above
implementation of pushexp and popexp leaving in expr_stack[0] the
values that the variables had when the program started. That is,
the first things saved are the initial values of the variables that
were assigned at program startup or by the compiler. Therefore, it is
safe to let the loop terminate when expr_depth == 0, without freeing up
any of the expr_depth[0] stuff. */
long
evalexp (expr)
char *expr;
{
long val = 0L;
jmp_buf old_evalbuf;
if (expr == NULL || *expr == NULL)
return (0);
/* Save the value of evalbuf to protect it around possible recursive
calls to evalexp (). */
bcopy ((char *)evalbuf, (char *)old_evalbuf, sizeof (jmp_buf));
if (setjmp (evalbuf))
{
if (tokstr) /* Clean up local allocation. */
free (tokstr);
if (expression)
free (expression);
while (--expr_depth)
{
if (expr_stack[expr_depth]->tokstr)
free (expr_stack[expr_depth]->tokstr);
if (expr_stack[expr_depth]->expression)
free (expr_stack[expr_depth]->expression);
}
longjmp (top_level, DISCARD);
}
pushexp ();
curtok = lasttok = 0;
expression = savestring (expr);
tp = expression;
tokstr = (char *)NULL;
tokval = 0l;
readtok ();
val = assignment ();
if (curtok != 0)
evalerror ("syntax error in expression");
if (expression)
free (expression);
popexp ();
/* Restore the value of evalbuf so that any subsequent longjmp calls
will have a valid location to jump to. */
bcopy ((char *)old_evalbuf, (char *)evalbuf, sizeof (jmp_buf));
return (val);
}
/* Bind/create a shell variable with the name LHS to the RHS.
This creates or modifies a variable such that it is an integer.
This should really be in variables.c, but it is here so that all of the
expression evaluation stuff is localized. Since we don't want any
recursive evaluation from bind_variable() (possible without this code,
since bind_variable() calls the evaluator for variables with the integer
attribute set), we temporarily turn off the integer attribute for each
variable we set here, then turn it back on after binding as necessary. */
void
bind_int_variable (lhs, rhs)
char *lhs, *rhs;
{
register SHELL_VAR *v;
int isint = 0;
v = find_variable (lhs);
if (v)
{
isint = integer_p (v);
v->attributes &= ~att_integer;
}
v = bind_variable (lhs, rhs);
if (isint)
v->attributes |= att_integer;
}
static long
assignment ()
{
register long value;
char *lhs;
char *rhs;
value = exp5 ();
if (curtok == EQ)
{
if (lasttok != STR)
evalerror ("attempted assignment to non-variable");
lhs = savestring (tokstr);
readtok ();
value = assignment ();
rhs = itos (value);
bind_int_variable (lhs, rhs);
free (rhs);
free (lhs);
free (tokstr);
tokstr = (char *)NULL; /* For freeing on errors. */
}
return (value);
}
static long
exp5 ()
{
register long val1, val2;
val1 = exp4 ();
while ((curtok == EQEQ) || (curtok == NEQ))
{
int op = curtok;
readtok ();
val2 = exp4 ();
if (op == EQEQ)
val1 = (val1 == val2);
else if (op == NEQ)
val1 = (val1 != val2);
}
return (val1);
}
static long
exp4 ()
{
register long val1, val2;
val1 = exp3 ();
while ((curtok == LEQ) ||
(curtok == GEQ) ||
(curtok == LT) ||
(curtok == GT))
{
int op = curtok;
readtok ();
val2 = exp3 ();
if (op == LEQ)
val1 = val1 <= val2;
else if (op == GEQ)
val1 = val1 >= val2;
else if (op == LT)
val1 = val1 < val2;
else if (op == GT)
val1 = val1 > val2;
}
return (val1);
}
static long
exp3 ()
{
register long val1, val2;
val1 = exp2 ();
while ((curtok == PLUS) || (curtok == MINUS))
{
int op = curtok;
readtok ();
val2 = exp2 ();
if (op == PLUS)
val1 += val2;
else if (op == MINUS)
val1 -= val2;
}
return (val1);
}
static long
exp2 ()
{
register long val1, val2;
val1 = exp1 ();
while ((curtok == MUL) ||
(curtok == DIV) ||
(curtok == MOD))
{
int op = curtok;
readtok ();
val2 = exp1 ();
if (((op == DIV) || (op == MOD)) && (val2 == 0))
evalerror ("division by 0");
if (op == MUL)
val1 *= val2;
else if (op == DIV)
val1 /= val2;
else if (op == MOD)
val1 %= val2;
}
return (val1);
}
static long
exp1 ()
{
register long val;
if (curtok == NOT)
{
readtok ();
val = !exp0 ();
}
else
val = exp0 ();
return (val);
}
static long
exp0 ()
{
register long val = 0L;
if (curtok == MINUS)
{
readtok ();
val = - exp0 ();
}
else if (curtok == LPAR)
{
readtok ();
val = assignment ();
if (curtok != RPAR)
evalerror ("missing `)'");
/* Skip over closing paren. */
readtok ();
}
else if ((curtok == NUM) || (curtok == STR))
{
val = tokval;
readtok ();
}
else
evalerror ("syntax error in expression");
return (val);
}
/* Lexical analyzer/token reader for the expression evaluator. Reads the
next token and puts its value into curtok, while advancing past it.
Updates value of tp. May also set tokval (for number) or tokstr (for
string). */
static void
readtok ()
{
register char *cp = tp;
register int c, c1;
/* Skip leading whitespace. */
c = 0;
while (cp && (c = *cp) && (whitespace(c)))
cp++;
if (c)
cp++;
tp = cp - 1;
if (c == '\0')
{
lasttok = curtok;
curtok = 0;
tp = cp;
return;
}
if (variable_starter (c))
{
/* Semi-bogus K*rn shell compatibility feature -- variable
names not preceded with a dollar sign are shell variables. */
char *value;
while (variable_character (c))
c = *cp++;
c = *--cp;
*cp = '\0';
tokstr = savestring (tp);
value = get_string_value (tokstr);
if (value && *value)
tokval = evalexp (value);
else
tokval = 0;
*cp = c;
lasttok = curtok;
curtok = STR;
}
else if (digit(c))
{
while (digit (c) || isletter (c) || c == '#')
c = *cp++;
c = *--cp;
*cp = '\0';
tokval = strlong (tp);
*cp = c;
lasttok = curtok;
curtok = NUM;
}
else
{
c1 = *cp++;
if ((c == EQ) && (c1 == EQ))
c = EQEQ;
else if ((c == NOT) && (c1 == EQ))
c = NEQ;
else if ((c == GT) && (c1 == EQ))
c = GEQ;
else if ((c == LT) && (c1 == EQ))
c = LEQ;
else
cp--; /* `unget' the character */
lasttok = curtok;
curtok = c;
}
tp = cp;
}
static void
evalerror (msg)
char *msg;
{
builtin_error ("%s: %s (remainder of expression is \"%s\")",
expression, msg, (tp && *tp) ? tp : "");
longjmp (evalbuf, 1);
}
/* Convert a string to a long integer, with an arbitrary base.
0nnn -> base 8
0xnn -> base 16
Anything else: [base#]number (this is from the ISO Pascal spec). */
static long
strlong (num)
char *num;
{
register char *s = num;
register int c;
int base = 10;
long val = 0L;
if (s == NULL || *s == NULL)
return 0L;
if (*s == '0')
{
s++;
if (s == NULL || *s == NULL)
return 0L;
/* Base 16? */
if (*s == 'x' || *s == 'X')
{
base = 16;
s++;
}
else
base = 8;
}
for (c = *s++; c; c = *s++)
{
if (c == '#')
{
base = (int)val;
/* Illegal base specifications are silently reset to base 10.
I don't think that this is a good idea? */
if (base < 2 || base > 36)
base = 10;
val = 0L;
}
else
if (isletter(c) || digit(c))
{
if (digit(c))
c = digit_value(c);
else if (c >= 'a' && c <= 'z')
c -= 'a' - 10;
else if (c >= 'A' && c <= 'Z')
c -= 'A' - 10;
if (c >= base)
evalerror ("value too great for base");
val = (val * base) + c;
}
else
break;
}
return (val);
}

View File

@@ -0,0 +1,18 @@
/* filecntl.h - Definitions to set file descriptors to close-on-exec. */
#if !defined (_FILECNTL_H_)
#define _FILECNTL_H_
#include <fcntl.h>
/* Definitions to set file descriptors to close-on-exec, the Posix way. */
#if !defined (FD_CLOEXEC)
#define FD_CLOEXEC 1
#endif
#define FD_NCLOEXEC 0
#define SET_CLOSE_ON_EXEC(fd) (fcntl ((fd), F_SETFD, FD_CLOEXEC))
#define SET_OPEN_ON_EXEC(fd) (fcntl ((fd), F_SETFD, FD_NCLOEXEC))
#endif /* ! _FILECNTL_H_ */

228
bin/old/bash-1.11/flags.c Normal file
View File

@@ -0,0 +1,228 @@
/* flags.c -- Everything about flags except the `set' command. That
is in builtins.c */
/* Copyright (C) 1987,1989 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 1, 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; see the file COPYING. If not, write to the Free Software
Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
/* Flags hacking. */
#include "config.h"
#include "flags.h"
#include "general.h"
#include "quit.h"
/* **************************************************************** */
/* */
/* The Standard Sh Flags. */
/* */
/* **************************************************************** */
/* Non-zero means automatically mark variables which are modified or created
as auto export variables. */
int mark_modified_vars = 0;
/* Non-zero causes asynchronous job notification. Otherwise, job state
notification only takes place just before a primary prompt is printed. */
int asynchronous_notification = 0;
/* Non-zero means exit immediately if a command exits with a non-zero
exit status. */
int exit_immediately_on_error = 0;
/* Non-zero means disable filename globbing. */
int disallow_filename_globbing = 0;
/* Non-zero means to locate and remember function commands as functions are
defined. Function commands are normally located when the function is
executed. */
int locate_commands_in_functions = 0;
/* Non-zero means that all keyword arguments are placed into the environment
for a command, not just those that appear on the line before the command
name. */
int place_keywords_in_env = 0;
/* Non-zero means read commands, but don't execute tham. This is useful
for debugging shell scripts that should do something hairy and possibly
desctructive. */
int read_but_dont_execute = 0;
/* Non-zero means end of file is after one command. */
int just_one_command = 0;
/* Non-zero means don't overwrite existing files while doing redirections. */
int noclobber = 0;
/* Non-zero means trying to get the value of $i where $i is undefined
causes an error, instead of a null substitution. */
int unbound_vars_is_error = 0;
/* Non-zero means type out input lines after you read them. */
int echo_input_at_read = 0;
/* Non-zero means type out the command definition after reading, but
before executing. */
int echo_command_at_execute = 0;
/* Non-zero means turn off the job control features. */
int jobs_m_flag = 0;
/* Non-zero means this shell is interactive, even if running under a
pipe. */
int forced_interactive = 0;
/* **************************************************************** */
/* */
/* Non-Standard Flags Follow Here. */
/* */
/* **************************************************************** */
/* Non-zero means do lexical scoping in the body of a FOR command. */
int lexical_scoping = 0;
/* Non-zero means no such thing as invisible variables. */
int no_invisible_vars = 0;
/* Non-zero means don't look up or remember command names in a hash table, */
int hashing_disabled = 0;
/* Non-zero means that we are doing history expansion. The default.
This means !22 gets the 22nd line of history. */
int history_expansion = 1;
/* **************************************************************** */
/* */
/* The Flags ALIST. */
/* */
/* **************************************************************** */
struct flags_alist shell_flags[] = {
/* Standard sh flags. */
{ "a", &mark_modified_vars },
#if defined (JOB_CONTROL)
{ "b", &asynchronous_notification },
#endif /* JOB_CONTROL */
{ "e", &exit_immediately_on_error },
{ "f", &disallow_filename_globbing },
{ "h", &locate_commands_in_functions }, /* Oh, yeah, good mnemonic. */
{ "i", &forced_interactive },
{ "k", &place_keywords_in_env },
{ "n", &read_but_dont_execute },
{ "t", &just_one_command },
{ "u", &unbound_vars_is_error },
{ "v", &echo_input_at_read },
{ "x", &echo_command_at_execute },
{ "C", &noclobber },
#if defined (JOB_CONTROL)
{ "m", &jobs_m_flag },
#endif
/* New flags that control non-standard things. */
{ "l", &lexical_scoping },
{ "I", &no_invisible_vars },
/* I want `h', but locate_commands_in_functions has it. Great. */
{ "d", &hashing_disabled },
/* Once again, we don't have the right mnemonic. */
{ "H", &history_expansion },
{(char *)NULL, (int *)NULL}
};
int *
find_flag (name)
char *name;
{
int i = 0;
while (shell_flags[i].name) {
if (strcmp (shell_flags[i].name, name) == 0)
return (shell_flags[i].value);
i++;
}
return ((int *)FLAG_ERROR);
}
/* Change the state of a flag, and return it's original value, or return
FLAG_ERROR if there is no flag called NAME. ON_OR_OFF should be one
of FLAG_ON or FLAG_OFF. */
/* With FLAG being a character. */
change_flag_char (flag, on_or_off)
int flag;
int on_or_off;
{
char name[2];
name[0] = flag; name[1] = '\0';
return (change_flag (name, on_or_off));
}
/* With FLAG being a string. */
change_flag (flag, on_or_off)
char *flag;
int on_or_off;
{
int *value = find_flag (flag);
int old_value;
if (value == (int *)FLAG_ERROR) return (FLAG_ERROR);
else old_value = *value;
if (on_or_off == FLAG_ON)
*value = 1;
else
{
if (on_or_off == FLAG_OFF)
*value = 0;
else
return (FLAG_ERROR);
}
#if defined (JOB_CONTROL)
/* Special hack for the -m flag. */
if (value == &jobs_m_flag)
{
extern set_job_control ();
set_job_control (on_or_off == '-');
}
#endif /* JOB_CONTROL */
return (old_value);
}
/* Return a string which is the names of all the currently
set shell flags. */
char *
which_set_flags ()
{
char *temp =
(char *)xmalloc (1 + sizeof (shell_flags) / (2 * sizeof (char *)));
int index, string_index = 0;
for (index = 0; shell_flags[index].name; index++)
if (*(shell_flags[index].value))
temp[string_index++] = *(shell_flags[index].name);
temp[string_index] = '\0';
return (temp);
}

34
bin/old/bash-1.11/flags.h Normal file
View File

@@ -0,0 +1,34 @@
/* flags.h -- a list of all the flags that the shell knows about. You add
a flag to this program by adding the name here, and in flags.c. */
#if !defined (_FLAGS_H)
#define _FLAGS_H
/* Welcome to the world of Un*x, where everything is slightly
backwards. */
#define FLAG_ON '-'
#define FLAG_OFF '+'
#define FLAG_ERROR -1
/* The thing that we build the array of flags out of. */
struct flags_alist {
char *name;
int *value;
};
extern struct flags_alist shell_flags[];
extern int
mark_modified_vars, exit_immediately_on_error, disallow_filename_globbing,
locate_commands_in_functions, place_keywords_in_env, read_but_dont_execute,
just_one_command, unbound_vars_is_error, echo_input_at_read,
echo_command_at_execute, lexical_scoping, no_invisible_vars, noclobber,
hashing_disabled, forced_interactive, history_expansion,
asynchronous_notification;
extern int *find_flag ();
extern int change_flag (), change_flag_char ();
extern char *which_set_flags ();
#endif /* _FLAGS_H */

Some files were not shown because too many files have changed in this diff Show More