mirror of
https://https.git.savannah.gnu.org/git/bash.git
synced 2026-06-24 06:17:57 +02:00
commit bash-20141031 snapshot
This commit is contained in:
+103
-4
@@ -6576,10 +6576,10 @@ lib/readline/display.c
|
||||
8/26
|
||||
----
|
||||
builtins/evalstring.c
|
||||
- evalstring: if CURRENT_TOKEN == yacc_EOF, reset it to newline. This is
|
||||
instead of calling reset_parser(); that might still be needed. Fixes
|
||||
bug with eval and a subsequent statement ending with EOF reported by
|
||||
<jim.avera@gmail.org>
|
||||
- evalstring: if CURRENT_TOKEN == yacc_EOF, reset it to newline. This
|
||||
is instead of calling reset_parser(); that might still be needed.
|
||||
Fixes bug with eval and a subsequent statement ending with EOF
|
||||
reported by <jim.avera@gmail.org>
|
||||
|
||||
pcomplete.c
|
||||
- filter_stringlist: when extglob is on, a leading ! in the filter
|
||||
@@ -7037,3 +7037,102 @@ subst.c
|
||||
the outer quotes don't make the characters in the expansion of
|
||||
$* special. Posix interp 221. Reported by Stephane Chazelas
|
||||
<stephane.chazelas@gmail.com>
|
||||
|
||||
10/28
|
||||
-----
|
||||
lib/readline/bind.c
|
||||
- enable-bracketed-paste: new bindable variable, enables support for
|
||||
a terminal's `bracketed paste mode'. Code contributed by
|
||||
Daniel Colascione <dancol@dancol.org>
|
||||
|
||||
lib/readline/doc/{readline.3,rluser.texi}
|
||||
- enable-bracketed-paste: add description
|
||||
|
||||
lib/readline/{readline.c,rlprivate.h}
|
||||
- _rl_enable_bracketed_paste: declarations
|
||||
- #defines for use by bracketed paste implementation
|
||||
|
||||
lib/readline/rltty.c
|
||||
- rl_prep_terminal: send BRACK_PASTE_INIT string to terminal if we
|
||||
are supposed to enable bracketed-paste mode; change terminal_prepped
|
||||
to indicate we sent that string and need to clean up
|
||||
- rl_deprep_terminal: if terminal_prepped indicates we sent the
|
||||
bracketed-paste mode init string to the terminal, send the cleanup
|
||||
string before restoring the terminal modes
|
||||
|
||||
lib/readline/kill.c
|
||||
- rl_bracketed_paste_begin: function to read bracketed paste until
|
||||
BRACK_PASTE_SUFF; discard the suffix, and insert the rest of the
|
||||
paste as a single (undoable) object. Bound to BRACK_PASTE_PREF
|
||||
|
||||
lib/readline/funmap.c
|
||||
- bracketed-paste-begin: new bindable command, executes
|
||||
rl_bracketed_paste_begin
|
||||
|
||||
lib/readline/readline.c
|
||||
- bind_bracketed_paste_prefix: new function, sets up to recognize
|
||||
the bracketed paste prefix sequence (BRACK_PASTE_PREF) in emacs
|
||||
keymap and vi insertion keymap
|
||||
- readline_initialize_everything: call bind_bracketed_paste_prefix
|
||||
|
||||
11/1
|
||||
----
|
||||
builtins/ulimit.def
|
||||
- RLIMIT_POSIXLOCKS: now synonym for RLIMIT_LOCKS
|
||||
- -k: new option: RLIMIT_KQUEUES, max kqueues allocated for this
|
||||
process
|
||||
- -P: new option: RLIMIT_NPTS, max number of pseudoterminals available
|
||||
to this process
|
||||
|
||||
doc/{bash.1,bashref.texi}
|
||||
- document `ulimit -k' option
|
||||
- document `ulimit -P' option
|
||||
|
||||
parse.y
|
||||
- `timespec list_terminator' production: if the list terminator is `;'
|
||||
set last_read_token to `;' to allow things like `time ; command' to
|
||||
time null commands and not throw a syntax error. Patch from
|
||||
Piotr Grzybowski <narsil.pl@gmail.com>
|
||||
- `BANG list_terminator' production: do the same thing
|
||||
|
||||
variables.c
|
||||
- sv_optind: use find_shell_variable and get_variable_value so we can
|
||||
have the variable's context in the case we need to do something
|
||||
when we are restoring a previous variable context's value
|
||||
|
||||
builtins/getopt.h
|
||||
- sh_getopt_state_t: struct to save sh_getopt's internal state so we
|
||||
can restore it around function calls in the event that we have a
|
||||
local copy of OPTIND
|
||||
|
||||
builtins/getopt.[ch]
|
||||
- sh_getopt_{save,restore}_istate: new functions to save and restore
|
||||
getopt's internal state
|
||||
- sh_getopt_{alloc,dispose}_istate: new functions to allocate and
|
||||
deallocate sh_getopt_istate_t objects
|
||||
|
||||
execute_cmd.c
|
||||
- maybe_restore_getopt_state: restore sh_getopt state after executing
|
||||
function body iff the funtion declared a local copy of OPTIND
|
||||
- execute_function: save sh_getopt state before executing function body
|
||||
- execute_function: note in getopt_state->flags whether or not the
|
||||
function declared a local copy of OPTIND; used by maybe_restore_getopt_state
|
||||
- execute_function: maybe restore sh_getopt state before returning via
|
||||
call to maybe_restore_getopt_state. Fixes bugs with getopts and
|
||||
state between calls reported in 2011 by Bernd Eggink <monoped@sudrala.de>
|
||||
and in 2014 by Oyvind Hvidsten <oyvind.hvidsten@dampir.no>
|
||||
|
||||
configure.ac
|
||||
- enable-function-import: new option, controls whether function imports
|
||||
are included. Enabled by default. Patch from David Galos
|
||||
<davegalos@google.com>
|
||||
|
||||
config.h.in
|
||||
- FUNCTION_IMPORT: define controlled by enable-function-import above
|
||||
|
||||
variables.c
|
||||
- initialize_shell_variables: include code to import function definitions
|
||||
from the environment if FUNCTION_IMPORT is defined
|
||||
|
||||
doc/bashref.texi
|
||||
- --enable_function-import: document new configuration option
|
||||
|
||||
+7135
File diff suppressed because it is too large
Load Diff
@@ -832,6 +832,7 @@ tests/array14.sub f
|
||||
tests/array15.sub f
|
||||
tests/array16.sub f
|
||||
tests/array17.sub f
|
||||
tests/array18.sub f
|
||||
tests/array-at-star f
|
||||
tests/array2.right f
|
||||
tests/assoc.tests f
|
||||
@@ -899,6 +900,7 @@ tests/dollar-at-star1.sub f
|
||||
tests/dollar-at-star2.sub f
|
||||
tests/dollar-at-star3.sub f
|
||||
tests/dollar-at-star4.sub f
|
||||
tests/dollar-at-star5.sub f
|
||||
tests/dollar-at1.sub f
|
||||
tests/dollar-at2.sub f
|
||||
tests/dollar-at3.sub f
|
||||
|
||||
+2
-1
@@ -1,4 +1,4 @@
|
||||
# Makefile for bash-4.3, version 4.11
|
||||
# Makefile for bash-4.3, version 4.12
|
||||
#
|
||||
# Copyright (C) 1996-2012 Free Software Foundation, Inc.
|
||||
|
||||
@@ -937,6 +937,7 @@ execute_cmd.o: ${BASHINCDIR}/memalloc.h ${GRAM_H} flags.h builtins.h jobs.h quit
|
||||
execute_cmd.o: execute_cmd.h findcmd.h redir.h trap.h test.h pathexp.h
|
||||
execute_cmd.o: $(DEFSRC)/common.h ${DEFDIR}/builtext.h ${GLOB_LIBSRC}/strmatch.h
|
||||
execute_cmd.o: ${BASHINCDIR}/posixtime.h ${BASHINCDIR}/chartypes.h
|
||||
execute_cmd.o: $(DEFSRC)/getopt.h
|
||||
expr.o: config.h bashansi.h ${BASHINCDIR}/ansi_stdlib.h
|
||||
expr.o: shell.h syntax.h config.h bashjmp.h ${BASHINCDIR}/posixjmp.h command.h ${BASHINCDIR}/stdc.h error.h
|
||||
expr.o: general.h xmalloc.h bashtypes.h variables.h arrayfunc.h conftypes.h array.h hashlib.h
|
||||
|
||||
+1555
File diff suppressed because it is too large
Load Diff
+15
-1
@@ -1,5 +1,5 @@
|
||||
@%:@! /bin/sh
|
||||
@%:@ From configure.ac for Bash 4.3, version 4.063.
|
||||
@%:@ From configure.ac for Bash 4.3, version 4.064.
|
||||
@%:@ Guess values for system-dependent variables and create Makefiles.
|
||||
@%:@ Generated by GNU Autoconf 2.69 for bash 4.3-maint.
|
||||
@%:@
|
||||
@@ -809,6 +809,7 @@ enable_disabled_builtins
|
||||
enable_dparen_arithmetic
|
||||
enable_extended_glob
|
||||
enable_extended_glob_default
|
||||
enable_funtion_import
|
||||
enable_glob_asciiranges_default
|
||||
enable_help_builtin
|
||||
enable_history
|
||||
@@ -1498,6 +1499,9 @@ Optional Features:
|
||||
--enable-extended-glob-default
|
||||
force extended pattern matching to be enabled by
|
||||
default
|
||||
--enable-function-import
|
||||
allow bash to import exported function definitions
|
||||
by default
|
||||
--enable-glob-asciiranges-default
|
||||
force bracket range expressions in pattern matching
|
||||
to use the C locale by default
|
||||
@@ -3002,6 +3006,7 @@ opt_casemod_expansions=yes
|
||||
opt_extglob_default=no
|
||||
opt_dircomplete_expand_default=no
|
||||
opt_globascii_default=no
|
||||
opt_function_import=yes
|
||||
|
||||
opt_static_link=no
|
||||
opt_profiling=no
|
||||
@@ -3115,6 +3120,11 @@ if test "${enable_extended_glob_default+set}" = set; then :
|
||||
enableval=$enable_extended_glob_default; opt_extglob_default=$enableval
|
||||
fi
|
||||
|
||||
@%:@ Check whether --enable-funtion-import was given.
|
||||
if test "${enable_funtion_import+set}" = set; then :
|
||||
enableval=$enable_funtion_import; opt_extglob_default=$enableval
|
||||
fi
|
||||
|
||||
@%:@ Check whether --enable-glob-asciiranges-default was given.
|
||||
if test "${enable_glob_asciiranges_default+set}" = set; then :
|
||||
enableval=$enable_glob_asciiranges_default; opt_globascii_default=$enableval
|
||||
@@ -3341,6 +3351,10 @@ $as_echo "@%:@define GLOBASCII_DEFAULT 1" >>confdefs.h
|
||||
else
|
||||
$as_echo "@%:@define GLOBASCII_DEFAULT 0" >>confdefs.h
|
||||
|
||||
fi
|
||||
if test $opt_function_import = yes; then
|
||||
$as_echo "@%:@define FUNCTION_IMPORT 1" >>confdefs.h
|
||||
|
||||
fi
|
||||
|
||||
if test $opt_memscramble = yes; then
|
||||
|
||||
@@ -7,10 +7,10 @@
|
||||
'0',
|
||||
1,
|
||||
[
|
||||
'/sw/share/autoconf'
|
||||
'/opt/local/share/autoconf'
|
||||
],
|
||||
[
|
||||
'/sw/share/autoconf/autoconf/autoconf.m4f',
|
||||
'/opt/local/share/autoconf/autoconf/autoconf.m4f',
|
||||
'aclocal.m4',
|
||||
'configure.ac'
|
||||
],
|
||||
|
||||
+1743
-1738
File diff suppressed because it is too large
Load Diff
@@ -223,6 +223,52 @@ sh_getopt_restore_state (argv)
|
||||
nextchar = argv[sh_curopt] + sh_charindex;
|
||||
}
|
||||
|
||||
sh_getopt_state_t *
|
||||
sh_getopt_alloc_istate ()
|
||||
{
|
||||
sh_getopt_state_t *ret;
|
||||
|
||||
ret = (sh_getopt_state_t *)xmalloc (sizeof (sh_getopt_state_t));
|
||||
return ret;
|
||||
}
|
||||
|
||||
void
|
||||
sh_getopt_dispose_istate (gs)
|
||||
sh_getopt_state_t *gs;
|
||||
{
|
||||
free (gs);
|
||||
}
|
||||
|
||||
sh_getopt_state_t *
|
||||
sh_getopt_save_istate ()
|
||||
{
|
||||
sh_getopt_state_t *ret;
|
||||
|
||||
ret = sh_getopt_alloc_istate ();
|
||||
|
||||
ret->gs_optarg = sh_optarg;
|
||||
ret->gs_optind = sh_optind;
|
||||
ret->gs_curopt = sh_curopt;
|
||||
ret->gs_nextchar = nextchar; /* XXX */
|
||||
ret->gs_charindex = sh_charindex;
|
||||
ret->gs_flags = 0; /* XXX for later use */
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void
|
||||
sh_getopt_restore_istate (state)
|
||||
sh_getopt_state_t *state;
|
||||
{
|
||||
sh_optarg = state->gs_optarg;
|
||||
sh_optind = state->gs_optind;
|
||||
sh_curopt = state->gs_curopt;
|
||||
nextchar = state->gs_nextchar; /* XXX - probably not usable */
|
||||
sh_charindex = state->gs_charindex;
|
||||
|
||||
sh_getopt_dispose_istate (state);
|
||||
}
|
||||
|
||||
#if 0
|
||||
void
|
||||
sh_getopt_debug_restore_state (argv)
|
||||
|
||||
@@ -0,0 +1,339 @@
|
||||
/* getopt.c - getopt for Bash. Used by the getopt builtin. */
|
||||
|
||||
/* Copyright (C) 1993-2009 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Bash, the Bourne Again SHell.
|
||||
|
||||
Bash is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Bash is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Bash. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#if defined (HAVE_UNISTD_H)
|
||||
# ifdef _MINIX
|
||||
# include <sys/types.h>
|
||||
# endif
|
||||
# include <unistd.h>
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include "memalloc.h"
|
||||
#include "../bashintl.h"
|
||||
#include "../shell.h"
|
||||
#include "getopt.h"
|
||||
|
||||
/* For communication from `sh_getopt' to the caller.
|
||||
When `sh_getopt' finds an option that takes an argument,
|
||||
the argument value is returned here. */
|
||||
char *sh_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 `sh_getopt'.
|
||||
|
||||
On entry to `sh_getopt', zero means this is the first call; initialize.
|
||||
|
||||
When `sh_getopt' returns EOF, this is the index of the first of the
|
||||
non-option elements that the caller should itself scan.
|
||||
|
||||
Otherwise, `sh_optind' communicates from one call to the next
|
||||
how much of ARGV has been scanned so far. */
|
||||
|
||||
/* XXX 1003.2 says this must be 1 before any call. */
|
||||
int sh_optind = 0;
|
||||
|
||||
/* Index of the current argument. */
|
||||
static int sh_curopt;
|
||||
|
||||
/* 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;
|
||||
static int sh_charindex;
|
||||
|
||||
/* Callers store zero here to inhibit the error message
|
||||
for unrecognized options. */
|
||||
|
||||
int sh_opterr = 1;
|
||||
|
||||
/* Set to an option character which was unrecognized.
|
||||
This must be initialized on some systems to avoid linking in the
|
||||
system's own getopt implementation. */
|
||||
|
||||
int sh_optopt = '?';
|
||||
|
||||
/* Set to 1 when we see an invalid option; public so getopts can reset it. */
|
||||
int sh_badopt = 0;
|
||||
|
||||
/* 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 `sh_getopt'
|
||||
is called repeatedly, it returns successively each of the option characters
|
||||
from each of the option elements.
|
||||
|
||||
If `sh_getopt' finds another option character, it returns that character,
|
||||
updating `sh_optind' and `nextchar' so that the next call to `sh_getopt' can
|
||||
resume the scan with the following option character or ARGV-element.
|
||||
|
||||
If there are no more option characters, `sh_getopt' returns `EOF'.
|
||||
Then `sh_optind' is the index in ARGV of the first ARGV-element
|
||||
that is not an option.
|
||||
|
||||
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 `sh_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 `sh_optarg'. */
|
||||
|
||||
/* 1003.2 specifies the format of this message. */
|
||||
#define BADOPT(x) fprintf (stderr, _("%s: illegal option -- %c\n"), argv[0], x)
|
||||
#define NEEDARG(x) fprintf (stderr, _("%s: option requires an argument -- %c\n"), argv[0], x)
|
||||
|
||||
int
|
||||
sh_getopt (argc, argv, optstring)
|
||||
int argc;
|
||||
char *const *argv;
|
||||
const char *optstring;
|
||||
{
|
||||
char c, *temp;
|
||||
|
||||
sh_optarg = 0;
|
||||
|
||||
if (sh_optind >= argc || sh_optind < 0) /* XXX was sh_optind > argc */
|
||||
{
|
||||
sh_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 (sh_optind == 0)
|
||||
{
|
||||
sh_optind = 1;
|
||||
nextchar = (char *)NULL;
|
||||
}
|
||||
|
||||
if (nextchar == 0 || *nextchar == '\0')
|
||||
{
|
||||
/* If we have done all the ARGV-elements, stop the scan. */
|
||||
if (sh_optind >= argc)
|
||||
return EOF;
|
||||
|
||||
temp = argv[sh_optind];
|
||||
|
||||
/* Special ARGV-element `--' means premature end of options.
|
||||
Skip it like a null option, and return EOF. */
|
||||
if (temp[0] == '-' && temp[1] == '-' && temp[2] == '\0')
|
||||
{
|
||||
sh_optind++;
|
||||
return EOF;
|
||||
}
|
||||
|
||||
/* If we have come to a non-option, either stop the scan or describe
|
||||
it to the caller and pass it by. This makes the pseudo-option
|
||||
`-' mean the end of options, but does not skip over it. */
|
||||
if (temp[0] != '-' || temp[1] == '\0')
|
||||
return EOF;
|
||||
|
||||
/* We have found another option-ARGV-element.
|
||||
Start decoding its characters. */
|
||||
nextchar = argv[sh_curopt = sh_optind] + 1;
|
||||
sh_charindex = 1;
|
||||
}
|
||||
|
||||
/* Look at and handle the next option-character. */
|
||||
|
||||
c = *nextchar++; sh_charindex++;
|
||||
temp = strchr (optstring, c);
|
||||
|
||||
sh_optopt = c;
|
||||
|
||||
/* Increment `sh_optind' when we start to process its last character. */
|
||||
if (nextchar == 0 || *nextchar == '\0')
|
||||
{
|
||||
sh_optind++;
|
||||
nextchar = (char *)NULL;
|
||||
}
|
||||
|
||||
if (sh_badopt = (temp == NULL || c == ':'))
|
||||
{
|
||||
if (sh_opterr)
|
||||
BADOPT (c);
|
||||
|
||||
return '?';
|
||||
}
|
||||
|
||||
if (temp[1] == ':')
|
||||
{
|
||||
if (nextchar && *nextchar)
|
||||
{
|
||||
/* This is an option that requires an argument. */
|
||||
sh_optarg = nextchar;
|
||||
/* If we end this ARGV-element by taking the rest as an arg,
|
||||
we must advance to the next element now. */
|
||||
sh_optind++;
|
||||
}
|
||||
else if (sh_optind == argc)
|
||||
{
|
||||
if (sh_opterr)
|
||||
NEEDARG (c);
|
||||
|
||||
sh_optopt = c;
|
||||
sh_optarg = ""; /* Needed by getopts. */
|
||||
c = (optstring[0] == ':') ? ':' : '?';
|
||||
}
|
||||
else
|
||||
/* We already incremented `sh_optind' once;
|
||||
increment it again when taking next ARGV-elt as argument. */
|
||||
sh_optarg = argv[sh_optind++];
|
||||
nextchar = (char *)NULL;
|
||||
}
|
||||
return c;
|
||||
}
|
||||
|
||||
void
|
||||
sh_getopt_restore_state (argv)
|
||||
char **argv;
|
||||
{
|
||||
if (nextchar)
|
||||
nextchar = argv[sh_curopt] + sh_charindex;
|
||||
}
|
||||
|
||||
sh_getopt_state_t *
|
||||
sh_getopt_save_istate ()
|
||||
{
|
||||
sh_getopt_state_t *ret;
|
||||
|
||||
ret = (sh_getopt_state_t *)xmalloc (sizeof (sh_getopt_state_t));
|
||||
|
||||
ret->gs_optarg = sh_optarg;
|
||||
ret->gs_optind = sh_optind;
|
||||
ret->gs_curopt = sh_curopt;
|
||||
ret->gs_nextchar = nextchar; /* XXX */
|
||||
ret->gs_charindex = sh_charindex;
|
||||
ret->gs_flags = 0; /* XXX for later use */
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void
|
||||
sh_getopt_restore_istate (state)
|
||||
sh_getopt_state_t *state;
|
||||
{
|
||||
sh_optarg = state->gs_optarg;
|
||||
sh_optind = state->gs_optind;
|
||||
sh_curopt = state->gs_curopt;
|
||||
nextchar = state->gs_nextchar; /* XXX - probably not usable */
|
||||
sh_charindex = state->gs_charindex;
|
||||
|
||||
free (state);
|
||||
}
|
||||
|
||||
#if 0
|
||||
void
|
||||
sh_getopt_debug_restore_state (argv)
|
||||
char **argv;
|
||||
{
|
||||
if (nextchar && nextchar != argv[sh_curopt] + sh_charindex)
|
||||
{
|
||||
itrace("sh_getopt_debug_restore_state: resetting nextchar");
|
||||
nextchar = argv[sh_curopt] + sh_charindex;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef TEST
|
||||
|
||||
/* Compile with -DTEST to make an executable for use in testing
|
||||
the above definition of `sh_getopt'. */
|
||||
|
||||
int
|
||||
main (argc, argv)
|
||||
int argc;
|
||||
char **argv;
|
||||
{
|
||||
int c;
|
||||
int digit_sh_optind = 0;
|
||||
|
||||
while (1)
|
||||
{
|
||||
int this_option_sh_optind = sh_optind ? sh_optind : 1;
|
||||
|
||||
c = sh_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_sh_optind != 0 && digit_sh_optind != this_option_sh_optind)
|
||||
printf ("digits occur in two different argv-elements.\n");
|
||||
digit_sh_optind = this_option_sh_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", sh_optarg);
|
||||
break;
|
||||
|
||||
case '?':
|
||||
break;
|
||||
|
||||
default:
|
||||
printf ("?? sh_getopt returned character code 0%o ??\n", c);
|
||||
}
|
||||
}
|
||||
|
||||
if (sh_optind < argc)
|
||||
{
|
||||
printf ("non-option ARGV-elements: ");
|
||||
while (sh_optind < argc)
|
||||
printf ("%s ", argv[sh_optind++]);
|
||||
printf ("\n");
|
||||
}
|
||||
|
||||
exit (0);
|
||||
}
|
||||
|
||||
#endif /* TEST */
|
||||
@@ -60,6 +60,23 @@ extern int sh_optopt;
|
||||
extern int sh_badopt;
|
||||
|
||||
extern int sh_getopt __P((int, char *const *, const char *));
|
||||
|
||||
typedef struct sh_getopt_state
|
||||
{
|
||||
char *gs_optarg;
|
||||
int gs_optind;
|
||||
int gs_curopt;
|
||||
char *gs_nextchar;
|
||||
int gs_charindex;
|
||||
int gs_flags;
|
||||
} sh_getopt_state_t;
|
||||
|
||||
extern void sh_getopt_restore_state __P((char **));
|
||||
|
||||
extern sh_getopt_state_t *sh_getopt_alloc_istate __P((void));
|
||||
extern void sh_getopt_dispose_istate __P((sh_getopt_state_t *));
|
||||
|
||||
extern sh_getopt_state_t *sh_getopt_save_istate __P((void));
|
||||
extern void sh_getopt_restore_istate __P((sh_getopt_state_t *));
|
||||
|
||||
#endif /* _SH_GETOPT_H */
|
||||
|
||||
@@ -0,0 +1,79 @@
|
||||
/* getopt.h - declarations for getopt. */
|
||||
|
||||
/* Copyright (C) 1989, 1990, 1991, 1992, 1993, 2008,2009 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Bash, the Bourne Again SHell.
|
||||
|
||||
Bash is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Bash is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Bash. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/* XXX THIS HAS BEEN MODIFIED FOR INCORPORATION INTO BASH XXX */
|
||||
|
||||
#ifndef _SH_GETOPT_H
|
||||
#define _SH_GETOPT_H 1
|
||||
|
||||
#include "stdc.h"
|
||||
|
||||
/* 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 *sh_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, `sh_optind' communicates from one call to the next
|
||||
how much of ARGV has been scanned so far. */
|
||||
|
||||
extern int sh_optind;
|
||||
|
||||
/* Callers store zero here to inhibit the error message `getopt' prints
|
||||
for unrecognized options. */
|
||||
|
||||
extern int sh_opterr;
|
||||
|
||||
/* Set to an option character which was unrecognized. */
|
||||
|
||||
extern int sh_optopt;
|
||||
|
||||
/* Set to 1 when an unrecognized option is encountered. */
|
||||
extern int sh_badopt;
|
||||
|
||||
extern int sh_getopt __P((int, char *const *, const char *));
|
||||
|
||||
typedef struct sh_getopt_state
|
||||
{
|
||||
char *gs_optarg;
|
||||
int gs_optind;
|
||||
int gs_curopt;
|
||||
char *gs_nextchar;
|
||||
int gs_charindex;
|
||||
int gs_flags;
|
||||
} sh_getopt_state_t;
|
||||
|
||||
extern void sh_getopt_restore_state __P((char **));
|
||||
|
||||
extern sh_getopt_state_t *sh_getopt_save_istate __P((void));
|
||||
extern void sh_getopt_restore_istate __P((sh_getopt_state_t *));
|
||||
|
||||
#endif /* _SH_GETOPT_H */
|
||||
@@ -0,0 +1,332 @@
|
||||
This file is getopts.def, from which is created getopts.c.
|
||||
It implements the builtin "getopts" in Bash.
|
||||
|
||||
Copyright (C) 1987-2004 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Bash, the Bourne Again SHell.
|
||||
|
||||
Bash is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Bash is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Bash. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
$PRODUCES getopts.c
|
||||
|
||||
$BUILTIN getopts
|
||||
$FUNCTION getopts_builtin
|
||||
$SHORT_DOC getopts optstring name [arg]
|
||||
Parse option arguments.
|
||||
|
||||
Getopts is used by shell procedures to parse positional parameters
|
||||
as options.
|
||||
|
||||
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 invalid 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 invalid option is seen, getopts places '?' into
|
||||
NAME and unsets OPTARG. If a required argument 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.
|
||||
|
||||
Exit Status:
|
||||
Returns success if an option is found; fails if the end of options is
|
||||
encountered or an error occurs.
|
||||
$END
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#if defined (HAVE_UNISTD_H)
|
||||
# ifdef _MINIX
|
||||
# include <sys/types.h>
|
||||
# endif
|
||||
# include <unistd.h>
|
||||
#endif
|
||||
|
||||
#include "../bashansi.h"
|
||||
|
||||
#include "../shell.h"
|
||||
#include "common.h"
|
||||
#include "bashgetopt.h"
|
||||
#include "getopt.h"
|
||||
|
||||
#define G_EOF -1
|
||||
#define G_INVALID_OPT -2
|
||||
#define G_ARG_MISSING -3
|
||||
|
||||
extern char *this_command_name;
|
||||
|
||||
static int getopts_bind_variable __P((char *, char *));
|
||||
static int dogetopts __P((int, char **));
|
||||
|
||||
/* 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;
|
||||
{
|
||||
itrace("getopts_reset: setting newind to %d", newind);
|
||||
sh_optind = newind;
|
||||
sh_badopt = 0;
|
||||
}
|
||||
|
||||
static int
|
||||
getopts_bind_variable (name, value)
|
||||
char *name, *value;
|
||||
{
|
||||
SHELL_VAR *v;
|
||||
|
||||
if (legal_identifier (name))
|
||||
{
|
||||
v = bind_variable (name, value, 0);
|
||||
if (v && (readonly_p (v) || noassign_p (v)))
|
||||
return (EX_MISCERROR);
|
||||
return (v ? EXECUTION_SUCCESS : EXECUTION_FAILURE);
|
||||
}
|
||||
else
|
||||
{
|
||||
sh_invalidid (name);
|
||||
return (EXECUTION_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
/* 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 invalid option characters. The handling is as follows.
|
||||
|
||||
INVALID 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, i, n;
|
||||
char strval[2], numval[16];
|
||||
char *optstr; /* list of options */
|
||||
char *name; /* variable to get flag val */
|
||||
char *t;
|
||||
|
||||
if (argc < 3)
|
||||
{
|
||||
builtin_usage ();
|
||||
return (EX_USAGE);
|
||||
}
|
||||
|
||||
/* argv[0] is "getopts". */
|
||||
|
||||
optstr = argv[1];
|
||||
name = argv[2];
|
||||
argc -= 2;
|
||||
argv += 2;
|
||||
|
||||
special_error = optstr[0] == ':';
|
||||
|
||||
if (special_error)
|
||||
{
|
||||
old_opterr = sh_opterr;
|
||||
optstr++;
|
||||
sh_opterr = 0; /* suppress diagnostic messages */
|
||||
}
|
||||
|
||||
if (argc > 1)
|
||||
{
|
||||
sh_getopt_restore_state (argv);
|
||||
t = argv[0];
|
||||
argv[0] = dollar_vars[0];
|
||||
ret = sh_getopt (argc, argv, optstr);
|
||||
argv[0] = t;
|
||||
}
|
||||
else if (rest_of_args == (WORD_LIST *)NULL)
|
||||
{
|
||||
for (i = 0; i < 10 && dollar_vars[i]; i++)
|
||||
;
|
||||
|
||||
sh_getopt_restore_state (dollar_vars);
|
||||
ret = sh_getopt (i, dollar_vars, optstr);
|
||||
}
|
||||
else
|
||||
{
|
||||
register WORD_LIST *words;
|
||||
char **v;
|
||||
|
||||
for (i = 0; i < 10 && dollar_vars[i]; i++)
|
||||
;
|
||||
for (words = rest_of_args; words; words = words->next, i++)
|
||||
;
|
||||
v = strvec_create (i + 1);
|
||||
for (i = 0; i < 10 && dollar_vars[i]; i++)
|
||||
v[i] = dollar_vars[i];
|
||||
for (words = rest_of_args; words; words = words->next, i++)
|
||||
v[i] = words->word->word;
|
||||
v[i] = (char *)NULL;
|
||||
sh_getopt_restore_state (v);
|
||||
ret = sh_getopt (i, v, optstr);
|
||||
free (v);
|
||||
}
|
||||
|
||||
if (special_error)
|
||||
sh_opterr = old_opterr;
|
||||
|
||||
/* Set the OPTIND variable in any case, to handle "--" skipping. It's
|
||||
highly unlikely that 14 digits will be too few. */
|
||||
if (sh_optind < 10)
|
||||
{
|
||||
numval[14] = sh_optind + '0';
|
||||
numval[15] = '\0';
|
||||
i = 14;
|
||||
}
|
||||
else
|
||||
{
|
||||
numval[i = 15] = '\0';
|
||||
n = sh_optind;
|
||||
do
|
||||
{
|
||||
numval[--i] = (n % 10) + '0';
|
||||
}
|
||||
while (n /= 10);
|
||||
}
|
||||
bind_variable ("OPTIND", numval + i, 0);
|
||||
|
||||
/* 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 invalid option was encountered, OPTARG is
|
||||
NULL. If a required option argument was missing, OPTARG points
|
||||
to a NULL string (that is, sh_optarg[0] == 0). */
|
||||
if (ret == '?')
|
||||
{
|
||||
if (sh_optarg == NULL)
|
||||
ret = G_INVALID_OPT;
|
||||
else if (sh_optarg[0] == '\0')
|
||||
ret = G_ARG_MISSING;
|
||||
}
|
||||
|
||||
if (ret == G_EOF)
|
||||
{
|
||||
unbind_variable ("OPTARG");
|
||||
getopts_bind_variable (name, "?");
|
||||
return (EXECUTION_FAILURE);
|
||||
}
|
||||
|
||||
if (ret == G_INVALID_OPT)
|
||||
{
|
||||
/* Invalid option encountered. */
|
||||
ret = getopts_bind_variable (name, "?");
|
||||
|
||||
if (special_error)
|
||||
{
|
||||
strval[0] = (char)sh_optopt;
|
||||
strval[1] = '\0';
|
||||
bind_variable ("OPTARG", strval, 0);
|
||||
}
|
||||
else
|
||||
unbind_variable ("OPTARG");
|
||||
|
||||
return (ret);
|
||||
}
|
||||
|
||||
if (ret == G_ARG_MISSING)
|
||||
{
|
||||
/* Required argument missing. */
|
||||
if (special_error)
|
||||
{
|
||||
ret = getopts_bind_variable (name, ":");
|
||||
|
||||
strval[0] = (char)sh_optopt;
|
||||
strval[1] = '\0';
|
||||
bind_variable ("OPTARG", strval, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = getopts_bind_variable (name, "?");
|
||||
unbind_variable ("OPTARG");
|
||||
}
|
||||
return (ret);
|
||||
}
|
||||
|
||||
bind_variable ("OPTARG", sh_optarg, 0);
|
||||
|
||||
strval[0] = (char) ret;
|
||||
strval[1] = '\0';
|
||||
return (getopts_bind_variable (name, strval));
|
||||
}
|
||||
|
||||
/* The getopts builtin. Build an argv, and call dogetopts with it. */
|
||||
int
|
||||
getopts_builtin (list)
|
||||
WORD_LIST *list;
|
||||
{
|
||||
char **av;
|
||||
int ac, ret;
|
||||
|
||||
if (list == 0)
|
||||
{
|
||||
builtin_usage ();
|
||||
return EX_USAGE;
|
||||
}
|
||||
|
||||
reset_internal_getopt ();
|
||||
if (internal_getopt (list, "") != -1)
|
||||
{
|
||||
builtin_usage ();
|
||||
return (EX_USAGE);
|
||||
}
|
||||
list = loptend;
|
||||
|
||||
av = make_builtin_argv (list, &ac);
|
||||
ret = dogetopts (ac, av);
|
||||
free ((char *)av);
|
||||
|
||||
return (ret);
|
||||
}
|
||||
+15
-1
@@ -23,7 +23,7 @@ $PRODUCES ulimit.c
|
||||
$BUILTIN ulimit
|
||||
$FUNCTION ulimit_builtin
|
||||
$DEPENDS_ON !_MINIX
|
||||
$SHORT_DOC ulimit [-SHabcdefilmnpqrstuvxT] [limit]
|
||||
$SHORT_DOC ulimit [-SHabcdefiklmnpqrstuvxPT] [limit]
|
||||
Modify shell resource limits.
|
||||
|
||||
Provides control over the resources available to the shell and processes
|
||||
@@ -39,6 +39,7 @@ Options:
|
||||
-e the maximum scheduling priority (`nice')
|
||||
-f the maximum size of files written by the shell and its children
|
||||
-i the maximum number of pending signals
|
||||
-k the maximum number of kqueues allocated for this process
|
||||
-l the maximum size a process may lock into memory
|
||||
-m the maximum resident set size
|
||||
-n the maximum number of open file descriptors
|
||||
@@ -50,6 +51,7 @@ Options:
|
||||
-u the maximum number of user processes
|
||||
-v the size of virtual memory
|
||||
-x the maximum number of file locks
|
||||
-P the maximum number of pseudoterminals
|
||||
-T the maximum number of threads
|
||||
|
||||
Not all options are available on all platforms.
|
||||
@@ -131,11 +133,17 @@ extern int errno;
|
||||
# define print_rlimtype(num, nl) printf ("%ld%s", num, nl ? "\n" : "")
|
||||
#endif
|
||||
|
||||
/* Alternate names */
|
||||
|
||||
/* Some systems use RLIMIT_NOFILE, others use RLIMIT_OFILE */
|
||||
#if defined (HAVE_RESOURCE) && defined (RLIMIT_OFILE) && !defined (RLIMIT_NOFILE)
|
||||
# define RLIMIT_NOFILE RLIMIT_OFILE
|
||||
#endif /* HAVE_RESOURCE && RLIMIT_OFILE && !RLIMIT_NOFILE */
|
||||
|
||||
#if defined (HAVE_RESOURCE) && defined (RLIMIT_POSIXLOCKS) && !defined (RLIMIT_LOCKS)
|
||||
# define RLIMIT_LOCKS RLIMIT_POSIXLOCKS
|
||||
#endif /* HAVE_RESOURCE && RLIMIT_POSIXLOCKS && !RLIMIT_LOCKS */
|
||||
|
||||
/* Some systems have these, some do not. */
|
||||
#ifdef RLIMIT_FSIZE
|
||||
# define RLIMIT_FILESIZE RLIMIT_FSIZE
|
||||
@@ -223,6 +231,9 @@ typedef struct {
|
||||
} RESOURCE_LIMITS;
|
||||
|
||||
static RESOURCE_LIMITS limits[] = {
|
||||
#ifdef RLIMIT_NPTS
|
||||
{ 'P', RLIMIT_NPTS, 1, "number of pseudoterminals", (char *)NULL },
|
||||
#endif
|
||||
#ifdef RLIMIT_PTHREAD
|
||||
{ 'T', RLIMIT_PTHREAD, 1, "number of threads", (char *)NULL },
|
||||
#endif
|
||||
@@ -242,6 +253,9 @@ static RESOURCE_LIMITS limits[] = {
|
||||
#ifdef RLIMIT_SIGPENDING
|
||||
{ 'i', RLIMIT_SIGPENDING, 1, "pending signals", (char *)NULL },
|
||||
#endif
|
||||
#ifdef RLIMIT_KQUEUES
|
||||
{ 'k', RLIMIT_KQUEUES, 1, "max kqueues", (char *)NULL" },
|
||||
#endif
|
||||
#ifdef RLIMIT_MEMLOCK
|
||||
{ 'l', RLIMIT_MEMLOCK, 1024, "max locked memory", "kbytes" },
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,793 @@
|
||||
This file is ulimit.def, from which is created ulimit.c.
|
||||
It implements the builtin "ulimit" in Bash.
|
||||
|
||||
Copyright (C) 1987-2010 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Bash, the Bourne Again SHell.
|
||||
|
||||
Bash is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Bash is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Bash. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
$PRODUCES ulimit.c
|
||||
|
||||
$BUILTIN ulimit
|
||||
$FUNCTION ulimit_builtin
|
||||
$DEPENDS_ON !_MINIX
|
||||
$SHORT_DOC ulimit [-SHabcdefilmnpqrstuvxT] [limit]
|
||||
Modify shell resource limits.
|
||||
|
||||
Provides control over the resources available to the shell and processes
|
||||
it creates, on systems that allow such control.
|
||||
|
||||
Options:
|
||||
-S use the `soft' resource limit
|
||||
-H use the `hard' resource limit
|
||||
-a all current limits are reported
|
||||
-b the socket buffer size
|
||||
-c the maximum size of core files created
|
||||
-d the maximum size of a process's data segment
|
||||
-e the maximum scheduling priority (`nice')
|
||||
-f the maximum size of files written by the shell and its children
|
||||
-i the maximum number of pending signals
|
||||
-k the maximum number of kqueues allocated for this process
|
||||
-l the maximum size a process may lock into memory
|
||||
-m the maximum resident set size
|
||||
-n the maximum number of open file descriptors
|
||||
-p the pipe buffer size
|
||||
-q the maximum number of bytes in POSIX message queues
|
||||
-r the maximum real-time scheduling priority
|
||||
-s the maximum stack size
|
||||
-t the maximum amount of cpu time in seconds
|
||||
-u the maximum number of user processes
|
||||
-v the size of virtual memory
|
||||
-x the maximum number of file locks
|
||||
-T the maximum number of threads
|
||||
|
||||
Not all options are available on all platforms.
|
||||
|
||||
If LIMIT is given, it is the new value of the specified resource; the
|
||||
special LIMIT values `soft', `hard', and `unlimited' stand for the
|
||||
current soft limit, the current hard limit, and no limit, respectively.
|
||||
Otherwise, the current value of the specified resource is printed. If
|
||||
no option is given, then -f is assumed.
|
||||
|
||||
Values are in 1024-byte increments, except for -t, which is in seconds,
|
||||
-p, which is in increments of 512 bytes, and -u, which is an unscaled
|
||||
number of processes.
|
||||
|
||||
Exit Status:
|
||||
Returns success unless an invalid option is supplied or an error occurs.
|
||||
$END
|
||||
|
||||
#if !defined (_MINIX)
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include "../bashtypes.h"
|
||||
#if defined (HAVE_SYS_PARAM_H)
|
||||
# include <sys/param.h>
|
||||
#endif
|
||||
|
||||
#if defined (HAVE_UNISTD_H)
|
||||
# include <unistd.h>
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "../bashintl.h"
|
||||
|
||||
#include "../shell.h"
|
||||
#include "common.h"
|
||||
#include "bashgetopt.h"
|
||||
#include "pipesize.h"
|
||||
|
||||
#if !defined (errno)
|
||||
extern int errno;
|
||||
#endif
|
||||
|
||||
/* For some reason, HPUX chose to make these definitions visible only if
|
||||
_KERNEL is defined, so we define _KERNEL before including <sys/resource.h>
|
||||
and #undef it afterward. */
|
||||
#if defined (HAVE_RESOURCE)
|
||||
# include <sys/time.h>
|
||||
# if defined (HPUX) && defined (RLIMIT_NEEDS_KERNEL)
|
||||
# define _KERNEL
|
||||
# endif
|
||||
# include <sys/resource.h>
|
||||
# if defined (HPUX) && defined (RLIMIT_NEEDS_KERNEL)
|
||||
# undef _KERNEL
|
||||
# endif
|
||||
#elif defined (HAVE_SYS_TIMES_H)
|
||||
# include <sys/times.h>
|
||||
#endif
|
||||
|
||||
#if defined (HAVE_LIMITS_H)
|
||||
# include <limits.h>
|
||||
#endif
|
||||
|
||||
/* Check for the most basic symbols. If they aren't present, this
|
||||
system's <sys/resource.h> isn't very useful to us. */
|
||||
#if !defined (RLIMIT_FSIZE) || !defined (HAVE_GETRLIMIT)
|
||||
# undef HAVE_RESOURCE
|
||||
#endif
|
||||
|
||||
#if !defined (HAVE_RESOURCE) && defined (HAVE_ULIMIT_H)
|
||||
# include <ulimit.h>
|
||||
#endif
|
||||
|
||||
#if !defined (RLIMTYPE)
|
||||
# define RLIMTYPE long
|
||||
# define string_to_rlimtype(s) strtol(s, (char **)NULL, 10)
|
||||
# define print_rlimtype(num, nl) printf ("%ld%s", num, nl ? "\n" : "")
|
||||
#endif
|
||||
|
||||
/* Alternate names */
|
||||
|
||||
/* Some systems use RLIMIT_NOFILE, others use RLIMIT_OFILE */
|
||||
#if defined (HAVE_RESOURCE) && defined (RLIMIT_OFILE) && !defined (RLIMIT_NOFILE)
|
||||
# define RLIMIT_NOFILE RLIMIT_OFILE
|
||||
#endif /* HAVE_RESOURCE && RLIMIT_OFILE && !RLIMIT_NOFILE */
|
||||
|
||||
#if defined (HAVE_RESOURCE) && defined (RLIMIT_POSIXLOCKS) && !defined (RLIMIT_LOCKS)
|
||||
# define RLIMIT_LOCKS RLIMIT_POSIXLOCKS
|
||||
#endif /* HAVE_RESOURCE && RLIMIT_POSIXLOCKS && !RLIMIT_LOCKS */
|
||||
|
||||
/* Some systems have these, some do not. */
|
||||
#ifdef RLIMIT_FSIZE
|
||||
# define RLIMIT_FILESIZE RLIMIT_FSIZE
|
||||
#else
|
||||
# define RLIMIT_FILESIZE 256
|
||||
#endif
|
||||
|
||||
#define RLIMIT_PIPESIZE 257
|
||||
|
||||
#ifdef RLIMIT_NOFILE
|
||||
# define RLIMIT_OPENFILES RLIMIT_NOFILE
|
||||
#else
|
||||
# define RLIMIT_OPENFILES 258
|
||||
#endif
|
||||
|
||||
#ifdef RLIMIT_VMEM
|
||||
# define RLIMIT_VIRTMEM RLIMIT_VMEM
|
||||
# define RLIMIT_VMBLKSZ 1024
|
||||
#else
|
||||
# ifdef RLIMIT_AS
|
||||
# define RLIMIT_VIRTMEM RLIMIT_AS
|
||||
# define RLIMIT_VMBLKSZ 1024
|
||||
# else
|
||||
# define RLIMIT_VIRTMEM 259
|
||||
# define RLIMIT_VMBLKSZ 1
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifdef RLIMIT_NPROC
|
||||
# define RLIMIT_MAXUPROC RLIMIT_NPROC
|
||||
#else
|
||||
# define RLIMIT_MAXUPROC 260
|
||||
#endif
|
||||
|
||||
#if !defined (RLIMIT_PTHREAD) && defined (RLIMIT_NTHR)
|
||||
# define RLIMIT_PTHREAD RLIMIT_NTHR
|
||||
#endif
|
||||
|
||||
#if !defined (RLIM_INFINITY)
|
||||
# define RLIM_INFINITY 0x7fffffff
|
||||
#endif
|
||||
|
||||
#if !defined (RLIM_SAVED_CUR)
|
||||
# define RLIM_SAVED_CUR RLIM_INFINITY
|
||||
#endif
|
||||
|
||||
#if !defined (RLIM_SAVED_MAX)
|
||||
# define RLIM_SAVED_MAX RLIM_INFINITY
|
||||
#endif
|
||||
|
||||
#define LIMIT_HARD 0x01
|
||||
#define LIMIT_SOFT 0x02
|
||||
|
||||
/* "Blocks" are defined as 512 bytes when in Posix mode and 1024 bytes
|
||||
otherwise. */
|
||||
#define POSIXBLK -2
|
||||
|
||||
#define BLOCKSIZE(x) (((x) == POSIXBLK) ? (posixly_correct ? 512 : 1024) : (x))
|
||||
|
||||
extern int posixly_correct;
|
||||
|
||||
static int _findlim __P((int));
|
||||
|
||||
static int ulimit_internal __P((int, char *, int, int));
|
||||
|
||||
static int get_limit __P((int, RLIMTYPE *, RLIMTYPE *));
|
||||
static int set_limit __P((int, RLIMTYPE, int));
|
||||
|
||||
static void printone __P((int, RLIMTYPE, int));
|
||||
static void print_all_limits __P((int));
|
||||
|
||||
static int set_all_limits __P((int, RLIMTYPE));
|
||||
|
||||
static int filesize __P((RLIMTYPE *));
|
||||
static int pipesize __P((RLIMTYPE *));
|
||||
static int getmaxuprc __P((RLIMTYPE *));
|
||||
static int getmaxvm __P((RLIMTYPE *, RLIMTYPE *));
|
||||
|
||||
typedef struct {
|
||||
int option; /* The ulimit option for this limit. */
|
||||
int parameter; /* Parameter to pass to get_limit (). */
|
||||
int block_factor; /* Blocking factor for specific limit. */
|
||||
const char * const description; /* Descriptive string to output. */
|
||||
const char * const units; /* scale */
|
||||
} RESOURCE_LIMITS;
|
||||
|
||||
static RESOURCE_LIMITS limits[] = {
|
||||
#ifdef RLIMIT_PTHREAD
|
||||
{ 'T', RLIMIT_PTHREAD, 1, "number of threads", (char *)NULL },
|
||||
#endif
|
||||
#ifdef RLIMIT_SBSIZE
|
||||
{ 'b', RLIMIT_SBSIZE, 1, "socket buffer size", "bytes" },
|
||||
#endif
|
||||
#ifdef RLIMIT_CORE
|
||||
{ 'c', RLIMIT_CORE, POSIXBLK, "core file size", "blocks" },
|
||||
#endif
|
||||
#ifdef RLIMIT_DATA
|
||||
{ 'd', RLIMIT_DATA, 1024, "data seg size", "kbytes" },
|
||||
#endif
|
||||
#ifdef RLIMIT_NICE
|
||||
{ 'e', RLIMIT_NICE, 1, "scheduling priority", (char *)NULL },
|
||||
#endif
|
||||
{ 'f', RLIMIT_FILESIZE, POSIXBLK, "file size", "blocks" },
|
||||
#ifdef RLIMIT_SIGPENDING
|
||||
{ 'i', RLIMIT_SIGPENDING, 1, "pending signals", (char *)NULL },
|
||||
#endif
|
||||
#ifdef RLIMIT_KQUEUES
|
||||
{ 'k', RLIMIT_KQUEUES, 1, "max kqueues", (char *)NULL" },
|
||||
#endif
|
||||
#ifdef RLIMIT_MEMLOCK
|
||||
{ 'l', RLIMIT_MEMLOCK, 1024, "max locked memory", "kbytes" },
|
||||
#endif
|
||||
#ifdef RLIMIT_RSS
|
||||
{ 'm', RLIMIT_RSS, 1024, "max memory size", "kbytes" },
|
||||
#endif /* RLIMIT_RSS */
|
||||
{ 'n', RLIMIT_OPENFILES, 1, "open files", (char *)NULL},
|
||||
{ 'p', RLIMIT_PIPESIZE, 512, "pipe size", "512 bytes" },
|
||||
#ifdef RLIMIT_MSGQUEUE
|
||||
{ 'q', RLIMIT_MSGQUEUE, 1, "POSIX message queues", "bytes" },
|
||||
#endif
|
||||
#ifdef RLIMIT_RTPRIO
|
||||
{ 'r', RLIMIT_RTPRIO, 1, "real-time priority", (char *)NULL },
|
||||
#endif
|
||||
#ifdef RLIMIT_STACK
|
||||
{ 's', RLIMIT_STACK, 1024, "stack size", "kbytes" },
|
||||
#endif
|
||||
#ifdef RLIMIT_CPU
|
||||
{ 't', RLIMIT_CPU, 1, "cpu time", "seconds" },
|
||||
#endif /* RLIMIT_CPU */
|
||||
{ 'u', RLIMIT_MAXUPROC, 1, "max user processes", (char *)NULL },
|
||||
#if defined (HAVE_RESOURCE)
|
||||
{ 'v', RLIMIT_VIRTMEM, RLIMIT_VMBLKSZ, "virtual memory", "kbytes" },
|
||||
#endif
|
||||
#ifdef RLIMIT_SWAP
|
||||
{ 'w', RLIMIT_SWAP, 1024, "swap size", "kbytes" },
|
||||
#endif
|
||||
#ifdef RLIMIT_LOCKS
|
||||
{ 'x', RLIMIT_LOCKS, 1, "file locks", (char *)NULL },
|
||||
#endif
|
||||
{ -1, -1, -1, (char *)NULL, (char *)NULL }
|
||||
};
|
||||
#define NCMDS (sizeof(limits) / sizeof(limits[0]))
|
||||
|
||||
typedef struct _cmd {
|
||||
int cmd;
|
||||
char *arg;
|
||||
} ULCMD;
|
||||
|
||||
static ULCMD *cmdlist;
|
||||
static int ncmd;
|
||||
static int cmdlistsz;
|
||||
|
||||
#if !defined (HAVE_RESOURCE) && !defined (HAVE_ULIMIT)
|
||||
long
|
||||
ulimit (cmd, newlim)
|
||||
int cmd;
|
||||
long newlim;
|
||||
{
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
#endif /* !HAVE_RESOURCE && !HAVE_ULIMIT */
|
||||
|
||||
static int
|
||||
_findlim (opt)
|
||||
int opt;
|
||||
{
|
||||
register int i;
|
||||
|
||||
for (i = 0; limits[i].option > 0; i++)
|
||||
if (limits[i].option == opt)
|
||||
return i;
|
||||
return -1;
|
||||
}
|
||||
|
||||
static char optstring[4 + 2 * NCMDS];
|
||||
|
||||
/* Report or set limits associated with certain per-process resources.
|
||||
See the help documentation in builtins.c for a full description. */
|
||||
int
|
||||
ulimit_builtin (list)
|
||||
register WORD_LIST *list;
|
||||
{
|
||||
register char *s;
|
||||
int c, limind, mode, opt, all_limits;
|
||||
|
||||
mode = 0;
|
||||
|
||||
all_limits = 0;
|
||||
|
||||
/* Idea stolen from pdksh -- build option string the first time called. */
|
||||
if (optstring[0] == 0)
|
||||
{
|
||||
s = optstring;
|
||||
*s++ = 'a'; *s++ = 'S'; *s++ = 'H';
|
||||
for (c = 0; limits[c].option > 0; c++)
|
||||
{
|
||||
*s++ = limits[c].option;
|
||||
*s++ = ';';
|
||||
}
|
||||
*s = '\0';
|
||||
}
|
||||
|
||||
/* Initialize the command list. */
|
||||
if (cmdlistsz == 0)
|
||||
cmdlist = (ULCMD *)xmalloc ((cmdlistsz = 16) * sizeof (ULCMD));
|
||||
ncmd = 0;
|
||||
|
||||
reset_internal_getopt ();
|
||||
while ((opt = internal_getopt (list, optstring)) != -1)
|
||||
{
|
||||
switch (opt)
|
||||
{
|
||||
case 'a':
|
||||
all_limits++;
|
||||
break;
|
||||
|
||||
/* -S and -H are modifiers, not real options. */
|
||||
case 'S':
|
||||
mode |= LIMIT_SOFT;
|
||||
break;
|
||||
|
||||
case 'H':
|
||||
mode |= LIMIT_HARD;
|
||||
break;
|
||||
|
||||
case '?':
|
||||
builtin_usage ();
|
||||
return (EX_USAGE);
|
||||
|
||||
default:
|
||||
if (ncmd >= cmdlistsz)
|
||||
cmdlist = (ULCMD *)xrealloc (cmdlist, (cmdlistsz *= 2) * sizeof (ULCMD));
|
||||
cmdlist[ncmd].cmd = opt;
|
||||
cmdlist[ncmd++].arg = list_optarg;
|
||||
break;
|
||||
}
|
||||
}
|
||||
list = loptend;
|
||||
|
||||
if (all_limits)
|
||||
{
|
||||
#ifdef NOTYET
|
||||
if (list) /* setting */
|
||||
{
|
||||
if (STREQ (list->word->word, "unlimited") == 0)
|
||||
{
|
||||
builtin_error (_("%s: invalid limit argument"), list->word->word);
|
||||
return (EXECUTION_FAILURE);
|
||||
}
|
||||
return (set_all_limits (mode == 0 ? LIMIT_SOFT|LIMIT_HARD : mode, RLIM_INFINITY));
|
||||
}
|
||||
#endif
|
||||
print_all_limits (mode == 0 ? LIMIT_SOFT : mode);
|
||||
return (sh_chkwrite (EXECUTION_SUCCESS));
|
||||
}
|
||||
|
||||
/* default is `ulimit -f' */
|
||||
if (ncmd == 0)
|
||||
{
|
||||
cmdlist[ncmd].cmd = 'f';
|
||||
/* `ulimit something' is same as `ulimit -f something' */
|
||||
cmdlist[ncmd++].arg = list ? list->word->word : (char *)NULL;
|
||||
if (list)
|
||||
list = list->next;
|
||||
}
|
||||
|
||||
/* verify each command in the list. */
|
||||
for (c = 0; c < ncmd; c++)
|
||||
{
|
||||
limind = _findlim (cmdlist[c].cmd);
|
||||
if (limind == -1)
|
||||
{
|
||||
builtin_error (_("`%c': bad command"), cmdlist[c].cmd);
|
||||
return (EX_USAGE);
|
||||
}
|
||||
}
|
||||
|
||||
for (c = 0; c < ncmd; c++)
|
||||
if (ulimit_internal (cmdlist[c].cmd, cmdlist[c].arg, mode, ncmd > 1) == EXECUTION_FAILURE)
|
||||
return (EXECUTION_FAILURE);
|
||||
|
||||
return (EXECUTION_SUCCESS);
|
||||
}
|
||||
|
||||
static int
|
||||
ulimit_internal (cmd, cmdarg, mode, multiple)
|
||||
int cmd;
|
||||
char *cmdarg;
|
||||
int mode, multiple;
|
||||
{
|
||||
int opt, limind, setting;
|
||||
int block_factor;
|
||||
RLIMTYPE soft_limit, hard_limit, real_limit, limit;
|
||||
|
||||
setting = cmdarg != 0;
|
||||
limind = _findlim (cmd);
|
||||
if (mode == 0)
|
||||
mode = setting ? (LIMIT_HARD|LIMIT_SOFT) : LIMIT_SOFT;
|
||||
opt = get_limit (limind, &soft_limit, &hard_limit);
|
||||
if (opt < 0)
|
||||
{
|
||||
builtin_error (_("%s: cannot get limit: %s"), limits[limind].description,
|
||||
strerror (errno));
|
||||
return (EXECUTION_FAILURE);
|
||||
}
|
||||
|
||||
if (setting == 0) /* print the value of the specified limit */
|
||||
{
|
||||
printone (limind, (mode & LIMIT_SOFT) ? soft_limit : hard_limit, multiple);
|
||||
return (EXECUTION_SUCCESS);
|
||||
}
|
||||
|
||||
/* Setting the limit. */
|
||||
if (STREQ (cmdarg, "hard"))
|
||||
real_limit = hard_limit;
|
||||
else if (STREQ (cmdarg, "soft"))
|
||||
real_limit = soft_limit;
|
||||
else if (STREQ (cmdarg, "unlimited"))
|
||||
real_limit = RLIM_INFINITY;
|
||||
else if (all_digits (cmdarg))
|
||||
{
|
||||
limit = string_to_rlimtype (cmdarg);
|
||||
block_factor = BLOCKSIZE(limits[limind].block_factor);
|
||||
real_limit = limit * block_factor;
|
||||
|
||||
if ((real_limit / block_factor) != limit)
|
||||
{
|
||||
sh_erange (cmdarg, _("limit"));
|
||||
return (EXECUTION_FAILURE);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
sh_invalidnum (cmdarg);
|
||||
return (EXECUTION_FAILURE);
|
||||
}
|
||||
|
||||
if (set_limit (limind, real_limit, mode) < 0)
|
||||
{
|
||||
builtin_error (_("%s: cannot modify limit: %s"), limits[limind].description,
|
||||
strerror (errno));
|
||||
return (EXECUTION_FAILURE);
|
||||
}
|
||||
|
||||
return (EXECUTION_SUCCESS);
|
||||
}
|
||||
|
||||
static int
|
||||
get_limit (ind, softlim, hardlim)
|
||||
int ind;
|
||||
RLIMTYPE *softlim, *hardlim;
|
||||
{
|
||||
RLIMTYPE value;
|
||||
#if defined (HAVE_RESOURCE)
|
||||
struct rlimit limit;
|
||||
#endif
|
||||
|
||||
if (limits[ind].parameter >= 256)
|
||||
{
|
||||
switch (limits[ind].parameter)
|
||||
{
|
||||
case RLIMIT_FILESIZE:
|
||||
if (filesize (&value) < 0)
|
||||
return -1;
|
||||
break;
|
||||
case RLIMIT_PIPESIZE:
|
||||
if (pipesize (&value) < 0)
|
||||
return -1;
|
||||
break;
|
||||
case RLIMIT_OPENFILES:
|
||||
value = (RLIMTYPE)getdtablesize ();
|
||||
break;
|
||||
case RLIMIT_VIRTMEM:
|
||||
return (getmaxvm (softlim, hardlim));
|
||||
case RLIMIT_MAXUPROC:
|
||||
if (getmaxuprc (&value) < 0)
|
||||
return -1;
|
||||
break;
|
||||
default:
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
*softlim = *hardlim = value;
|
||||
return (0);
|
||||
}
|
||||
else
|
||||
{
|
||||
#if defined (HAVE_RESOURCE)
|
||||
if (getrlimit (limits[ind].parameter, &limit) < 0)
|
||||
return -1;
|
||||
*softlim = limit.rlim_cur;
|
||||
*hardlim = limit.rlim_max;
|
||||
# if defined (HPUX9)
|
||||
if (limits[ind].parameter == RLIMIT_FILESIZE)
|
||||
{
|
||||
*softlim *= 512;
|
||||
*hardlim *= 512; /* Ugh. */
|
||||
}
|
||||
else
|
||||
# endif /* HPUX9 */
|
||||
return 0;
|
||||
#else
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
set_limit (ind, newlim, mode)
|
||||
int ind;
|
||||
RLIMTYPE newlim;
|
||||
int mode;
|
||||
{
|
||||
#if defined (HAVE_RESOURCE)
|
||||
struct rlimit limit;
|
||||
RLIMTYPE val;
|
||||
#endif
|
||||
|
||||
if (limits[ind].parameter >= 256)
|
||||
switch (limits[ind].parameter)
|
||||
{
|
||||
case RLIMIT_FILESIZE:
|
||||
#if !defined (HAVE_RESOURCE)
|
||||
return (ulimit (2, newlim / 512L));
|
||||
#else
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
#endif
|
||||
|
||||
case RLIMIT_OPENFILES:
|
||||
#if defined (HAVE_SETDTABLESIZE)
|
||||
# if defined (__CYGWIN__)
|
||||
/* Grrr... Cygwin declares setdtablesize as void. */
|
||||
setdtablesize (newlim);
|
||||
return 0;
|
||||
# else
|
||||
return (setdtablesize (newlim));
|
||||
# endif
|
||||
#endif
|
||||
case RLIMIT_PIPESIZE:
|
||||
case RLIMIT_VIRTMEM:
|
||||
case RLIMIT_MAXUPROC:
|
||||
default:
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
#if defined (HAVE_RESOURCE)
|
||||
if (getrlimit (limits[ind].parameter, &limit) < 0)
|
||||
return -1;
|
||||
# if defined (HPUX9)
|
||||
if (limits[ind].parameter == RLIMIT_FILESIZE)
|
||||
newlim /= 512; /* Ugh. */
|
||||
# endif /* HPUX9 */
|
||||
val = (current_user.euid != 0 && newlim == RLIM_INFINITY &&
|
||||
(mode & LIMIT_HARD) == 0 && /* XXX -- test */
|
||||
(limit.rlim_cur <= limit.rlim_max))
|
||||
? limit.rlim_max : newlim;
|
||||
if (mode & LIMIT_SOFT)
|
||||
limit.rlim_cur = val;
|
||||
if (mode & LIMIT_HARD)
|
||||
limit.rlim_max = val;
|
||||
|
||||
return (setrlimit (limits[ind].parameter, &limit));
|
||||
#else
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
getmaxvm (softlim, hardlim)
|
||||
RLIMTYPE *softlim, *hardlim;
|
||||
{
|
||||
#if defined (HAVE_RESOURCE)
|
||||
struct rlimit datalim, stacklim;
|
||||
|
||||
if (getrlimit (RLIMIT_DATA, &datalim) < 0)
|
||||
return -1;
|
||||
|
||||
if (getrlimit (RLIMIT_STACK, &stacklim) < 0)
|
||||
return -1;
|
||||
|
||||
/* Protect against overflow. */
|
||||
*softlim = (datalim.rlim_cur / 1024L) + (stacklim.rlim_cur / 1024L);
|
||||
*hardlim = (datalim.rlim_max / 1024L) + (stacklim.rlim_max / 1024L);
|
||||
return 0;
|
||||
#else
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
#endif /* HAVE_RESOURCE */
|
||||
}
|
||||
|
||||
static int
|
||||
filesize(valuep)
|
||||
RLIMTYPE *valuep;
|
||||
{
|
||||
#if !defined (HAVE_RESOURCE)
|
||||
long result;
|
||||
if ((result = ulimit (1, 0L)) < 0)
|
||||
return -1;
|
||||
else
|
||||
*valuep = (RLIMTYPE) result * 512;
|
||||
return 0;
|
||||
#else
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
#endif
|
||||
}
|
||||
|
||||
static int
|
||||
pipesize (valuep)
|
||||
RLIMTYPE *valuep;
|
||||
{
|
||||
#if defined (PIPE_BUF)
|
||||
/* This is defined on Posix systems. */
|
||||
*valuep = (RLIMTYPE) PIPE_BUF;
|
||||
return 0;
|
||||
#else
|
||||
# if defined (_POSIX_PIPE_BUF)
|
||||
*valuep = (RLIMTYPE) _POSIX_PIPE_BUF;
|
||||
return 0;
|
||||
# else
|
||||
# if defined (PIPESIZE)
|
||||
/* This is defined by running a program from the Makefile. */
|
||||
*valuep = (RLIMTYPE) PIPESIZE;
|
||||
return 0;
|
||||
# else
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
# endif /* PIPESIZE */
|
||||
# endif /* _POSIX_PIPE_BUF */
|
||||
#endif /* PIPE_BUF */
|
||||
}
|
||||
|
||||
static int
|
||||
getmaxuprc (valuep)
|
||||
RLIMTYPE *valuep;
|
||||
{
|
||||
long maxchild;
|
||||
|
||||
maxchild = getmaxchild ();
|
||||
if (maxchild < 0)
|
||||
{
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
*valuep = (RLIMTYPE) maxchild;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
print_all_limits (mode)
|
||||
int mode;
|
||||
{
|
||||
register int i;
|
||||
RLIMTYPE softlim, hardlim;
|
||||
|
||||
if (mode == 0)
|
||||
mode |= LIMIT_SOFT;
|
||||
|
||||
for (i = 0; limits[i].option > 0; i++)
|
||||
{
|
||||
if (get_limit (i, &softlim, &hardlim) == 0)
|
||||
printone (i, (mode & LIMIT_SOFT) ? softlim : hardlim, 1);
|
||||
else if (errno != EINVAL)
|
||||
builtin_error ("%s: cannot get limit: %s", limits[i].description,
|
||||
strerror (errno));
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
printone (limind, curlim, pdesc)
|
||||
int limind;
|
||||
RLIMTYPE curlim;
|
||||
int pdesc;
|
||||
{
|
||||
char unitstr[64];
|
||||
int factor;
|
||||
|
||||
factor = BLOCKSIZE(limits[limind].block_factor);
|
||||
if (pdesc)
|
||||
{
|
||||
if (limits[limind].units)
|
||||
sprintf (unitstr, "(%s, -%c) ", limits[limind].units, limits[limind].option);
|
||||
else
|
||||
sprintf (unitstr, "(-%c) ", limits[limind].option);
|
||||
|
||||
printf ("%-20s %16s", limits[limind].description, unitstr);
|
||||
}
|
||||
if (curlim == RLIM_INFINITY)
|
||||
puts ("unlimited");
|
||||
else if (curlim == RLIM_SAVED_MAX)
|
||||
puts ("hard");
|
||||
else if (curlim == RLIM_SAVED_CUR)
|
||||
puts ("soft");
|
||||
else
|
||||
print_rlimtype ((curlim / factor), 1);
|
||||
}
|
||||
|
||||
/* Set all limits to NEWLIM. NEWLIM currently must be RLIM_INFINITY, which
|
||||
causes all limits to be set as high as possible depending on mode (like
|
||||
csh `unlimit'). Returns -1 if NEWLIM is invalid, 0 if all limits
|
||||
were set successfully, and 1 if at least one limit could not be set.
|
||||
|
||||
To raise all soft limits to their corresponding hard limits, use
|
||||
ulimit -S -a unlimited
|
||||
To attempt to raise all hard limits to infinity (superuser-only), use
|
||||
ulimit -H -a unlimited
|
||||
To attempt to raise all soft and hard limits to infinity, use
|
||||
ulimit -a unlimited
|
||||
*/
|
||||
|
||||
static int
|
||||
set_all_limits (mode, newlim)
|
||||
int mode;
|
||||
RLIMTYPE newlim;
|
||||
{
|
||||
register int i;
|
||||
int retval = 0;
|
||||
|
||||
if (newlim != RLIM_INFINITY)
|
||||
{
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (mode == 0)
|
||||
mode = LIMIT_SOFT|LIMIT_HARD;
|
||||
|
||||
for (retval = i = 0; limits[i].option > 0; i++)
|
||||
if (set_limit (i, newlim, mode) < 0)
|
||||
{
|
||||
builtin_error (_("%s: cannot modify limit: %s"), limits[i].description,
|
||||
strerror (errno));
|
||||
retval = 1;
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
#endif /* !_MINIX */
|
||||
@@ -173,6 +173,9 @@
|
||||
/* Define to make the `globasciiranges' shopt option enabled by default. */
|
||||
#undef GLOBASCII_DEFAULT
|
||||
|
||||
/* Define to allow functions to be imported from the environment. */
|
||||
#undef FUNCTION_IMPORT
|
||||
|
||||
/* Define AFS if you are using Transarc's AFS. */
|
||||
#undef AFS
|
||||
|
||||
|
||||
+1154
File diff suppressed because it is too large
Load Diff
@@ -1,5 +1,5 @@
|
||||
#! /bin/sh
|
||||
# From configure.ac for Bash 4.3, version 4.063.
|
||||
# From configure.ac for Bash 4.3, version 4.064.
|
||||
# Guess values for system-dependent variables and create Makefiles.
|
||||
# Generated by GNU Autoconf 2.69 for bash 4.3-maint.
|
||||
#
|
||||
@@ -809,6 +809,7 @@ enable_disabled_builtins
|
||||
enable_dparen_arithmetic
|
||||
enable_extended_glob
|
||||
enable_extended_glob_default
|
||||
enable_funtion_import
|
||||
enable_glob_asciiranges_default
|
||||
enable_help_builtin
|
||||
enable_history
|
||||
@@ -1498,6 +1499,9 @@ Optional Features:
|
||||
--enable-extended-glob-default
|
||||
force extended pattern matching to be enabled by
|
||||
default
|
||||
--enable-function-import
|
||||
allow bash to import exported function definitions
|
||||
by default
|
||||
--enable-glob-asciiranges-default
|
||||
force bracket range expressions in pattern matching
|
||||
to use the C locale by default
|
||||
@@ -3002,6 +3006,7 @@ opt_casemod_expansions=yes
|
||||
opt_extglob_default=no
|
||||
opt_dircomplete_expand_default=no
|
||||
opt_globascii_default=no
|
||||
opt_function_import=yes
|
||||
|
||||
opt_static_link=no
|
||||
opt_profiling=no
|
||||
@@ -3115,6 +3120,11 @@ if test "${enable_extended_glob_default+set}" = set; then :
|
||||
enableval=$enable_extended_glob_default; opt_extglob_default=$enableval
|
||||
fi
|
||||
|
||||
# Check whether --enable-funtion-import was given.
|
||||
if test "${enable_funtion_import+set}" = set; then :
|
||||
enableval=$enable_funtion_import; opt_extglob_default=$enableval
|
||||
fi
|
||||
|
||||
# Check whether --enable-glob-asciiranges-default was given.
|
||||
if test "${enable_glob_asciiranges_default+set}" = set; then :
|
||||
enableval=$enable_glob_asciiranges_default; opt_globascii_default=$enableval
|
||||
@@ -3341,6 +3351,10 @@ $as_echo "#define GLOBASCII_DEFAULT 1" >>confdefs.h
|
||||
else
|
||||
$as_echo "#define GLOBASCII_DEFAULT 0" >>confdefs.h
|
||||
|
||||
fi
|
||||
if test $opt_function_import = yes; then
|
||||
$as_echo "#define FUNCTION_IMPORT 1" >>confdefs.h
|
||||
|
||||
fi
|
||||
|
||||
if test $opt_memscramble = yes; then
|
||||
|
||||
+6
-1
@@ -21,7 +21,7 @@ dnl Process this file with autoconf to produce a configure script.
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
AC_REVISION([for Bash 4.3, version 4.063])dnl
|
||||
AC_REVISION([for Bash 4.3, version 4.064])dnl
|
||||
|
||||
define(bashvers, 4.3)
|
||||
define(relstatus, maint)
|
||||
@@ -193,6 +193,7 @@ opt_casemod_expansions=yes
|
||||
opt_extglob_default=no
|
||||
opt_dircomplete_expand_default=no
|
||||
opt_globascii_default=no
|
||||
opt_function_import=yes
|
||||
|
||||
dnl options that affect how bash is compiled and linked
|
||||
opt_static_link=no
|
||||
@@ -234,6 +235,7 @@ AC_ARG_ENABLE(disabled-builtins, AC_HELP_STRING([--enable-disabled-builtins], [a
|
||||
AC_ARG_ENABLE(dparen-arithmetic, AC_HELP_STRING([--enable-dparen-arithmetic], [include ((...)) command]), opt_dparen_arith=$enableval)
|
||||
AC_ARG_ENABLE(extended-glob, AC_HELP_STRING([--enable-extended-glob], [include ksh-style extended pattern matching]), opt_extended_glob=$enableval)
|
||||
AC_ARG_ENABLE(extended-glob-default, AC_HELP_STRING([--enable-extended-glob-default], [force extended pattern matching to be enabled by default]), opt_extglob_default=$enableval)
|
||||
AC_ARG_ENABLE(funtion-import, AC_HELP_STRING([--enable-function-import], [allow bash to import exported function definitions by default]), opt_extglob_default=$enableval)
|
||||
AC_ARG_ENABLE(glob-asciiranges-default, AC_HELP_STRING([--enable-glob-asciiranges-default], [force bracket range expressions in pattern matching to use the C locale by default]), opt_globascii_default=$enableval)
|
||||
AC_ARG_ENABLE(help-builtin, AC_HELP_STRING([--enable-help-builtin], [include the help builtin]), opt_help=$enableval)
|
||||
AC_ARG_ENABLE(history, AC_HELP_STRING([--enable-history], [turn on command history]), opt_history=$enableval)
|
||||
@@ -357,6 +359,9 @@ AC_DEFINE(GLOBASCII_DEFAULT, 1)
|
||||
else
|
||||
AC_DEFINE(GLOBASCII_DEFAULT, 0)
|
||||
fi
|
||||
if test $opt_function_import = yes; then
|
||||
AC_DEFINE(FUNCTION_IMPORT)
|
||||
fi
|
||||
|
||||
if test $opt_memscramble = yes; then
|
||||
AC_DEFINE(MEMSCRAMBLE)
|
||||
|
||||
+1212
File diff suppressed because it is too large
Load Diff
+11
-3
@@ -5,12 +5,12 @@
|
||||
.\" Case Western Reserve University
|
||||
.\" chet.ramey@case.edu
|
||||
.\"
|
||||
.\" Last Change: Tue Oct 7 11:42:56 EDT 2014
|
||||
.\" Last Change: Sat Nov 1 20:00:51 EDT 2014
|
||||
.\"
|
||||
.\" bash_builtins, strip all but Built-Ins section
|
||||
.if \n(zZ=1 .ig zZ
|
||||
.if \n(zY=1 .ig zY
|
||||
.TH BASH 1 "2014 October 7" "GNU Bash 4.3"
|
||||
.TH BASH 1 "2014 November 1" "GNU Bash 4.3"
|
||||
.\"
|
||||
.\" There's some problem with having a `@'
|
||||
.\" in a tagged paragraph with the BSD man macros.
|
||||
@@ -9924,7 +9924,7 @@ option suppresses shell function lookup, as with the \fBcommand\fP builtin.
|
||||
returns true if all of the arguments are found, false if
|
||||
any are not found.
|
||||
.TP
|
||||
\fBulimit\fP [\fB\-HSTabcdefilmnpqrstuvx\fP [\fIlimit\fP]]
|
||||
\fBulimit\fP [\fB\-HSabcdefiklmnpqrstuvxPT\fP [\fIlimit\fP]]
|
||||
Provides control over the resources available to the shell and to
|
||||
processes started by it, on systems that allow such control.
|
||||
The \fB\-H\fP and \fB\-S\fP options specify that the hard or soft limit is
|
||||
@@ -9973,6 +9973,9 @@ The maximum size of files written by the shell and its children
|
||||
.B \-i
|
||||
The maximum number of pending signals
|
||||
.TP
|
||||
.B \-k
|
||||
The maximum number of kqueues that may be allocated
|
||||
.TP
|
||||
.B \-l
|
||||
The maximum size that may be locked into memory
|
||||
.TP
|
||||
@@ -10008,6 +10011,9 @@ some systems, to its children
|
||||
.B \-x
|
||||
The maximum number of file locks
|
||||
.TP
|
||||
.B \-P
|
||||
The maximum number of pseudoterminals
|
||||
.TP
|
||||
.B \-T
|
||||
The maximum number of threads
|
||||
.PD
|
||||
@@ -10026,8 +10032,10 @@ which is in seconds;
|
||||
.BR \-p ,
|
||||
which is in units of 512-byte blocks;
|
||||
and
|
||||
.BR \-P ,
|
||||
.BR \-T ,
|
||||
.BR \-b ,
|
||||
.BR \-k ,
|
||||
.BR \-n ,
|
||||
and
|
||||
.BR \-u ,
|
||||
|
||||
+10356
File diff suppressed because it is too large
Load Diff
+15
-3
@@ -4449,7 +4449,7 @@ It is a synonym for the @code{declare} builtin command.
|
||||
@item ulimit
|
||||
@btindex ulimit
|
||||
@example
|
||||
ulimit [-abcdefilmnpqrstuvxHST] [@var{limit}]
|
||||
ulimit [-HSabcdefiklmnpqrstuvxPT] [@var{limit}]
|
||||
@end example
|
||||
|
||||
@code{ulimit} provides control over the resources available to processes
|
||||
@@ -4484,6 +4484,9 @@ The maximum size of files written by the shell and its children.
|
||||
@item -i
|
||||
The maximum number of pending signals.
|
||||
|
||||
@item -k
|
||||
The maximum number of kqueues that may be allocated.
|
||||
|
||||
@item -l
|
||||
The maximum size that may be locked into memory.
|
||||
|
||||
@@ -4519,6 +4522,9 @@ some systems, to its children.
|
||||
@item -x
|
||||
The maximum number of file locks.
|
||||
|
||||
@item -P
|
||||
The maximum number of pseudoterminals.
|
||||
|
||||
@item -T
|
||||
The maximum number of threads.
|
||||
@end table
|
||||
@@ -4536,8 +4542,9 @@ When setting new limits, if neither @option{-H} nor @option{-S} is supplied,
|
||||
both the hard and soft limits are set.
|
||||
If no option is given, then @option{-f} is assumed. Values are in 1024-byte
|
||||
increments, except for @option{-t}, which is in seconds; @option{-p},
|
||||
which is in units of 512-byte blocks; and @option{-T}, @option{-b},
|
||||
@option{-n} and @option{-u}, which are unscaled values.
|
||||
which is in units of 512-byte blocks; and @option{-P}, @option{-T},
|
||||
@option{-b},
|
||||
@option{-k}, @option{-n} and @option{-u}, which are unscaled values.
|
||||
|
||||
The return status is zero unless an invalid option or argument is supplied,
|
||||
or an error occurs while setting a new limit.
|
||||
@@ -8128,6 +8135,11 @@ above under @ref{Pattern Matching}.
|
||||
Set the default value of the @var{extglob} shell option described
|
||||
above under @ref{The Shopt Builtin} to be enabled.
|
||||
|
||||
@item --enable-function-import
|
||||
Include support for importing function definitions exported by another
|
||||
instance of the shell from the environment. This option is enabled by
|
||||
default.
|
||||
|
||||
@item --enable-glob-asciirange-default
|
||||
Set the default value of the @var{globasciiranges} shell option described
|
||||
above under @ref{The Shopt Builtin} to be enabled.
|
||||
|
||||
+8773
File diff suppressed because it is too large
Load Diff
+3
-3
@@ -2,10 +2,10 @@
|
||||
Copyright (C) 1988-2014 Free Software Foundation, Inc.
|
||||
@end ignore
|
||||
|
||||
@set LASTCHANGE Tue Oct 7 11:45:14 EDT 2014
|
||||
@set LASTCHANGE Sat Nov 1 20:03:13 EDT 2014
|
||||
|
||||
@set EDITION 4.3
|
||||
@set VERSION 4.3
|
||||
|
||||
@set UPDATED 7 October 2014
|
||||
@set UPDATED-MONTH October 2014
|
||||
@set UPDATED 1 November 2014
|
||||
@set UPDATED-MONTH November 2014
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
@ignore
|
||||
Copyright (C) 1988-2014 Free Software Foundation, Inc.
|
||||
@end ignore
|
||||
|
||||
@set LASTCHANGE Tue Oct 7 11:45:14 EDT 2014
|
||||
|
||||
@set EDITION 4.3
|
||||
@set VERSION 4.3
|
||||
|
||||
@set UPDATED 7 October 2014
|
||||
@set UPDATED-MONTH October 2014
|
||||
+29
-1
@@ -83,6 +83,8 @@ extern int errno;
|
||||
#include "builtins/common.h"
|
||||
#include "builtins/builtext.h" /* list of builtins */
|
||||
|
||||
#include "builtins/getopt.h"
|
||||
|
||||
#include <glob/strmatch.h>
|
||||
#include <tilde/tilde.h>
|
||||
|
||||
@@ -4443,6 +4445,22 @@ execute_builtin (builtin, words, flags, subshell)
|
||||
return (result);
|
||||
}
|
||||
|
||||
static void
|
||||
maybe_restore_getopt_state (gs)
|
||||
sh_getopt_state_t *gs;
|
||||
{
|
||||
SHELL_VAR *v;
|
||||
|
||||
/* If we have a local copy of OPTIND and it's at the right (current)
|
||||
context, then we restore getopt's internal state. If not, we just
|
||||
let it go. We know there is a local OPTIND if gs->gs_flags & 1.
|
||||
This is set below in execute_function() before the context is run. */
|
||||
if (gs->gs_flags & 1)
|
||||
sh_getopt_restore_istate (gs);
|
||||
else
|
||||
free (gs);
|
||||
}
|
||||
|
||||
static int
|
||||
execute_function (var, words, flags, fds_to_close, async, subshell)
|
||||
SHELL_VAR *var;
|
||||
@@ -4462,6 +4480,7 @@ execute_function (var, words, flags, fds_to_close, async, subshell)
|
||||
#endif
|
||||
FUNCTION_DEF *shell_fn;
|
||||
char *sfile, *t;
|
||||
sh_getopt_state_t *gs;
|
||||
|
||||
USE_VAR(fc);
|
||||
|
||||
@@ -4482,17 +4501,21 @@ execute_function (var, words, flags, fds_to_close, async, subshell)
|
||||
if (tc && (flags & CMD_IGNORE_RETURN))
|
||||
tc->flags |= CMD_IGNORE_RETURN;
|
||||
|
||||
gs = sh_getopt_save_istate ();
|
||||
if (subshell == 0)
|
||||
{
|
||||
begin_unwind_frame ("function_calling");
|
||||
push_context (var->name, subshell, temporary_env);
|
||||
/* This has to be before the pop_context(), because the unwinding of
|
||||
local variables may cause the restore of a local declaration of
|
||||
OPTIND to force a getopts state reset. */
|
||||
add_unwind_protect (maybe_restore_getopt_state, gs);
|
||||
add_unwind_protect (pop_context, (char *)NULL);
|
||||
unwind_protect_int (line_number);
|
||||
unwind_protect_int (return_catch_flag);
|
||||
unwind_protect_jmp_buf (return_catch);
|
||||
add_unwind_protect (dispose_command, (char *)tc);
|
||||
unwind_protect_pointer (this_shell_function);
|
||||
unwind_protect_int (loop_level);
|
||||
unwind_protect_int (funcnest);
|
||||
unwind_protect_int (loop_level);
|
||||
}
|
||||
@@ -4638,6 +4661,11 @@ execute_function (var, words, flags, fds_to_close, async, subshell)
|
||||
if (debugging_mode)
|
||||
pop_args ();
|
||||
|
||||
/* If we have a local copy of OPTIND, note it in the saved getopts state. */
|
||||
nfv = find_variable ("OPTIND");
|
||||
if (nfv && nfv->context == variable_context)
|
||||
gs->gs_flags |= 1;
|
||||
|
||||
if (subshell == 0)
|
||||
run_unwind_frame ("function_calling");
|
||||
|
||||
|
||||
+5578
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,984 @@
|
||||
/* rltty.c -- functions to prepare and restore the terminal for readline's
|
||||
use. */
|
||||
|
||||
/* Copyright (C) 1992-2005 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of the GNU Readline Library (Readline), a library
|
||||
for reading lines of text with interactive input and history editing.
|
||||
|
||||
Readline is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Readline 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 Readline. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#define READLINE_LIBRARY
|
||||
|
||||
#if defined (HAVE_CONFIG_H)
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <signal.h>
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#if defined (HAVE_UNISTD_H)
|
||||
# include <unistd.h>
|
||||
#endif /* HAVE_UNISTD_H */
|
||||
|
||||
#include "rldefs.h"
|
||||
|
||||
#if defined (GWINSZ_IN_SYS_IOCTL)
|
||||
# include <sys/ioctl.h>
|
||||
#endif /* GWINSZ_IN_SYS_IOCTL */
|
||||
|
||||
#include "rltty.h"
|
||||
#include "readline.h"
|
||||
#include "rlprivate.h"
|
||||
|
||||
#if !defined (errno)
|
||||
extern int errno;
|
||||
#endif /* !errno */
|
||||
|
||||
rl_vintfunc_t *rl_prep_term_function = rl_prep_terminal;
|
||||
rl_voidfunc_t *rl_deprep_term_function = rl_deprep_terminal;
|
||||
|
||||
static void set_winsize PARAMS((int));
|
||||
|
||||
/* **************************************************************** */
|
||||
/* */
|
||||
/* Saving and Restoring the TTY */
|
||||
/* */
|
||||
/* **************************************************************** */
|
||||
|
||||
/* Non-zero means that the terminal is in a prepped state. There are several
|
||||
flags that are OR'd in to denote whether or not we have sent various
|
||||
init strings to the terminal. */
|
||||
#define TPX_PREPPED 0x01
|
||||
#define TPX_BRACKPASTE 0x02
|
||||
#define TPX_METAKEY 0x04
|
||||
|
||||
static int terminal_prepped;
|
||||
|
||||
static _RL_TTY_CHARS _rl_tty_chars, _rl_last_tty_chars;
|
||||
|
||||
/* If non-zero, means that this process has called tcflow(fd, TCOOFF)
|
||||
and output is suspended. */
|
||||
#if defined (__ksr1__)
|
||||
static int ksrflow;
|
||||
#endif
|
||||
|
||||
/* Dummy call to force a backgrounded readline to stop before it tries
|
||||
to get the tty settings. */
|
||||
static void
|
||||
set_winsize (tty)
|
||||
int tty;
|
||||
{
|
||||
#if defined (TIOCGWINSZ)
|
||||
struct winsize w;
|
||||
|
||||
if (ioctl (tty, TIOCGWINSZ, &w) == 0)
|
||||
(void) ioctl (tty, TIOCSWINSZ, &w);
|
||||
#endif /* TIOCGWINSZ */
|
||||
}
|
||||
|
||||
#if defined (NO_TTY_DRIVER)
|
||||
/* Nothing */
|
||||
#elif defined (NEW_TTY_DRIVER)
|
||||
|
||||
/* Values for the `flags' field of a struct bsdtty. This tells which
|
||||
elements of the struct bsdtty have been fetched from the system and
|
||||
are valid. */
|
||||
#define SGTTY_SET 0x01
|
||||
#define LFLAG_SET 0x02
|
||||
#define TCHARS_SET 0x04
|
||||
#define LTCHARS_SET 0x08
|
||||
|
||||
struct bsdtty {
|
||||
struct sgttyb sgttyb; /* Basic BSD tty driver information. */
|
||||
int lflag; /* Local mode flags, like LPASS8. */
|
||||
#if defined (TIOCGETC)
|
||||
struct tchars tchars; /* Terminal special characters, including ^S and ^Q. */
|
||||
#endif
|
||||
#if defined (TIOCGLTC)
|
||||
struct ltchars ltchars; /* 4.2 BSD editing characters */
|
||||
#endif
|
||||
int flags; /* Bitmap saying which parts of the struct are valid. */
|
||||
};
|
||||
|
||||
#define TIOTYPE struct bsdtty
|
||||
|
||||
static TIOTYPE otio;
|
||||
|
||||
static void save_tty_chars PARAMS((TIOTYPE *));
|
||||
static int _get_tty_settings PARAMS((int, TIOTYPE *));
|
||||
static int get_tty_settings PARAMS((int, TIOTYPE *));
|
||||
static int _set_tty_settings PARAMS((int, TIOTYPE *));
|
||||
static int set_tty_settings PARAMS((int, TIOTYPE *));
|
||||
|
||||
static void prepare_terminal_settings PARAMS((int, TIOTYPE, TIOTYPE *));
|
||||
|
||||
static void set_special_char PARAMS((Keymap, TIOTYPE *, int, rl_command_func_t *));
|
||||
|
||||
static void
|
||||
save_tty_chars (tiop)
|
||||
TIOTYPE *tiop;
|
||||
{
|
||||
_rl_last_tty_chars = _rl_tty_chars;
|
||||
|
||||
if (tiop->flags & SGTTY_SET)
|
||||
{
|
||||
_rl_tty_chars.t_erase = tiop->sgttyb.sg_erase;
|
||||
_rl_tty_chars.t_kill = tiop->sgttyb.sg_kill;
|
||||
}
|
||||
|
||||
if (tiop->flags & TCHARS_SET)
|
||||
{
|
||||
_rl_intr_char = _rl_tty_chars.t_intr = tiop->tchars.t_intrc;
|
||||
_rl_quit_char = _rl_tty_chars.t_quit = tiop->tchars.t_quitc;
|
||||
|
||||
_rl_tty_chars.t_start = tiop->tchars.t_startc;
|
||||
_rl_tty_chars.t_stop = tiop->tchars.t_stopc;
|
||||
_rl_tty_chars.t_eof = tiop->tchars.t_eofc;
|
||||
_rl_tty_chars.t_eol = '\n';
|
||||
_rl_tty_chars.t_eol2 = tiop->tchars.t_brkc;
|
||||
}
|
||||
|
||||
if (tiop->flags & LTCHARS_SET)
|
||||
{
|
||||
_rl_susp_char = _rl_tty_chars.t_susp = tiop->ltchars.t_suspc;
|
||||
|
||||
_rl_tty_chars.t_dsusp = tiop->ltchars.t_dsuspc;
|
||||
_rl_tty_chars.t_reprint = tiop->ltchars.t_rprntc;
|
||||
_rl_tty_chars.t_flush = tiop->ltchars.t_flushc;
|
||||
_rl_tty_chars.t_werase = tiop->ltchars.t_werasc;
|
||||
_rl_tty_chars.t_lnext = tiop->ltchars.t_lnextc;
|
||||
}
|
||||
|
||||
_rl_tty_chars.t_status = -1;
|
||||
}
|
||||
|
||||
static int
|
||||
get_tty_settings (tty, tiop)
|
||||
int tty;
|
||||
TIOTYPE *tiop;
|
||||
{
|
||||
set_winsize (tty);
|
||||
|
||||
tiop->flags = tiop->lflag = 0;
|
||||
|
||||
errno = 0;
|
||||
if (ioctl (tty, TIOCGETP, &(tiop->sgttyb)) < 0)
|
||||
return -1;
|
||||
tiop->flags |= SGTTY_SET;
|
||||
|
||||
#if defined (TIOCLGET)
|
||||
if (ioctl (tty, TIOCLGET, &(tiop->lflag)) == 0)
|
||||
tiop->flags |= LFLAG_SET;
|
||||
#endif
|
||||
|
||||
#if defined (TIOCGETC)
|
||||
if (ioctl (tty, TIOCGETC, &(tiop->tchars)) == 0)
|
||||
tiop->flags |= TCHARS_SET;
|
||||
#endif
|
||||
|
||||
#if defined (TIOCGLTC)
|
||||
if (ioctl (tty, TIOCGLTC, &(tiop->ltchars)) == 0)
|
||||
tiop->flags |= LTCHARS_SET;
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
set_tty_settings (tty, tiop)
|
||||
int tty;
|
||||
TIOTYPE *tiop;
|
||||
{
|
||||
if (tiop->flags & SGTTY_SET)
|
||||
{
|
||||
ioctl (tty, TIOCSETN, &(tiop->sgttyb));
|
||||
tiop->flags &= ~SGTTY_SET;
|
||||
}
|
||||
_rl_echoing_p = 1;
|
||||
|
||||
#if defined (TIOCLSET)
|
||||
if (tiop->flags & LFLAG_SET)
|
||||
{
|
||||
ioctl (tty, TIOCLSET, &(tiop->lflag));
|
||||
tiop->flags &= ~LFLAG_SET;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined (TIOCSETC)
|
||||
if (tiop->flags & TCHARS_SET)
|
||||
{
|
||||
ioctl (tty, TIOCSETC, &(tiop->tchars));
|
||||
tiop->flags &= ~TCHARS_SET;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined (TIOCSLTC)
|
||||
if (tiop->flags & LTCHARS_SET)
|
||||
{
|
||||
ioctl (tty, TIOCSLTC, &(tiop->ltchars));
|
||||
tiop->flags &= ~LTCHARS_SET;
|
||||
}
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
prepare_terminal_settings (meta_flag, oldtio, tiop)
|
||||
int meta_flag;
|
||||
TIOTYPE oldtio, *tiop;
|
||||
{
|
||||
_rl_echoing_p = (oldtio.sgttyb.sg_flags & ECHO);
|
||||
_rl_echoctl = (oldtio.sgttyb.sg_flags & ECHOCTL);
|
||||
|
||||
/* Copy the original settings to the structure we're going to use for
|
||||
our settings. */
|
||||
tiop->sgttyb = oldtio.sgttyb;
|
||||
tiop->lflag = oldtio.lflag;
|
||||
#if defined (TIOCGETC)
|
||||
tiop->tchars = oldtio.tchars;
|
||||
#endif
|
||||
#if defined (TIOCGLTC)
|
||||
tiop->ltchars = oldtio.ltchars;
|
||||
#endif
|
||||
tiop->flags = oldtio.flags;
|
||||
|
||||
/* First, the basic settings to put us into character-at-a-time, no-echo
|
||||
input mode. */
|
||||
tiop->sgttyb.sg_flags &= ~(ECHO | CRMOD);
|
||||
tiop->sgttyb.sg_flags |= CBREAK;
|
||||
|
||||
/* If this terminal doesn't care how the 8th bit is used, then we can
|
||||
use it for the meta-key. If only one of even or odd parity is
|
||||
specified, then the terminal is using parity, and we cannot. */
|
||||
#if !defined (ANYP)
|
||||
# define ANYP (EVENP | ODDP)
|
||||
#endif
|
||||
if (((oldtio.sgttyb.sg_flags & ANYP) == ANYP) ||
|
||||
((oldtio.sgttyb.sg_flags & ANYP) == 0))
|
||||
{
|
||||
tiop->sgttyb.sg_flags |= ANYP;
|
||||
|
||||
/* Hack on local mode flags if we can. */
|
||||
#if defined (TIOCLGET)
|
||||
# if defined (LPASS8)
|
||||
tiop->lflag |= LPASS8;
|
||||
# endif /* LPASS8 */
|
||||
#endif /* TIOCLGET */
|
||||
}
|
||||
|
||||
#if defined (TIOCGETC)
|
||||
# if defined (USE_XON_XOFF)
|
||||
/* Get rid of terminal output start and stop characters. */
|
||||
tiop->tchars.t_stopc = -1; /* C-s */
|
||||
tiop->tchars.t_startc = -1; /* C-q */
|
||||
|
||||
/* If there is an XON character, bind it to restart the output. */
|
||||
if (oldtio.tchars.t_startc != -1)
|
||||
rl_bind_key (oldtio.tchars.t_startc, rl_restart_output);
|
||||
# endif /* USE_XON_XOFF */
|
||||
|
||||
/* If there is an EOF char, bind _rl_eof_char to it. */
|
||||
if (oldtio.tchars.t_eofc != -1)
|
||||
_rl_eof_char = oldtio.tchars.t_eofc;
|
||||
|
||||
# if defined (NO_KILL_INTR)
|
||||
/* Get rid of terminal-generated SIGQUIT and SIGINT. */
|
||||
tiop->tchars.t_quitc = -1; /* C-\ */
|
||||
tiop->tchars.t_intrc = -1; /* C-c */
|
||||
# endif /* NO_KILL_INTR */
|
||||
#endif /* TIOCGETC */
|
||||
|
||||
#if defined (TIOCGLTC)
|
||||
/* Make the interrupt keys go away. Just enough to make people happy. */
|
||||
tiop->ltchars.t_dsuspc = -1; /* C-y */
|
||||
tiop->ltchars.t_lnextc = -1; /* C-v */
|
||||
#endif /* TIOCGLTC */
|
||||
}
|
||||
|
||||
#else /* !defined (NEW_TTY_DRIVER) */
|
||||
|
||||
#if !defined (VMIN)
|
||||
# define VMIN VEOF
|
||||
#endif
|
||||
|
||||
#if !defined (VTIME)
|
||||
# define VTIME VEOL
|
||||
#endif
|
||||
|
||||
#if defined (TERMIOS_TTY_DRIVER)
|
||||
# define TIOTYPE struct termios
|
||||
# define DRAIN_OUTPUT(fd) tcdrain (fd)
|
||||
# define GETATTR(tty, tiop) (tcgetattr (tty, tiop))
|
||||
# ifdef M_UNIX
|
||||
# define SETATTR(tty, tiop) (tcsetattr (tty, TCSANOW, tiop))
|
||||
# else
|
||||
# define SETATTR(tty, tiop) (tcsetattr (tty, TCSADRAIN, tiop))
|
||||
# endif /* !M_UNIX */
|
||||
#else
|
||||
# define TIOTYPE struct termio
|
||||
# define DRAIN_OUTPUT(fd)
|
||||
# define GETATTR(tty, tiop) (ioctl (tty, TCGETA, tiop))
|
||||
# define SETATTR(tty, tiop) (ioctl (tty, TCSETAW, tiop))
|
||||
#endif /* !TERMIOS_TTY_DRIVER */
|
||||
|
||||
static TIOTYPE otio;
|
||||
|
||||
static void save_tty_chars PARAMS((TIOTYPE *));
|
||||
static int _get_tty_settings PARAMS((int, TIOTYPE *));
|
||||
static int get_tty_settings PARAMS((int, TIOTYPE *));
|
||||
static int _set_tty_settings PARAMS((int, TIOTYPE *));
|
||||
static int set_tty_settings PARAMS((int, TIOTYPE *));
|
||||
|
||||
static void prepare_terminal_settings PARAMS((int, TIOTYPE, TIOTYPE *));
|
||||
|
||||
static void set_special_char PARAMS((Keymap, TIOTYPE *, int, rl_command_func_t *));
|
||||
static void _rl_bind_tty_special_chars PARAMS((Keymap, TIOTYPE));
|
||||
|
||||
#if defined (FLUSHO)
|
||||
# define OUTPUT_BEING_FLUSHED(tp) (tp->c_lflag & FLUSHO)
|
||||
#else
|
||||
# define OUTPUT_BEING_FLUSHED(tp) 0
|
||||
#endif
|
||||
|
||||
static void
|
||||
save_tty_chars (tiop)
|
||||
TIOTYPE *tiop;
|
||||
{
|
||||
_rl_last_tty_chars = _rl_tty_chars;
|
||||
|
||||
_rl_tty_chars.t_eof = tiop->c_cc[VEOF];
|
||||
_rl_tty_chars.t_eol = tiop->c_cc[VEOL];
|
||||
#ifdef VEOL2
|
||||
_rl_tty_chars.t_eol2 = tiop->c_cc[VEOL2];
|
||||
#endif
|
||||
_rl_tty_chars.t_erase = tiop->c_cc[VERASE];
|
||||
#ifdef VWERASE
|
||||
_rl_tty_chars.t_werase = tiop->c_cc[VWERASE];
|
||||
#endif
|
||||
_rl_tty_chars.t_kill = tiop->c_cc[VKILL];
|
||||
#ifdef VREPRINT
|
||||
_rl_tty_chars.t_reprint = tiop->c_cc[VREPRINT];
|
||||
#endif
|
||||
_rl_intr_char = _rl_tty_chars.t_intr = tiop->c_cc[VINTR];
|
||||
_rl_quit_char = _rl_tty_chars.t_quit = tiop->c_cc[VQUIT];
|
||||
#ifdef VSUSP
|
||||
_rl_susp_char = _rl_tty_chars.t_susp = tiop->c_cc[VSUSP];
|
||||
#endif
|
||||
#ifdef VDSUSP
|
||||
_rl_tty_chars.t_dsusp = tiop->c_cc[VDSUSP];
|
||||
#endif
|
||||
#ifdef VSTART
|
||||
_rl_tty_chars.t_start = tiop->c_cc[VSTART];
|
||||
#endif
|
||||
#ifdef VSTOP
|
||||
_rl_tty_chars.t_stop = tiop->c_cc[VSTOP];
|
||||
#endif
|
||||
#ifdef VLNEXT
|
||||
_rl_tty_chars.t_lnext = tiop->c_cc[VLNEXT];
|
||||
#endif
|
||||
#ifdef VDISCARD
|
||||
_rl_tty_chars.t_flush = tiop->c_cc[VDISCARD];
|
||||
#endif
|
||||
#ifdef VSTATUS
|
||||
_rl_tty_chars.t_status = tiop->c_cc[VSTATUS];
|
||||
#endif
|
||||
}
|
||||
|
||||
#if defined (_AIX) || defined (_AIX41)
|
||||
/* Currently this is only used on AIX */
|
||||
static void
|
||||
rltty_warning (msg)
|
||||
char *msg;
|
||||
{
|
||||
_rl_errmsg ("warning: %s", msg);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined (_AIX)
|
||||
void
|
||||
setopost(tp)
|
||||
TIOTYPE *tp;
|
||||
{
|
||||
if ((tp->c_oflag & OPOST) == 0)
|
||||
{
|
||||
_rl_errmsg ("warning: turning on OPOST for terminal\r");
|
||||
tp->c_oflag |= OPOST|ONLCR;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
static int
|
||||
_get_tty_settings (tty, tiop)
|
||||
int tty;
|
||||
TIOTYPE *tiop;
|
||||
{
|
||||
int ioctl_ret;
|
||||
|
||||
while (1)
|
||||
{
|
||||
ioctl_ret = GETATTR (tty, tiop);
|
||||
if (ioctl_ret < 0)
|
||||
{
|
||||
if (errno != EINTR)
|
||||
return -1;
|
||||
else
|
||||
continue;
|
||||
}
|
||||
if (OUTPUT_BEING_FLUSHED (tiop))
|
||||
{
|
||||
#if defined (FLUSHO)
|
||||
_rl_errmsg ("warning: turning off output flushing");
|
||||
tiop->c_lflag &= ~FLUSHO;
|
||||
break;
|
||||
#else
|
||||
continue;
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
get_tty_settings (tty, tiop)
|
||||
int tty;
|
||||
TIOTYPE *tiop;
|
||||
{
|
||||
set_winsize (tty);
|
||||
|
||||
errno = 0;
|
||||
if (_get_tty_settings (tty, tiop) < 0)
|
||||
return -1;
|
||||
|
||||
#if defined (_AIX)
|
||||
setopost(tiop);
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
_set_tty_settings (tty, tiop)
|
||||
int tty;
|
||||
TIOTYPE *tiop;
|
||||
{
|
||||
while (SETATTR (tty, tiop) < 0)
|
||||
{
|
||||
if (errno != EINTR)
|
||||
return -1;
|
||||
errno = 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
set_tty_settings (tty, tiop)
|
||||
int tty;
|
||||
TIOTYPE *tiop;
|
||||
{
|
||||
if (_set_tty_settings (tty, tiop) < 0)
|
||||
return -1;
|
||||
|
||||
#if 0
|
||||
|
||||
#if defined (TERMIOS_TTY_DRIVER)
|
||||
# if defined (__ksr1__)
|
||||
if (ksrflow)
|
||||
{
|
||||
ksrflow = 0;
|
||||
tcflow (tty, TCOON);
|
||||
}
|
||||
# else /* !ksr1 */
|
||||
tcflow (tty, TCOON); /* Simulate a ^Q. */
|
||||
# endif /* !ksr1 */
|
||||
#else
|
||||
ioctl (tty, TCXONC, 1); /* Simulate a ^Q. */
|
||||
#endif /* !TERMIOS_TTY_DRIVER */
|
||||
|
||||
#endif /* 0 */
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
prepare_terminal_settings (meta_flag, oldtio, tiop)
|
||||
int meta_flag;
|
||||
TIOTYPE oldtio, *tiop;
|
||||
{
|
||||
_rl_echoing_p = (oldtio.c_lflag & ECHO);
|
||||
#if defined (ECHOCTL)
|
||||
_rl_echoctl = (oldtio.c_lflag & ECHOCTL);
|
||||
#endif
|
||||
|
||||
tiop->c_lflag &= ~(ICANON | ECHO);
|
||||
|
||||
if ((unsigned char) oldtio.c_cc[VEOF] != (unsigned char) _POSIX_VDISABLE)
|
||||
_rl_eof_char = oldtio.c_cc[VEOF];
|
||||
|
||||
#if defined (USE_XON_XOFF)
|
||||
#if defined (IXANY)
|
||||
tiop->c_iflag &= ~(IXON | IXANY);
|
||||
#else
|
||||
/* `strict' Posix systems do not define IXANY. */
|
||||
tiop->c_iflag &= ~IXON;
|
||||
#endif /* IXANY */
|
||||
#endif /* USE_XON_XOFF */
|
||||
|
||||
/* Only turn this off if we are using all 8 bits. */
|
||||
if (((tiop->c_cflag & CSIZE) == CS8) || meta_flag)
|
||||
tiop->c_iflag &= ~(ISTRIP | INPCK);
|
||||
|
||||
/* Make sure we differentiate between CR and NL on input. */
|
||||
tiop->c_iflag &= ~(ICRNL | INLCR);
|
||||
|
||||
#if !defined (HANDLE_SIGNALS)
|
||||
tiop->c_lflag &= ~ISIG;
|
||||
#else
|
||||
tiop->c_lflag |= ISIG;
|
||||
#endif
|
||||
|
||||
tiop->c_cc[VMIN] = 1;
|
||||
tiop->c_cc[VTIME] = 0;
|
||||
|
||||
#if defined (FLUSHO)
|
||||
if (OUTPUT_BEING_FLUSHED (tiop))
|
||||
{
|
||||
tiop->c_lflag &= ~FLUSHO;
|
||||
oldtio.c_lflag &= ~FLUSHO;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Turn off characters that we need on Posix systems with job control,
|
||||
just to be sure. This includes ^Y and ^V. This should not really
|
||||
be necessary. */
|
||||
#if defined (TERMIOS_TTY_DRIVER) && defined (_POSIX_VDISABLE)
|
||||
|
||||
#if defined (VLNEXT)
|
||||
tiop->c_cc[VLNEXT] = _POSIX_VDISABLE;
|
||||
#endif
|
||||
|
||||
#if defined (VDSUSP)
|
||||
tiop->c_cc[VDSUSP] = _POSIX_VDISABLE;
|
||||
#endif
|
||||
|
||||
#endif /* TERMIOS_TTY_DRIVER && _POSIX_VDISABLE */
|
||||
}
|
||||
#endif /* !NEW_TTY_DRIVER */
|
||||
|
||||
/* Put the terminal in CBREAK mode so that we can detect key presses. */
|
||||
#if defined (NO_TTY_DRIVER)
|
||||
void
|
||||
rl_prep_terminal (meta_flag)
|
||||
int meta_flag;
|
||||
{
|
||||
_rl_echoing_p = 1;
|
||||
}
|
||||
|
||||
void
|
||||
rl_deprep_terminal ()
|
||||
{
|
||||
}
|
||||
|
||||
#else /* ! NO_TTY_DRIVER */
|
||||
void
|
||||
rl_prep_terminal (meta_flag)
|
||||
int meta_flag;
|
||||
{
|
||||
int tty, nprep;
|
||||
TIOTYPE tio;
|
||||
|
||||
if (terminal_prepped)
|
||||
return;
|
||||
|
||||
/* Try to keep this function from being INTerrupted. */
|
||||
_rl_block_sigint ();
|
||||
|
||||
tty = rl_instream ? fileno (rl_instream) : fileno (stdin);
|
||||
|
||||
if (get_tty_settings (tty, &tio) < 0)
|
||||
{
|
||||
#if defined (ENOTSUP)
|
||||
/* MacOS X and Linux, at least, lie about the value of errno if
|
||||
tcgetattr fails. */
|
||||
if (errno == ENOTTY || errno == EINVAL || errno == ENOTSUP)
|
||||
#else
|
||||
if (errno == ENOTTY || errno == EINVAL)
|
||||
#endif
|
||||
_rl_echoing_p = 1; /* XXX */
|
||||
|
||||
_rl_release_sigint ();
|
||||
return;
|
||||
}
|
||||
|
||||
otio = tio;
|
||||
|
||||
if (_rl_bind_stty_chars)
|
||||
{
|
||||
#if defined (VI_MODE)
|
||||
/* If editing in vi mode, make sure we restore the bindings in the
|
||||
insertion keymap no matter what keymap we ended up in. */
|
||||
if (rl_editing_mode == vi_mode)
|
||||
rl_tty_unset_default_bindings (vi_insertion_keymap);
|
||||
else
|
||||
#endif
|
||||
rl_tty_unset_default_bindings (_rl_keymap);
|
||||
}
|
||||
save_tty_chars (&otio);
|
||||
RL_SETSTATE(RL_STATE_TTYCSAVED);
|
||||
if (_rl_bind_stty_chars)
|
||||
{
|
||||
#if defined (VI_MODE)
|
||||
/* If editing in vi mode, make sure we set the bindings in the
|
||||
insertion keymap no matter what keymap we ended up in. */
|
||||
if (rl_editing_mode == vi_mode)
|
||||
_rl_bind_tty_special_chars (vi_insertion_keymap, tio);
|
||||
else
|
||||
#endif
|
||||
_rl_bind_tty_special_chars (_rl_keymap, tio);
|
||||
}
|
||||
|
||||
prepare_terminal_settings (meta_flag, otio, &tio);
|
||||
|
||||
if (set_tty_settings (tty, &tio) < 0)
|
||||
{
|
||||
_rl_release_sigint ();
|
||||
return;
|
||||
}
|
||||
|
||||
if (_rl_enable_keypad)
|
||||
_rl_control_keypad (1);
|
||||
|
||||
nprep = TPX_PREPPED;
|
||||
|
||||
if (_rl_enab
|
||||
fflush (rl_outstream);
|
||||
terminal_prepped = nprep;
|
||||
RL_SETSTATE(RL_STATE_TERMPREPPED);
|
||||
|
||||
_rl_release_sigint ();
|
||||
}
|
||||
|
||||
/* Restore the terminal's normal settings and modes. */
|
||||
void
|
||||
rl_deprep_terminal ()
|
||||
{
|
||||
int tty;
|
||||
|
||||
if (!terminal_prepped)
|
||||
return;
|
||||
|
||||
/* Try to keep this function from being interrupted. */
|
||||
_rl_block_sigint ();
|
||||
|
||||
tty = rl_instream ? fileno (rl_instream) : fileno (stdin);
|
||||
|
||||
if (_rl_enable_keypad)
|
||||
_rl_control_keypad (0);
|
||||
|
||||
fflush (rl_outstream);
|
||||
|
||||
if (set_tty_settings (tty, &otio) < 0)
|
||||
{
|
||||
_rl_release_sigint ();
|
||||
return;
|
||||
}
|
||||
|
||||
terminal_prepped = 0;
|
||||
RL_UNSETSTATE(RL_STATE_TERMPREPPED);
|
||||
|
||||
_rl_release_sigint ();
|
||||
}
|
||||
#endif /* !NO_TTY_DRIVER */
|
||||
|
||||
/* **************************************************************** */
|
||||
/* */
|
||||
/* Bogus Flow Control */
|
||||
/* */
|
||||
/* **************************************************************** */
|
||||
|
||||
int
|
||||
rl_restart_output (count, key)
|
||||
int count, key;
|
||||
{
|
||||
#if defined (__MINGW32__)
|
||||
return 0;
|
||||
#else /* !__MING32__ */
|
||||
|
||||
int fildes = fileno (rl_outstream);
|
||||
#if defined (TIOCSTART)
|
||||
#if defined (apollo)
|
||||
ioctl (&fildes, TIOCSTART, 0);
|
||||
#else
|
||||
ioctl (fildes, TIOCSTART, 0);
|
||||
#endif /* apollo */
|
||||
|
||||
#else /* !TIOCSTART */
|
||||
# if defined (TERMIOS_TTY_DRIVER)
|
||||
# if defined (__ksr1__)
|
||||
if (ksrflow)
|
||||
{
|
||||
ksrflow = 0;
|
||||
tcflow (fildes, TCOON);
|
||||
}
|
||||
# else /* !ksr1 */
|
||||
tcflow (fildes, TCOON); /* Simulate a ^Q. */
|
||||
# endif /* !ksr1 */
|
||||
# else /* !TERMIOS_TTY_DRIVER */
|
||||
# if defined (TCXONC)
|
||||
ioctl (fildes, TCXONC, TCOON);
|
||||
# endif /* TCXONC */
|
||||
# endif /* !TERMIOS_TTY_DRIVER */
|
||||
#endif /* !TIOCSTART */
|
||||
|
||||
return 0;
|
||||
#endif /* !__MINGW32__ */
|
||||
}
|
||||
|
||||
int
|
||||
rl_stop_output (count, key)
|
||||
int count, key;
|
||||
{
|
||||
#if defined (__MINGW32__)
|
||||
return 0;
|
||||
#else
|
||||
|
||||
int fildes = fileno (rl_instream);
|
||||
|
||||
#if defined (TIOCSTOP)
|
||||
# if defined (apollo)
|
||||
ioctl (&fildes, TIOCSTOP, 0);
|
||||
# else
|
||||
ioctl (fildes, TIOCSTOP, 0);
|
||||
# endif /* apollo */
|
||||
#else /* !TIOCSTOP */
|
||||
# if defined (TERMIOS_TTY_DRIVER)
|
||||
# if defined (__ksr1__)
|
||||
ksrflow = 1;
|
||||
# endif /* ksr1 */
|
||||
tcflow (fildes, TCOOFF);
|
||||
# else
|
||||
# if defined (TCXONC)
|
||||
ioctl (fildes, TCXONC, TCOON);
|
||||
# endif /* TCXONC */
|
||||
# endif /* !TERMIOS_TTY_DRIVER */
|
||||
#endif /* !TIOCSTOP */
|
||||
|
||||
return 0;
|
||||
#endif /* !__MINGW32__ */
|
||||
}
|
||||
|
||||
/* **************************************************************** */
|
||||
/* */
|
||||
/* Default Key Bindings */
|
||||
/* */
|
||||
/* **************************************************************** */
|
||||
|
||||
#if !defined (NO_TTY_DRIVER)
|
||||
#define SET_SPECIAL(sc, func) set_special_char(kmap, &ttybuff, sc, func)
|
||||
#endif
|
||||
|
||||
#if defined (NO_TTY_DRIVER)
|
||||
|
||||
#define SET_SPECIAL(sc, func)
|
||||
#define RESET_SPECIAL(c)
|
||||
|
||||
#elif defined (NEW_TTY_DRIVER)
|
||||
static void
|
||||
set_special_char (kmap, tiop, sc, func)
|
||||
Keymap kmap;
|
||||
TIOTYPE *tiop;
|
||||
int sc;
|
||||
rl_command_func_t *func;
|
||||
{
|
||||
if (sc != -1 && kmap[(unsigned char)sc].type == ISFUNC)
|
||||
kmap[(unsigned char)sc].function = func;
|
||||
}
|
||||
|
||||
#define RESET_SPECIAL(c) \
|
||||
if (c != -1 && kmap[(unsigned char)c].type == ISFUNC) \
|
||||
kmap[(unsigned char)c].function = rl_insert;
|
||||
|
||||
static void
|
||||
_rl_bind_tty_special_chars (kmap, ttybuff)
|
||||
Keymap kmap;
|
||||
TIOTYPE ttybuff;
|
||||
{
|
||||
if (ttybuff.flags & SGTTY_SET)
|
||||
{
|
||||
SET_SPECIAL (ttybuff.sgttyb.sg_erase, rl_rubout);
|
||||
SET_SPECIAL (ttybuff.sgttyb.sg_kill, rl_unix_line_discard);
|
||||
}
|
||||
|
||||
# if defined (TIOCGLTC)
|
||||
if (ttybuff.flags & LTCHARS_SET)
|
||||
{
|
||||
SET_SPECIAL (ttybuff.ltchars.t_werasc, rl_unix_word_rubout);
|
||||
SET_SPECIAL (ttybuff.ltchars.t_lnextc, rl_quoted_insert);
|
||||
}
|
||||
# endif /* TIOCGLTC */
|
||||
}
|
||||
|
||||
#else /* !NEW_TTY_DRIVER */
|
||||
static void
|
||||
set_special_char (kmap, tiop, sc, func)
|
||||
Keymap kmap;
|
||||
TIOTYPE *tiop;
|
||||
int sc;
|
||||
rl_command_func_t *func;
|
||||
{
|
||||
unsigned char uc;
|
||||
|
||||
uc = tiop->c_cc[sc];
|
||||
if (uc != (unsigned char)_POSIX_VDISABLE && kmap[uc].type == ISFUNC)
|
||||
kmap[uc].function = func;
|
||||
}
|
||||
|
||||
/* used later */
|
||||
#define RESET_SPECIAL(uc) \
|
||||
if (uc != (unsigned char)_POSIX_VDISABLE && kmap[uc].type == ISFUNC) \
|
||||
kmap[uc].function = rl_insert;
|
||||
|
||||
static void
|
||||
_rl_bind_tty_special_chars (kmap, ttybuff)
|
||||
Keymap kmap;
|
||||
TIOTYPE ttybuff;
|
||||
{
|
||||
SET_SPECIAL (VERASE, rl_rubout);
|
||||
SET_SPECIAL (VKILL, rl_unix_line_discard);
|
||||
|
||||
# if defined (VLNEXT) && defined (TERMIOS_TTY_DRIVER)
|
||||
SET_SPECIAL (VLNEXT, rl_quoted_insert);
|
||||
# endif /* VLNEXT && TERMIOS_TTY_DRIVER */
|
||||
|
||||
# if defined (VWERASE) && defined (TERMIOS_TTY_DRIVER)
|
||||
SET_SPECIAL (VWERASE, rl_unix_word_rubout);
|
||||
# endif /* VWERASE && TERMIOS_TTY_DRIVER */
|
||||
}
|
||||
|
||||
#endif /* !NEW_TTY_DRIVER */
|
||||
|
||||
/* Set the system's default editing characters to their readline equivalents
|
||||
in KMAP. Should be static, now that we have rl_tty_set_default_bindings. */
|
||||
void
|
||||
rltty_set_default_bindings (kmap)
|
||||
Keymap kmap;
|
||||
{
|
||||
#if !defined (NO_TTY_DRIVER)
|
||||
TIOTYPE ttybuff;
|
||||
int tty;
|
||||
|
||||
tty = fileno (rl_instream);
|
||||
|
||||
if (get_tty_settings (tty, &ttybuff) == 0)
|
||||
_rl_bind_tty_special_chars (kmap, ttybuff);
|
||||
#endif
|
||||
}
|
||||
|
||||
/* New public way to set the system default editing chars to their readline
|
||||
equivalents. */
|
||||
void
|
||||
rl_tty_set_default_bindings (kmap)
|
||||
Keymap kmap;
|
||||
{
|
||||
rltty_set_default_bindings (kmap);
|
||||
}
|
||||
|
||||
/* Rebind all of the tty special chars that readline worries about back
|
||||
to self-insert. Call this before saving the current terminal special
|
||||
chars with save_tty_chars(). This only works on POSIX termios or termio
|
||||
systems. */
|
||||
void
|
||||
rl_tty_unset_default_bindings (kmap)
|
||||
Keymap kmap;
|
||||
{
|
||||
/* Don't bother before we've saved the tty special chars at least once. */
|
||||
if (RL_ISSTATE(RL_STATE_TTYCSAVED) == 0)
|
||||
return;
|
||||
|
||||
RESET_SPECIAL (_rl_tty_chars.t_erase);
|
||||
RESET_SPECIAL (_rl_tty_chars.t_kill);
|
||||
|
||||
# if defined (VLNEXT) && defined (TERMIOS_TTY_DRIVER)
|
||||
RESET_SPECIAL (_rl_tty_chars.t_lnext);
|
||||
# endif /* VLNEXT && TERMIOS_TTY_DRIVER */
|
||||
|
||||
# if defined (VWERASE) && defined (TERMIOS_TTY_DRIVER)
|
||||
RESET_SPECIAL (_rl_tty_chars.t_werase);
|
||||
# endif /* VWERASE && TERMIOS_TTY_DRIVER */
|
||||
}
|
||||
|
||||
#if defined (HANDLE_SIGNALS)
|
||||
|
||||
#if defined (NEW_TTY_DRIVER) || defined (NO_TTY_DRIVER)
|
||||
int
|
||||
_rl_disable_tty_signals ()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
_rl_restore_tty_signals ()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
|
||||
static TIOTYPE sigstty, nosigstty;
|
||||
static int tty_sigs_disabled = 0;
|
||||
|
||||
int
|
||||
_rl_disable_tty_signals ()
|
||||
{
|
||||
if (tty_sigs_disabled)
|
||||
return 0;
|
||||
|
||||
if (_get_tty_settings (fileno (rl_instream), &sigstty) < 0)
|
||||
return -1;
|
||||
|
||||
nosigstty = sigstty;
|
||||
|
||||
nosigstty.c_lflag &= ~ISIG;
|
||||
nosigstty.c_iflag &= ~IXON;
|
||||
|
||||
if (_set_tty_settings (fileno (rl_instream), &nosigstty) < 0)
|
||||
return (_set_tty_settings (fileno (rl_instream), &sigstty));
|
||||
|
||||
tty_sigs_disabled = 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
_rl_restore_tty_signals ()
|
||||
{
|
||||
int r;
|
||||
|
||||
if (tty_sigs_disabled == 0)
|
||||
return 0;
|
||||
|
||||
r = _set_tty_settings (fileno (rl_instream), &sigstty);
|
||||
|
||||
if (r == 0)
|
||||
tty_sigs_disabled = 0;
|
||||
|
||||
return r;
|
||||
}
|
||||
#endif /* !NEW_TTY_DRIVER */
|
||||
|
||||
#endif /* HANDLE_SIGNALS */
|
||||
@@ -1486,6 +1486,7 @@ static const struct {
|
||||
{ "convert-meta", &_rl_convert_meta_chars_to_ascii, 0 },
|
||||
{ "disable-completion", &rl_inhibit_completion, 0 },
|
||||
{ "echo-control-characters", &_rl_echo_control_chars, 0 },
|
||||
{ "enable-bracketed-paste", &_rl_enable_bracketed_paste, 0 },
|
||||
{ "enable-keypad", &_rl_enable_keypad, 0 },
|
||||
{ "enable-meta-key", &_rl_enable_meta, 0 },
|
||||
{ "expand-tilde", &rl_complete_with_tilde_expansion, 0 },
|
||||
|
||||
@@ -430,6 +430,13 @@ When set to \fBOn\fP, on operating systems that indicate they support it,
|
||||
readline echoes a character corresponding to a signal generated from the
|
||||
keyboard.
|
||||
.TP
|
||||
.B enable\-bracketed\-paste (Off)
|
||||
When set to \fBOn\fP, readline will configure the terminal in a way
|
||||
that will enable it to insert each paste into the editing buffer as a
|
||||
single string of characters, instead of treating each character as if
|
||||
it had been read from the keyboard. This can prevent pasted characters
|
||||
from being interpreted as editing commands.
|
||||
.TP
|
||||
.B enable\-keypad (Off)
|
||||
When set to \fBOn\fP, readline will try to enable the application
|
||||
keypad when it is called. Some systems need this to enable the
|
||||
|
||||
@@ -511,6 +511,14 @@ When set to @samp{on}, on operating systems that indicate they support it,
|
||||
readline echoes a character corresponding to a signal generated from the
|
||||
keyboard. The default is @samp{on}.
|
||||
|
||||
@item enable-bracketed-paste
|
||||
@vindex enable-bracketed-paste
|
||||
When set to @samp{On}, Readline will configure the terminal in a way
|
||||
that will enable it to insert each paste into the editing buffer as a
|
||||
single string of characters, instead of treating each character as if
|
||||
it had been read from the keyboard. This can prevent pasted characters
|
||||
from being interpreted as editing commands. The default is @samp{off}.
|
||||
|
||||
@item enable-keypad
|
||||
@vindex enable-keypad
|
||||
When set to @samp{on}, Readline will try to enable the application
|
||||
@@ -1232,6 +1240,14 @@ Insert a tab character.
|
||||
@item self-insert (a, b, A, 1, !, @dots{})
|
||||
Insert yourself.
|
||||
|
||||
@item bracketed-paste-begin ()
|
||||
This function is intended to be bound to the "bracketed paste" escape
|
||||
sequence sent by some terminals, and such a binding is assigned by default.
|
||||
It allows Readline to insert the pasted text as a single unit without treating
|
||||
each character as if it had been read from the keyboard. The characters
|
||||
are inserted as if each one was bound to @code{self-insert}) instead of
|
||||
executing any editing commands.
|
||||
|
||||
@item transpose-chars (C-t)
|
||||
Drag the character before the cursor forward over
|
||||
the character at the cursor, moving the
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -68,6 +68,7 @@ static const FUNMAP default_funmap[] = {
|
||||
{ "backward-word", rl_backward_word },
|
||||
{ "beginning-of-history", rl_beginning_of_history },
|
||||
{ "beginning-of-line", rl_beg_of_line },
|
||||
{ "bracketed-paste-begin", rl_bracketed_paste_begin },
|
||||
{ "call-last-kbd-macro", rl_call_last_kbd_macro },
|
||||
{ "capitalize-word", rl_capitalize_word },
|
||||
{ "character-search", rl_char_search },
|
||||
|
||||
@@ -656,6 +656,56 @@ rl_yank_last_arg (count, key)
|
||||
return retval;
|
||||
}
|
||||
|
||||
/* Having read the special escape sequence denoting the beginning of a
|
||||
`bracketed paste' sequence, read the rest of the pasted input until the
|
||||
closing sequence and insert the pasted text as a single unit without
|
||||
interpretation. */
|
||||
int
|
||||
rl_bracketed_paste_begin (count, key)
|
||||
int count, key;
|
||||
{
|
||||
int retval, c;
|
||||
size_t len, cap;
|
||||
char *buf;
|
||||
|
||||
retval = 1;
|
||||
len = 0;
|
||||
buf = xmalloc (cap = 64);
|
||||
|
||||
RL_SETSTATE (RL_STATE_MOREINPUT);
|
||||
while ((c = rl_read_key ()) >= 0)
|
||||
{
|
||||
if (RL_ISSTATE (RL_STATE_MACRODEF))
|
||||
_rl_add_macro_char (c);
|
||||
|
||||
if (c == '\r') /* XXX */
|
||||
c = '\n';
|
||||
|
||||
if (len == cap)
|
||||
buf = xrealloc (buf, cap *= 2);
|
||||
|
||||
buf[len++] = c;
|
||||
if (len >= BRACK_PASTE_SLEN && c == BRACK_PASTE_LAST &&
|
||||
STREQN (buf + len - BRACK_PASTE_SLEN, BRACK_PASTE_SUFF, BRACK_PASTE_SLEN))
|
||||
{
|
||||
len -= BRACK_PASTE_SLEN;
|
||||
break;
|
||||
}
|
||||
}
|
||||
RL_UNSETSTATE (RL_STATE_MOREINPUT);
|
||||
|
||||
if (c >= 0)
|
||||
{
|
||||
if (len == cap)
|
||||
buf = xrealloc (buf, cap + 1);
|
||||
buf[len] = '\0';
|
||||
retval = rl_insert_text (buf);
|
||||
}
|
||||
|
||||
xfree (buf);
|
||||
return (retval);
|
||||
}
|
||||
|
||||
/* A special paste command for users of Cygnus's cygwin32. */
|
||||
#if defined (__CYGWIN__)
|
||||
#include <windows.h>
|
||||
|
||||
@@ -94,6 +94,8 @@ static void readline_initialize_everything PARAMS((void));
|
||||
static void bind_arrow_keys_internal PARAMS((Keymap));
|
||||
static void bind_arrow_keys PARAMS((void));
|
||||
|
||||
static void bind_bracketed_paste_prefix PARAMS((void));
|
||||
|
||||
static void readline_default_bindings PARAMS((void));
|
||||
static void reset_default_bindings PARAMS((void));
|
||||
|
||||
@@ -306,6 +308,11 @@ int _rl_echo_control_chars = 1;
|
||||
the editing mode: @ for emacs, : for vi-command, + for vi-insert. */
|
||||
int _rl_show_mode_in_prompt = 0;
|
||||
|
||||
/* Non-zero means to attempt to put the terminal in `bracketed paste mode',
|
||||
where it will prefix pasted text with an escape sequence and send
|
||||
another to mark the end of the paste. */
|
||||
int _rl_enable_bracketed_paste = 0;
|
||||
|
||||
/* **************************************************************** */
|
||||
/* */
|
||||
/* Top Level Functions */
|
||||
@@ -1179,6 +1186,10 @@ readline_initialize_everything ()
|
||||
/* Try to bind a common arrow key prefix, if not already bound. */
|
||||
bind_arrow_keys ();
|
||||
|
||||
/* Bind the bracketed paste prefix assuming that the user will enable
|
||||
it on terminals that support it. */
|
||||
bind_bracketed_paste_prefix ();
|
||||
|
||||
/* If the completion parser's default word break characters haven't
|
||||
been set yet, then do so now. */
|
||||
if (rl_completer_word_break_characters == (char *)NULL)
|
||||
@@ -1289,6 +1300,22 @@ bind_arrow_keys ()
|
||||
#endif
|
||||
}
|
||||
|
||||
static void
|
||||
bind_bracketed_paste_prefix ()
|
||||
{
|
||||
Keymap xkeymap;
|
||||
|
||||
xkeymap = _rl_keymap;
|
||||
|
||||
_rl_keymap = emacs_standard_keymap;
|
||||
rl_bind_keyseq_if_unbound (BRACK_PASTE_PREF, rl_bracketed_paste_begin);
|
||||
|
||||
_rl_keymap = vi_insertion_keymap;
|
||||
rl_bind_keyseq_if_unbound (BRACK_PASTE_PREF, rl_bracketed_paste_begin);
|
||||
|
||||
_rl_keymap = xkeymap;
|
||||
}
|
||||
|
||||
/* **************************************************************** */
|
||||
/* */
|
||||
/* Saving and Restoring Readline's state */
|
||||
|
||||
@@ -172,6 +172,7 @@ extern int rl_yank PARAMS((int, int));
|
||||
extern int rl_yank_pop PARAMS((int, int));
|
||||
extern int rl_yank_nth_arg PARAMS((int, int));
|
||||
extern int rl_yank_last_arg PARAMS((int, int));
|
||||
extern int rl_bracketed_paste_begin PARAMS((int, int));
|
||||
/* Not available unless __CYGWIN__ is defined. */
|
||||
#ifdef __CYGWIN__
|
||||
extern int rl_paste_from_clipboard PARAMS((int, int));
|
||||
|
||||
@@ -293,6 +293,16 @@ extern int _rl_isearch_callback PARAMS((_rl_search_cxt *));
|
||||
|
||||
extern int _rl_search_getchar PARAMS((_rl_search_cxt *));
|
||||
|
||||
/* kill.c */
|
||||
#define BRACK_PASTE_PREF "\033[200~"
|
||||
#define BRACK_PASTE_SUFF "\033[201~"
|
||||
|
||||
#define BRACK_PASTE_LAST '~'
|
||||
#define BRACK_PASTE_SLEN 6
|
||||
|
||||
#define BRACK_PASTE_INIT "\033[?2004h"
|
||||
#define BRACK_PASTE_FINI "\033[?2004l"
|
||||
|
||||
/* macro.c */
|
||||
extern void _rl_with_macro_input PARAMS((char *));
|
||||
extern int _rl_next_macro_key PARAMS((void));
|
||||
@@ -476,6 +486,7 @@ extern int _rl_bind_stty_chars;
|
||||
extern int _rl_revert_all_at_newline;
|
||||
extern int _rl_echo_control_chars;
|
||||
extern int _rl_show_mode_in_prompt;
|
||||
extern int _rl_enable_bracketed_paste;
|
||||
extern char *_rl_comment_begin;
|
||||
extern unsigned char _rl_parsing_conditionalized_out;
|
||||
extern Keymap _rl_keymap;
|
||||
|
||||
+23
-6
@@ -4,7 +4,7 @@
|
||||
/* Copyright (C) 1992-2005 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of the GNU Readline Library (Readline), a library
|
||||
for reading lines of text with interactive input and history editing.
|
||||
for reading lines of text with interactive input and history editing.
|
||||
|
||||
Readline is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@@ -60,7 +60,13 @@ static void set_winsize PARAMS((int));
|
||||
/* */
|
||||
/* **************************************************************** */
|
||||
|
||||
/* Non-zero means that the terminal is in a prepped state. */
|
||||
/* Non-zero means that the terminal is in a prepped state. There are several
|
||||
flags that are OR'd in to denote whether or not we have sent various
|
||||
init strings to the terminal. */
|
||||
#define TPX_PREPPED 0x01
|
||||
#define TPX_BRACKPASTE 0x02
|
||||
#define TPX_METAKEY 0x04
|
||||
|
||||
static int terminal_prepped;
|
||||
|
||||
static _RL_TTY_CHARS _rl_tty_chars, _rl_last_tty_chars;
|
||||
@@ -595,7 +601,7 @@ void
|
||||
rl_prep_terminal (meta_flag)
|
||||
int meta_flag;
|
||||
{
|
||||
int tty;
|
||||
int tty, nprep;
|
||||
TIOTYPE tio;
|
||||
|
||||
if (terminal_prepped)
|
||||
@@ -642,7 +648,7 @@ rl_prep_terminal (meta_flag)
|
||||
/* If editing in vi mode, make sure we set the bindings in the
|
||||
insertion keymap no matter what keymap we ended up in. */
|
||||
if (rl_editing_mode == vi_mode)
|
||||
_rl_bind_tty_special_chars (vi_insertion_keymap, tio);
|
||||
_rl_bind_tty_special_chars (vi_insertion_keymap, tio);
|
||||
else
|
||||
#endif
|
||||
_rl_bind_tty_special_chars (_rl_keymap, tio);
|
||||
@@ -659,8 +665,16 @@ rl_prep_terminal (meta_flag)
|
||||
if (_rl_enable_keypad)
|
||||
_rl_control_keypad (1);
|
||||
|
||||
nprep = TPX_PREPPED;
|
||||
|
||||
if (_rl_enable_bracketed_paste)
|
||||
{
|
||||
fprintf (rl_outstream, BRACK_PASTE_INIT);
|
||||
nprep |= TPX_BRACKPASTE;
|
||||
}
|
||||
|
||||
fflush (rl_outstream);
|
||||
terminal_prepped = 1;
|
||||
terminal_prepped = nprep;
|
||||
RL_SETSTATE(RL_STATE_TERMPREPPED);
|
||||
|
||||
_rl_release_sigint ();
|
||||
@@ -672,7 +686,7 @@ rl_deprep_terminal ()
|
||||
{
|
||||
int tty;
|
||||
|
||||
if (!terminal_prepped)
|
||||
if (terminal_prepped == 0)
|
||||
return;
|
||||
|
||||
/* Try to keep this function from being interrupted. */
|
||||
@@ -680,6 +694,9 @@ rl_deprep_terminal ()
|
||||
|
||||
tty = rl_instream ? fileno (rl_instream) : fileno (stdin);
|
||||
|
||||
if (terminal_prepped & TPX_BRACKPASTE)
|
||||
fprintf (rl_outstream, BRACK_PASTE_FINI);
|
||||
|
||||
if (_rl_enable_keypad)
|
||||
_rl_control_keypad (0);
|
||||
|
||||
|
||||
@@ -1224,6 +1224,8 @@ pipeline_command: pipeline
|
||||
/* XXX - let's cheat and push a newline back */
|
||||
if ($2 == '\n')
|
||||
token_to_read = '\n';
|
||||
else if ($2 == ';')
|
||||
token_to_read = ';';
|
||||
}
|
||||
| BANG list_terminator
|
||||
{
|
||||
@@ -1242,6 +1244,8 @@ pipeline_command: pipeline
|
||||
/* XXX - let's cheat and push a newline back */
|
||||
if ($2 == '\n')
|
||||
token_to_read = '\n';
|
||||
if ($2 == ';')
|
||||
token_to_read = ';';
|
||||
}
|
||||
;
|
||||
|
||||
|
||||
@@ -411,3 +411,24 @@ one
|
||||
two
|
||||
two
|
||||
./array17.sub: line 76: ~ : syntax error: operand expected (error token is "~ ")
|
||||
1
|
||||
argv[1] = <>
|
||||
argv[2] = <>
|
||||
argv[3] = <>
|
||||
argv[1] = <bar>
|
||||
argv[1] = <-->
|
||||
argv[1] = <>
|
||||
argv[1] = <qux>
|
||||
argv[1] = <->
|
||||
argv[2] = <->
|
||||
argv[1] = < >
|
||||
argv[1] = <>
|
||||
argv[2] = <>
|
||||
argv[3] = <>
|
||||
argv[1] = <bar>
|
||||
argv[1] = <-->
|
||||
argv[1] = <>
|
||||
argv[1] = <qux>
|
||||
argv[1] = <->
|
||||
argv[2] = <->
|
||||
argv[1] = < >
|
||||
|
||||
@@ -402,3 +402,5 @@ ${THIS_SH} ./array15.sub
|
||||
${THIS_SH} ./array16.sub
|
||||
|
||||
${THIS_SH} ./array17.sub
|
||||
|
||||
${THIS_SH} ./array18.sub
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
# arrays referenced using @ subscript and positional parameters should behave
|
||||
# the same way
|
||||
|
||||
foo=(0 0 0); [[ -z ${foo[@]#0} ]]; echo $?
|
||||
|
||||
recho "${foo[@]#0}"
|
||||
bar=${foo[@]#0}
|
||||
recho bar
|
||||
recho $bar
|
||||
recho -$bar-
|
||||
recho "$bar"
|
||||
|
||||
qux="${foo[@]#0}"
|
||||
recho qux
|
||||
recho $qux
|
||||
recho -$qux-
|
||||
recho "$qux"
|
||||
|
||||
unset foo qux bar
|
||||
|
||||
set -- 0 0 0
|
||||
|
||||
recho "${@#0}"
|
||||
bar=${@#0}
|
||||
recho bar
|
||||
recho $bar
|
||||
recho -$bar-
|
||||
recho "$bar"
|
||||
|
||||
qux="${@#0}"
|
||||
recho qux
|
||||
recho $qux
|
||||
recho -$qux-
|
||||
recho "$qux"
|
||||
@@ -216,6 +216,7 @@ ${THIS_SH} ./dollar-at-star1.sub
|
||||
${THIS_SH} ./dollar-at-star2.sub
|
||||
${THIS_SH} ./dollar-at-star3.sub
|
||||
${THIS_SH} ./dollar-at-star4.sub
|
||||
${THIS_SH} ./dollar-at-star5.sub
|
||||
|
||||
# tests for special expansion of "$*" and "${array[*]}" when used with other
|
||||
# expansions -- bugs through bash-2.05b
|
||||
|
||||
@@ -3,9 +3,35 @@ unset f ; f=abcd
|
||||
first_char=${f[@]:0:1}
|
||||
recho $first_char
|
||||
|
||||
first_char=${f[0]:0:1}
|
||||
recho $first_char
|
||||
|
||||
first_char=${f:0:1}
|
||||
recho $first_char
|
||||
|
||||
first_char="${f[@]:0:1}"
|
||||
recho $first_char
|
||||
|
||||
first_char="${f[@]:0:1}"
|
||||
recho $first_char
|
||||
|
||||
first_char="${f[0]:0:1}"
|
||||
recho $first_char
|
||||
|
||||
first_char="${f:0:1}"
|
||||
recho $first_char
|
||||
|
||||
unset f;
|
||||
f=( one two three )
|
||||
first_word=${f[@]:0:1}
|
||||
recho $first_word
|
||||
|
||||
first_word=${f[0]:0:1}
|
||||
recho $first_word
|
||||
|
||||
first_word=${f:0:1}
|
||||
recho $first_word
|
||||
|
||||
unset f;
|
||||
f=( one two three )
|
||||
first_word=${f[@]:0:1}
|
||||
@@ -15,3 +41,4 @@ set -- abc def ghi
|
||||
|
||||
printf '<%s> ' "123 $@ 456"; echo
|
||||
printf '<%s> ' "123 $@\ 456"; echo
|
||||
|
||||
|
||||
@@ -81,4 +81,17 @@ recho ${foo=$@}
|
||||
recho "$foo"
|
||||
|
||||
shift $#
|
||||
unset foo
|
||||
unset foo x
|
||||
|
||||
set -- a b
|
||||
x=abc
|
||||
|
||||
IFS=
|
||||
printf "<%s>\n" ${x#$*}
|
||||
printf "<%s>\n" "${x#$*}"
|
||||
|
||||
x=abcd
|
||||
set a c
|
||||
IFS='?'
|
||||
printf "<%s>\n" ${x#$*}
|
||||
printf "<%s>\n" "${x#$*}"
|
||||
|
||||
@@ -0,0 +1,53 @@
|
||||
# testing various combinations of quoted and unquoted expansions of $@, and
|
||||
# whether they generate empty words after expansion
|
||||
|
||||
n() { echo "$#"; }
|
||||
|
||||
n "$@"
|
||||
n ${foo-"$@"}
|
||||
n "${foo-$@}"
|
||||
|
||||
n ""$@
|
||||
n """$@"
|
||||
|
||||
n $(true)$@
|
||||
n "$(true)$@"
|
||||
n "$(true)$@"
|
||||
n "$(true)""$@"
|
||||
|
||||
n $xxx$@
|
||||
n "$xxx$@"
|
||||
n $xxx"$@"
|
||||
n "$xxx""$@"
|
||||
|
||||
recho $xxx"$@"
|
||||
echo after 1
|
||||
|
||||
recho "$xxx$@"
|
||||
echo after 2
|
||||
|
||||
recho ${foo:-$xxx"$@"}
|
||||
echo after 3
|
||||
|
||||
# this is where these things start to differ
|
||||
echo same as 1
|
||||
recho "${foo:-$xxx"$@"}"
|
||||
echo same as 2
|
||||
recho "${foo:-$xxx$@}"
|
||||
|
||||
echo null fields
|
||||
recho ""$@
|
||||
recho """$@"
|
||||
|
||||
echo null fields in rhs
|
||||
echo null string with unquoted '$@'
|
||||
recho ${foo:-""$@}
|
||||
echo null string with quoted '$@'
|
||||
recho ${foo:-"""$@"}
|
||||
|
||||
echo assignment
|
||||
recho "${foo=$@}"
|
||||
echo variable
|
||||
recho "$foo"
|
||||
echo dollar-at
|
||||
recho "${@}"
|
||||
@@ -158,6 +158,14 @@ ok at 8
|
||||
ok at 9
|
||||
argv[1] = <a>
|
||||
argv[1] = <a>
|
||||
argv[1] = <a>
|
||||
argv[1] = <a>
|
||||
argv[1] = <a>
|
||||
argv[1] = <a>
|
||||
argv[1] = <a>
|
||||
argv[1] = <one>
|
||||
argv[1] = <o>
|
||||
argv[1] = <o>
|
||||
argv[1] = <one>
|
||||
<123 abc> <def> <ghi 456>
|
||||
<123 abc> <def> <ghi\ 456>
|
||||
@@ -185,6 +193,42 @@ argv[1] = <abcd>
|
||||
argv[1] = <a>
|
||||
argv[2] = <b>
|
||||
argv[1] = <a b>
|
||||
<c>
|
||||
<c>
|
||||
<d>
|
||||
<d>
|
||||
0
|
||||
0
|
||||
1
|
||||
1
|
||||
1
|
||||
0
|
||||
0
|
||||
0
|
||||
1
|
||||
0
|
||||
0
|
||||
0
|
||||
1
|
||||
after 1
|
||||
after 2
|
||||
after 3
|
||||
same as 1
|
||||
argv[1] = <>
|
||||
same as 2
|
||||
argv[1] = <>
|
||||
null fields
|
||||
argv[1] = <>
|
||||
argv[1] = <>
|
||||
null fields in rhs
|
||||
null string with unquoted $@
|
||||
argv[1] = <>
|
||||
null string with quoted $@
|
||||
assignment
|
||||
argv[1] = <>
|
||||
variable
|
||||
argv[1] = <>
|
||||
dollar-at
|
||||
xa|xb|xc
|
||||
xa|xb|xc
|
||||
a|b|c
|
||||
|
||||
+9
-5
@@ -357,6 +357,7 @@ initialize_shell_variables (env, privmode)
|
||||
|
||||
temp_var = (SHELL_VAR *)NULL;
|
||||
|
||||
#if defined (FUNCTION_IMPORT)
|
||||
/* If exported function, define it now. Don't import functions from
|
||||
the environment in privileged mode. */
|
||||
if (privmode == 0 && read_but_dont_execute == 0 &&
|
||||
@@ -406,6 +407,7 @@ initialize_shell_variables (env, privmode)
|
||||
/* Restore original suffix */
|
||||
tname[namelen] = BASHFUNC_SUFFIX[0];
|
||||
}
|
||||
#endif /* FUNCTION_IMPORT */
|
||||
#if defined (ARRAY_VARS)
|
||||
# if ARRAY_EXPORT
|
||||
/* Array variables may not yet be exported. */
|
||||
@@ -420,11 +422,7 @@ initialize_shell_variables (env, privmode)
|
||||
}
|
||||
# endif /* ARRAY_EXPORT */
|
||||
#endif
|
||||
#if 0
|
||||
else if (legal_identifier (name))
|
||||
#else
|
||||
else
|
||||
#endif
|
||||
{
|
||||
ro = 0;
|
||||
if (posixly_correct && STREQ (name, "SHELLOPTS"))
|
||||
@@ -5158,10 +5156,16 @@ void
|
||||
sv_optind (name)
|
||||
char *name;
|
||||
{
|
||||
SHELL_VAR *var;
|
||||
char *tt;
|
||||
int s;
|
||||
|
||||
tt = get_string_value ("OPTIND");
|
||||
var = find_variable ("OPTIND");
|
||||
tt = var ? get_variable_value (var) : (char *)NULL;
|
||||
|
||||
/* Assume that if var->context < variable_context and variable_context > 0
|
||||
then we are restoring the variables's previous state while returning
|
||||
from a function. */
|
||||
if (tt && *tt)
|
||||
{
|
||||
s = atoi (tt);
|
||||
|
||||
+5440
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user