commit bash-20080904 snapshot

This commit is contained in:
Chet Ramey
2011-12-07 09:28:26 -05:00
parent 40c8fbee93
commit 48ff544772
57 changed files with 6877 additions and 6620 deletions
+50
View File
@@ -6828,3 +6828,53 @@ subst.c
- set the W_HASQUOTEDNULL flag in the return value from
parameter_brace_expand if the return value from parameter_brace_patsub
is a quoted null string
9/6
---
builtins/read.def
- change read -t 0 to return success if there is input available to be
read -- allows scripts to poll for input. Uses input_avail libsh
function
9/9
---
externs.h
- fix extern fpurge declaration -- use HAVE_DECL_FPURGE instead of
NEED_FPURGE_DECL, since the former is set by `configure'
jobs.h
- add extern declaration for close_pgrp_pipe
- add a new job state JNONE (-1) to the enum
jobs.c
- include execute_cmd.h for extern declarations for coproc functions
subst.c
- include builtins/builtext.h for extern declarations for functions
implementing builtins (e.g., declare_builtin)
arrayfunc.c
- include "pathexp.h" for extern declaration for glob_char_p
braces.c
- add extern declaration for `asprintf'
lib/readline/rlprivate.h
- add extern declarations for _rl_trace, _rl_tropen
lib/sh/zgetline.c
- add extern declarations for zread, zreadc
lib/sh/mktime.c
- include "bashansi.h" for string function declarations
builtins/common.h
- add extern declaration for parse_string
trap.c
- include jobs.h for extern declaration for run_sigchld_trap
general.c
- fix call to strtoimax in legal_number; if ep == string when function
returns, the number was not converted, even if errno is not set.
Fix from Paul Jarc <prj@case.edu>
+48
View File
@@ -6825,3 +6825,51 @@ subst.c
W_HASQUOTEDNULL flag in the returned WORD_DESC * if the return value
from parameter_brace_remove_pattern is a quoted null string. Fixes
bug reported by Andreas Schwab <schwab@suse.de>
- set the W_HASQUOTEDNULL flag in the return value from
parameter_brace_expand if the return value from parameter_brace_patsub
is a quoted null string
9/6
---
builtins/read.def
- change read -t 0 to return success if there is input available to be
read -- allows scripts to poll for input. Uses input_avail libsh
function
9/9
---
externs.h
- fix extern fpurge declaration -- use HAVE_DECL_FPURGE instead of
NEED_FPURGE_DECL, since the former is set by `configure'
jobs.h
- add extern declaration for close_pgrp_pipe
- add a new job state JNONE (-1) to the enum
jobs.c
- include execute_cmd.h for extern declarations for coproc functions
subst.c
- include builtins/builtext.h for extern declarations for functions
implementing builtins (e.g., declare_builtin)
arrayfunc.c
- include "pathexp.h" for extern declaration for glob_char_p
braces.c
- add extern declaration for `asprintf'
lib/readline/rlprivate.h
- add extern declarations for _rl_trace, _rl_tropen
lib/sh/zgetline.c
- add extern declarations for zread, zreadc
lib/sh/mktime.c
- include "bashansi.h" for string function declarations
builtins/common.h
- add extern declaration for parse_string
trap.c
- include jobs.h for extern declaration for run_sigchld_trap
+1
View File
@@ -30,6 +30,7 @@
#include "bashintl.h"
#include "shell.h"
#include "pathexp.h"
#include "shmbutil.h"
+13 -18
View File
@@ -4,19 +4,19 @@
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 2, or (at your option) any later
version.
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.
Bash is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with Bash; see the file COPYING. If not, write to the Free Software
Foundation, 59 Temple Place, Suite 330, Boston, MA 02111 USA. */
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"
@@ -420,13 +420,8 @@ assign_compound_array_list (var, nlist, flags)
arrayind_t ind, last_ind;
char *akey;
a = (ARRAY *)0;
h = (HASH_TABLE *)0;
if (assoc_p (var))
h = assoc_cell (var);
else
a = array_cell (var);
a = (var && array_p (var)) ? array_cell (var) : (ARRAY *)0;
h = (var && assoc_p (var)) ? assoc_cell (var) : (HASH_TABLE *)0;
akey = (char *)0;
ind = 0;
+2
View File
@@ -45,6 +45,8 @@
#define BRACE_SEQ_SPECIFIER ".."
extern int asprintf __P((char **, const char *, ...)) __attribute__((__format__ (printf, 2, 3)));
/* Basic idea:
Segregate the text into 3 sections: preamble (stuff before an open brace),
+13 -14
View File
@@ -4,19 +4,19 @@
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 2, or (at your option)
any later version.
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.
Bash is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Bash; see the file COPYING. If not, write to the Free
Software Foundation, 59 Temple Place, Suite 330, Boston, MA 02111 USA. */
along with Bash. If not, see <http://www.gnu.org/licenses/>.
*/
/* Stuff in curly braces gets expanded before all other shell expansions. */
@@ -413,7 +413,6 @@ expand_seqterm (text, tlen)
if (*ep != 0)
rhs_t = ST_BAD; /* invalid incr */
}
if (lhs_t != rhs_t || lhs_t == ST_BAD || rhs_t == ST_BAD)
{
@@ -442,7 +441,7 @@ expand_seqterm (text, tlen)
width = 0;
if (lhs_l > 1 && lhs[0] == '0')
width = lhs_l, lhs_t = ST_ZINT;
if (lhs > 2 && lhs[0] == '-' && lhs[1] == '0')
if (lhs_l > 2 && lhs[0] == '-' && lhs[1] == '0')
width = lhs_l, lhs_t = ST_ZINT;
if (rhs_l > 1 && rhs[0] == '0' && width < rhs_l)
width = rhs_l, lhs_t = ST_ZINT;
@@ -450,7 +449,7 @@ expand_seqterm (text, tlen)
width = rhs_l, lhs_t = ST_ZINT;
}
result = mkseq (lhs_v, rhs_v, 1, lhs_t, width);
result = mkseq (lhs_v, rhs_v, incr, lhs_t, width);
free (lhs);
free (rhs);
@@ -539,7 +538,7 @@ brace_gobbler (text, tlen, indx, satisfy)
if ((c == '$' || c == '<' || c == '>') && text[i+1] == '(') /* ) */
{
si = i + 2;
t = extract_command_subst (text, &si);
t = extract_command_subst (text, &si, 0);
i = si;
free (t);
i++;
+1
View File
@@ -294,6 +294,7 @@ sh_wrerror ()
int
sh_chkwrite (s)
int s;
{
fflush (stdout);
if (ferror (stdout))
+36 -26
View File
@@ -1,20 +1,22 @@
/* Copyright (C) 1987-2007 Free Software Foundation, Inc.
/* common.c - utility functions for all builtins */
/* Copyright (C) 1987-2008 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 2, or (at your option) any later
version.
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; see the file COPYING. If not, write to the Free Software
Foundation, 59 Temple Place, Suite 330, Boston, MA 02111 USA. */
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>
@@ -284,6 +286,9 @@ sh_notbuiltin (s)
void
sh_wrerror ()
{
#if defined (DONT_REPORT_BROKEN_PIPE_WRITE_ERRORS) && defined (EPIPE)
if (errno != EPIPE)
#endif /* DONT_REPORT_BROKEN_PIPE_WRITE_ERRORS && EPIPE */
builtin_error (_("write error: %s"), strerror (errno));
}
@@ -396,30 +401,35 @@ set_dollar_vars_changed ()
/* Read a numeric arg for this_command_name, the name of the shell builtin
that wants it. LIST is the word list that the arg is to come from.
Accept only the numeric argument; report an error if other arguments
follow. If FATAL is true, call throw_to_top_level, which exits the
shell; if not, call jump_to_top_level (DISCARD), which aborts the
current command. */
intmax_t
get_numeric_arg (list, fatal)
follow. If FATAL is 1, call throw_to_top_level, which exits the
shell; if it's 2, call jump_to_top_level (DISCARD), which aborts the
current command; if FATAL is 0, return an indication of an invalid
number by setting *NUMOK == 0 and return -1. */
int
get_numeric_arg (list, fatal, count)
WORD_LIST *list;
int fatal;
intmax_t *count;
{
intmax_t count = 1;
char *arg;
if (count)
*count = 1;
if (list && list->word && ISOPTION (list->word->word, '-'))
list = list->next;
if (list)
{
register char *arg;
arg = list->word->word;
if (arg == 0 || (legal_number (arg, &count) == 0))
if (arg == 0 || (legal_number (arg, count) == 0))
{
sh_neednumarg (list->word->word);
if (fatal)
sh_neednumarg (list->word->word ? list->word->word : "`'");
if (fatal == 0)
return 0;
else if (fatal == 1) /* fatal == 1; abort */
throw_to_top_level ();
else
else /* fatal == 2; discard current command */
{
top_level_cleanup ();
jump_to_top_level (DISCARD);
@@ -428,7 +438,7 @@ get_numeric_arg (list, fatal)
no_args (list->next);
}
return (count);
return (1);
}
/* Get an eight-bit status value from LIST */
+1
View File
@@ -158,6 +158,7 @@ extern WORD_LIST *get_directory_stack __P((int));
/* Functions from evalstring.c */
extern int parse_and_execute __P((char *, const char *, int));
extern void parse_and_execute_cleanup __P((void));
extern int parse_string __P((char *, const char *, int, char **));
/* Functions from evalfile.c */
extern int maybe_execute_file __P((const char *, int));
+14 -12
View File
@@ -4,19 +4,19 @@
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 2, or (at your option) any later
version.
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.
Bash is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with Bash; see the file COPYING. If not, write to the Free Software
Foundation, 59 Temple Place, Suite 330, Boston, MA 02111 USA. */
You should have received a copy of the GNU General Public License
along with Bash. If not, see <http://www.gnu.org/licenses/>.
*/
#if !defined (__COMMON_H)
# define __COMMON_H
@@ -31,6 +31,8 @@
#define SEVAL_NOHIST 0x004
#define SEVAL_NOFREE 0x008
#define SEVAL_RESETLINE 0x010
#define SEVAL_PARSEONLY 0x020
#define SEVAL_NOLONGJMP 0x040
/* Flags for describe_command, shared between type.def and command.def */
#define CDESC_ALL 0x001 /* type -a */
@@ -87,7 +89,7 @@ extern int dollar_vars_changed __P((void));
extern void set_dollar_vars_unchanged __P((void));
extern void set_dollar_vars_changed __P((void));
extern intmax_t get_numeric_arg __P((WORD_LIST *, int));
extern int get_numeric_arg __P((WORD_LIST *, int, intmax_t *));
extern int get_exitstat __P((WORD_LIST *));
extern int read_octal __P((char *));
+1 -1
View File
@@ -588,7 +588,7 @@ printstr (fmt, string, len, fieldwidth, precision)
#else
if (string == 0 || len == 0)
#endif
return;
return 0;
#if 0
s = fmt;
+14 -11
View File
@@ -5,19 +5,18 @@ Copyright (C) 1997-2008 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 2, or (at your option) any later
version.
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.
Bash is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with Bash; see the file COPYING. If not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA
You should have received a copy of the GNU General Public License
along with Bash. If not, see <http://www.gnu.org/licenses/>.
$PRODUCES printf.c
@@ -41,6 +40,10 @@ and printf(3), printf interprets:
%b expand backslash escape sequences in the corresponding argument
%q quote the argument in a way that can be reused as shell input
Exit Status:
Returns success unless an invalid option is given or a write or assignment
error occurs.
$END
#include <config.h>
+7 -2
View File
@@ -50,8 +50,9 @@ Options:
-t timeout time out and return failure if a complete line of input is
not read withint TIMEOUT seconds. The value of the TMOUT
variable is the default timeout. TIMEOUT may be a
fractional number. The exit status is greater than 128 if
the timeout is exceeded
fractional number. If TIMEOUT is 0, read returns success only
if input is available on the specified file descriptor. The
exit status is greater than 128 if the timeout is exceeded
-u fd read from file descriptor FD instead of the standard input
Exit Status:
@@ -293,7 +294,11 @@ read_builtin (list)
whether input is available with select/FIONREAD, and fail if those
are unavailable? */
if (have_timeout && tmsec == 0 && tmusec == 0)
#if 0
return (EXECUTION_FAILURE);
#else
return (input_avail (fd) ? EXECUTION_SUCCESS : EXECUTION_FAILURE);
#endif
/* IF IFS is unset, we use the default of " \t\n". */
ifs_chars = getifs ();
+16 -11
View File
@@ -5,19 +5,18 @@ Copyright (C) 1987-2008 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 2, or (at your option) any later
version.
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.
Bash is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with Bash; see the file COPYING. If not, write to the Free Software
Foundation, 59 Temple Place, Suite 330, Boston, MA 02111 USA.
You should have received a copy of the GNU General Public License
along with Bash. If not, see <http://www.gnu.org/licenses/>.
$PRODUCES read.c
@@ -67,6 +66,8 @@ $END
#include <stdio.h>
#include "bashansi.h"
#if defined (HAVE_UNISTD_H)
# include <unistd.h>
#endif
@@ -292,7 +293,11 @@ read_builtin (list)
whether input is available with select/FIONREAD, and fail if those
are unavailable? */
if (have_timeout && tmsec == 0 && tmusec == 0)
#if 0
return (EXECUTION_FAILURE);
#else
return (input_avail (fd) ? EXECUTION_SUCCESS : EXECUTION_FAILURE);
#endif
/* IF IFS is unset, we use the default of " \t\n". */
ifs_chars = getifs ();
+4 -2
View File
@@ -5,12 +5,12 @@
.\" Case Western Reserve University
.\" chet@po.cwru.edu
.\"
.\" Last Change: Fri Aug 22 12:45:34 EDT 2008
.\" Last Change: Sat Sep 6 13:05:54 EDT 2008
.\"
.\" bash_builtins, strip all but Built-Ins section
.if \n(zZ=1 .ig zZ
.if \n(zY=1 .ig zY
.TH BASH 1 "2008 August 22" "GNU Bash-4.0"
.TH BASH 1 "2008 September 6" "GNU Bash-4.0"
.\"
.\" There's some problem with having a `@'
.\" in a tagged paragraph with the BSD man macros.
@@ -7876,6 +7876,8 @@ the decimal point.
This option is only effective if \fBread\fP is reading input from a
terminal, pipe, or other special file; it has no effect when reading
from regular files.
If \fItimeout\fP is 0, \fBread\fP returns success if input is available on
the specified file descriptor, failure otherwise.
The exit status is greater than 128 if the timeout is exceeded.
.TP
.B \-u \fIfd\fP
+3 -3
View File
@@ -5,12 +5,12 @@
.\" Case Western Reserve University
.\" chet@po.cwru.edu
.\"
.\" Last Change: Sun Jul 6 14:33:52 EDT 2008
.\" Last Change: Fri Aug 22 12:45:34 EDT 2008
.\"
.\" bash_builtins, strip all but Built-Ins section
.if \n(zZ=1 .ig zZ
.if \n(zY=1 .ig zY
.TH BASH 1 "2008 July 6" "GNU Bash-4.0"
.TH BASH 1 "2008 August 22" "GNU Bash-4.0"
.\"
.\" There's some problem with having a `@'
.\" in a tagged paragraph with the BSD man macros.
@@ -5252,7 +5252,7 @@ Invoke an editor on the current command line, and execute the result as shell
commands.
\fBBash\fP attempts to invoke
.SM
.BR $FCEDIT ,
.BR $VISUAL ,
.SM
.BR $EDITOR ,
and \fIemacs\fP as the editor, in that order.
+2
View File
@@ -3748,6 +3748,8 @@ the decimal point.
This option is only effective if @code{read} is reading input from a
terminal, pipe, or other special file; it has no effect when reading
from regular files.
If @var{timeout} is 0, @code{read} returns success if input is available on
the specified file descriptor, failure otherwise.
The exit status is greater than 128 if the timeout is exceeded.
@item -u @var{fd}
+1 -1
View File
@@ -6459,7 +6459,7 @@ file if it is the only so-named file found in @code{$PATH}.
@item
The @code{vi} editing mode will invoke the @code{vi} editor directly when
the @samp{v} command is run, instead of checking @code{$FCEDIT} and
the @samp{v} command is run, instead of checking @code{$VISUAL} and
@code{$EDITOR}.
@item
+3 -3
View File
@@ -2,9 +2,9 @@
Copyright (C) 1988-2008 Free Software Foundation, Inc.
@end ignore
@set LASTCHANGE Fri Aug 22 12:46:16 EDT 2008
@set LASTCHANGE Sat Sep 6 13:05:30 EDT 2008
@set EDITION 4.0
@set VERSION 4.0
@set UPDATED 22 August 2008
@set UPDATED-MONTH August 2008
@set UPDATED 6 September 2008
@set UPDATED-MONTH September 2008
+3 -3
View File
@@ -2,9 +2,9 @@
Copyright (C) 1988-2008 Free Software Foundation, Inc.
@end ignore
@set LASTCHANGE Sun Jul 6 14:33:52 EDT 2008
@set LASTCHANGE Fri Aug 22 12:46:16 EDT 2008
@set EDITION 4.0
@set VERSION 4.0
@set UPDATED 6 July 2008
@set UPDATED-MONTH July 2008
@set UPDATED 22 August 2008
@set UPDATED-MONTH August 2008
+2 -2
View File
@@ -185,14 +185,14 @@ extern char *fmtullong __P((unsigned long long int, int, char *, size_t, int));
extern char *fmtumax __P((uintmax_t, int, char *, size_t, int));
/* Declarations for functions defined in lib/sh/fpurge.c */
#if defined (NEED_FPURGE_DECL)
#if !HAVE_DECL_FPURGE
#if HAVE_FPURGE
# define fpurge _bash_fpurge
#endif
extern int fpurge __P((FILE *stream));
#endif /* NEED_FPURGE_DECL */
#endif /* HAVE_DECL_FPURGE */
/* Declarations for functions defined in lib/sh/getcwd.c */
+12 -11
View File
@@ -5,19 +5,19 @@
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 2, or (at your option) any later
version.
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.
Bash is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with Bash; see the file COPYING. If not, write to the Free Software
Foundation, 59 Temple Place, Suite 330, Boston, MA 02111 USA. */
You should have received a copy of the GNU General Public License
along with Bash. If not, see <http://www.gnu.org/licenses/>.
*/
/* Make sure that this is included *after* config.h! */
@@ -96,6 +96,7 @@ extern char **brace_expand __P((char *));
/* Miscellaneous functions from parse.y */
extern int yyparse __P((void));
extern int return_EOF __P((void));
extern char *xparse_dolparen __P((char *, char *, int *, int));
extern void reset_parser __P((void));
extern WORD_LIST *parse_string_to_word_list __P((char *, int, const char *));
+1 -1
View File
@@ -173,7 +173,7 @@ legal_number (string, result)
errno = 0;
value = strtoimax (string, &ep, 10);
if (errno)
if (errno || ep == string)
return 0; /* errno is set on overflow or underflow */
/* Skip any trailing whitespace, since strtoimax does not. */
+11 -17
View File
@@ -4,19 +4,19 @@
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 2, or (at your option) any later
version.
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.
Bash is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with Bash; see the file COPYING. If not, write to the Free Software
Foundation, 59 Temple Place, Suite 330, Boston, MA 02111 USA. */
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"
@@ -476,14 +476,8 @@ check_binary_file (sample, sample_len)
c = sample[i];
if (c == '\n')
return (0);
#if 0
if (ISSPACE (c) == 0 && ISPRINT (c) == 0)
#else
if (c == '\0')
#endif
return (1);
}
return (0);
+4
View File
@@ -67,6 +67,7 @@
#include "bashintl.h"
#include "shell.h"
#include "jobs.h"
#include "execute_cmd.h"
#include "flags.h"
#include "builtins/builtext.h"
@@ -843,6 +844,7 @@ cleanup_dead_jobs ()
static int
processes_in_job (job)
int job;
{
int nproc;
register PROCESS *p;
@@ -1685,6 +1687,8 @@ make_child (command, async_p)
making_children ();
forksleep = 1;
#if defined (BUFFERED_INPUT)
/* If default_buffered_input is active, we are reading a script. If
the command is asynchronous, we have already duplicated /dev/null
+19 -16
View File
@@ -1,4 +1,4 @@
/* The thing that makes children, remembers them, and contains wait loops. */
/* jobs.c - functions that make children, remember them, and handle their termination. */
/* This file works with both POSIX and BSD systems. It implements job
control. */
@@ -7,19 +7,19 @@
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 2, or (at your option) any later
version.
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.
Bash is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with Bash; see the file COPYING. If not, write to the Free Software
Foundation, 59 Temple Place, Suite 330, Boston, MA 02111 USA. */
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"
@@ -769,7 +769,7 @@ bgp_prune ()
bgpids.npid--;
}
}
/* Reset the values of js.j_lastj and js.j_firstj after one or both have
been deleted. The caller should check whether js.j_njobs is 0 before
calling this. This wraps around, but the rest of the code does not. At
@@ -843,6 +843,7 @@ cleanup_dead_jobs ()
static int
processes_in_job (job)
int job;
{
int nproc;
register PROCESS *p;
@@ -1685,6 +1686,8 @@ make_child (command, async_p)
making_children ();
forksleep = 1;
#if defined (BUFFERED_INPUT)
/* If default_buffered_input is active, we are reading a script. If
the command is asynchronous, we have already duplicated /dev/null
@@ -3058,8 +3061,6 @@ waitchld (wpid, block)
break;
}
itrace("waitchld: waitpid returns %d", pid);
/* If waitpid returns 0, there are running children. If it returns -1,
the only other error POSIX says it can return is EINTR. */
CHECK_TERMSIG;
@@ -3845,6 +3846,8 @@ maybe_give_terminal_to (opgrp, npgrp, flags)
int tpgrp;
tpgrp = tcgetpgrp (shell_tty);
if (tpgrp < 0 && errno == ENOTTY)
return -1;
if (tpgrp == npgrp)
{
terminal_pgrp = npgrp;
@@ -3853,7 +3856,7 @@ maybe_give_terminal_to (opgrp, npgrp, flags)
else if (tpgrp != opgrp)
{
#if defined (DEBUG)
internal_warning ("maybe_give_terminal_to: terminal pgrp == %d shell pgrp = %d", tpgrp, opgrp);
internal_warning ("maybe_give_terminal_to: terminal pgrp == %d shell pgrp = %d new pgrp = %d", tpgrp, opgrp, npgrp);
#endif
return -1;
}
+3 -1
View File
@@ -77,7 +77,7 @@ typedef struct process {
#define get_job_by_jid(ind) (jobs[(ind)])
/* A description of a pipeline's state. */
typedef enum { JRUNNING = 1, JSTOPPED = 2, JDEAD = 4, JMIXED = 8 } JOB_STATE;
typedef enum { JNONE = -1, JRUNNING = 1, JSTOPPED = 2, JDEAD = 4, JMIXED = 8 } JOB_STATE;
#define JOBSTATE(job) (jobs[(job)]->state)
#define J_JOBSTATE(j) ((j)->state)
@@ -234,6 +234,8 @@ extern void default_tty_job_signals __P((void));
extern void init_job_stats __P((void));
extern void close_pgrp_pipe __P((void));
#if defined (JOB_CONTROL)
extern int job_control;
#endif
+243
View File
@@ -0,0 +1,243 @@
/* jobs.h -- structures and definitions used by the jobs.c file. */
/* Copyright (C) 1993-2008 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
Bash is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Bash is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Bash. If not, see <http://www.gnu.org/licenses/>.
*/
#if !defined (_JOBS_H_)
# define _JOBS_H_
#include "quit.h"
#include "siglist.h"
#include "stdc.h"
#include "posixwait.h"
/* Defines controlling the fashion in which jobs are listed. */
#define JLIST_STANDARD 0
#define JLIST_LONG 1
#define JLIST_PID_ONLY 2
#define JLIST_CHANGED_ONLY 3
#define JLIST_NONINTERACTIVE 4
/* I looked it up. For pretty_print_job (). The real answer is 24. */
#define LONGEST_SIGNAL_DESC 24
/* The max time to sleep while retrying fork() on EAGAIN failure */
#define FORKSLEEP_MAX 16
/* We keep an array of jobs. Each entry in the array is a linked list
of processes that are piped together. The first process encountered is
the group leader. */
/* Values for the `running' field of a struct process. */
#define PS_DONE 0
#define PS_RUNNING 1
#define PS_STOPPED 2
#define PS_RECYCLED 4
/* Each child of the shell is remembered in a STRUCT PROCESS. A circular
chain of such structures is a pipeline. */
typedef struct process {
struct process *next; /* Next process in the pipeline. A circular chain. */
pid_t pid; /* Process ID. */
WAIT status; /* The status of this command as returned by wait. */
int running; /* Non-zero if this process is running. */
char *command; /* The particular program that is running. */
} PROCESS;
/* PALIVE really means `not exited' */
#define PSTOPPED(p) (WIFSTOPPED((p)->status))
#define PRUNNING(p) ((p)->running == PS_RUNNING)
#define PALIVE(p) (PRUNNING(p) || PSTOPPED(p))
#define PEXITED(p) ((p)->running == PS_DONE)
#if defined (RECYCLES_PIDS)
# define PRECYCLED(p) ((p)->running == PS_RECYCLED)
#else
# define PRECYCLED(p) (0)
#endif
#define PDEADPROC(p) (PEXITED(p) || PRECYCLED(p))
#define get_job_by_jid(ind) (jobs[(ind)])
/* A description of a pipeline's state. */
typedef enum { JRUNNING = 1, JSTOPPED = 2, JDEAD = 4, JMIXED = 8 } JOB_STATE;
#define JOBSTATE(job) (jobs[(job)]->state)
#define J_JOBSTATE(j) ((j)->state)
#define STOPPED(j) (jobs[(j)]->state == JSTOPPED)
#define RUNNING(j) (jobs[(j)]->state == JRUNNING)
#define DEADJOB(j) (jobs[(j)]->state == JDEAD)
#define INVALID_JOB(j) ((j) < 0 || (j) >= js.j_jobslots || get_job_by_jid(j) == 0)
/* Values for the FLAGS field in the JOB struct below. */
#define J_FOREGROUND 0x01 /* Non-zero if this is running in the foreground. */
#define J_NOTIFIED 0x02 /* Non-zero if already notified about job state. */
#define J_JOBCONTROL 0x04 /* Non-zero if this job started under job control. */
#define J_NOHUP 0x08 /* Don't send SIGHUP to job if shell gets SIGHUP. */
#define J_STATSAVED 0x10 /* A process in this job had had status saved via $! */
#define J_ASYNC 0x20 /* Job was started asynchronously */
#define IS_FOREGROUND(j) ((jobs[j]->flags & J_FOREGROUND) != 0)
#define IS_NOTIFIED(j) ((jobs[j]->flags & J_NOTIFIED) != 0)
#define IS_JOBCONTROL(j) ((jobs[j]->flags & J_JOBCONTROL) != 0)
#define IS_ASYNC(j) ((jobs[j]->flags & J_ASYNC) != 0)
typedef struct job {
char *wd; /* The working directory at time of invocation. */
PROCESS *pipe; /* The pipeline of processes that make up this job. */
pid_t pgrp; /* The process ID of the process group (necessary). */
JOB_STATE state; /* The state that this job is in. */
int flags; /* Flags word: J_NOTIFIED, J_FOREGROUND, or J_JOBCONTROL. */
#if defined (JOB_CONTROL)
COMMAND *deferred; /* Commands that will execute when this job is done. */
sh_vptrfunc_t *j_cleanup; /* Cleanup function to call when job marked JDEAD */
PTR_T cleanarg; /* Argument passed to (*j_cleanup)() */
#endif /* JOB_CONTROL */
} JOB;
struct jobstats {
/* limits */
long c_childmax;
/* child process statistics */
int c_living; /* running or stopped child processes */
int c_reaped; /* exited child processes still in jobs list */
int c_injobs; /* total number of child processes in jobs list */
/* child process totals */
int c_totforked; /* total number of children this shell has forked */
int c_totreaped; /* total number of children this shell has reaped */
/* job counters and indices */
int j_jobslots; /* total size of jobs array */
int j_lastj; /* last (newest) job allocated */
int j_firstj; /* first (oldest) job allocated */
int j_njobs; /* number of non-NULL jobs in jobs array */
int j_ndead; /* number of JDEAD jobs in jobs array */
/* */
int j_current; /* current job */
int j_previous; /* previous job */
/* */
JOB *j_lastmade; /* last job allocated by stop_pipeline */
JOB *j_lastasync; /* last async job allocated by stop_pipeline */
};
struct pidstat {
struct pidstat *next;
pid_t pid;
int status;
};
struct bgpids {
struct pidstat *list;
struct pidstat *end;
int npid;
};
#define NO_JOB -1 /* An impossible job array index. */
#define DUP_JOB -2 /* A possible return value for get_job_spec (). */
#define BAD_JOBSPEC -3 /* Bad syntax for job spec. */
/* A value which cannot be a process ID. */
#define NO_PID (pid_t)-1
/* System calls. */
#if !defined (HAVE_UNISTD_H)
extern pid_t fork (), getpid (), getpgrp ();
#endif /* !HAVE_UNISTD_H */
/* Stuff from the jobs.c file. */
extern struct jobstats js;
extern pid_t original_pgrp, shell_pgrp, pipeline_pgrp;
extern pid_t last_made_pid, last_asynchronous_pid;
extern int asynchronous_notification;
extern JOB **jobs;
extern void making_children __P((void));
extern void stop_making_children __P((void));
extern void cleanup_the_pipeline __P((void));
extern void save_pipeline __P((int));
extern void restore_pipeline __P((int));
extern void start_pipeline __P((void));
extern int stop_pipeline __P((int, COMMAND *));
extern void delete_job __P((int, int));
extern void nohup_job __P((int));
extern void delete_all_jobs __P((int));
extern void nohup_all_jobs __P((int));
extern int count_all_jobs __P((void));
extern void terminate_current_pipeline __P((void));
extern void terminate_stopped_jobs __P((void));
extern void hangup_all_jobs __P((void));
extern void kill_current_pipeline __P((void));
#if defined (__STDC__) && defined (pid_t)
extern int get_job_by_pid __P((int, int));
extern void describe_pid __P((int));
#else
extern int get_job_by_pid __P((pid_t, int));
extern void describe_pid __P((pid_t));
#endif
extern void list_one_job __P((JOB *, int, int, int));
extern void list_all_jobs __P((int));
extern void list_stopped_jobs __P((int));
extern void list_running_jobs __P((int));
extern pid_t make_child __P((char *, int));
extern int get_tty_state __P((void));
extern int set_tty_state __P((void));
extern int wait_for_single_pid __P((pid_t));
extern void wait_for_background_pids __P((void));
extern int wait_for __P((pid_t));
extern int wait_for_job __P((int));
extern void notify_and_cleanup __P((void));
extern void reap_dead_jobs __P((void));
extern int start_job __P((int, int));
extern int kill_pid __P((pid_t, int, int));
extern int initialize_job_control __P((int));
extern void initialize_job_signals __P((void));
extern int give_terminal_to __P((pid_t, int));
extern void run_sigchld_trap __P((int));
extern void unfreeze_jobs_list __P((void));
extern int set_job_control __P((int));
extern void without_job_control __P((void));
extern void end_job_control __P((void));
extern void restart_job_control __P((void));
extern void set_sigchld_handler __P((void));
extern void ignore_tty_job_signals __P((void));
extern void default_tty_job_signals __P((void));
extern void init_job_stats __P((void));
extern void close_pgrp_pipe __P((void));
#if defined (JOB_CONTROL)
extern int job_control;
#endif
#endif /* _JOBS_H_ */
+1 -1
View File
@@ -25,7 +25,7 @@
#include "strmatch.h"
extern int xstrmatch __P((char *, char *, int));
#if defined (HAVE_MULTIBYTE)
#if defined (HANDLE_MULTIBYTE)
extern int internal_wstrmatch __P((wchar_t *, wchar_t *, int));
#endif
+79
View File
@@ -0,0 +1,79 @@
/* strmatch.c -- ksh-like extended pattern matching for the shell and filename
globbing. */
/* Copyright (C) 1991-2002 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>
#include "stdc.h"
#include "strmatch.h"
extern int xstrmatch __P((char *, char *, int));
#if defined (HAVE_MULTIBYTE)
extern int internal_wstrmatch __P((wchar_t *, wchar_t *, int));
#endif
int
strmatch (pattern, string, flags)
char *pattern;
char *string;
int flags;
{
if (string == 0 || pattern == 0)
return FNM_NOMATCH;
return (xstrmatch (pattern, string, flags));
}
#if defined (HANDLE_MULTIBYTE)
int
wcsmatch (wpattern, wstring, flags)
wchar_t *wpattern;
wchar_t *wstring;
int flags;
{
if (wstring == 0 || wpattern == 0)
return (FNM_NOMATCH);
return (internal_wstrmatch (wpattern, wstring, flags));
}
#endif
#ifdef TEST
main (c, v)
int c;
char **v;
{
char *string, *pat;
string = v[1];
pat = v[2];
if (strmatch (pat, string, 0) == 0)
{
printf ("%s matches %s\n", string, pat);
exit (0);
}
else
{
printf ("%s does not match %s\n", string, pat);
exit (1);
}
}
#endif
+1 -1
View File
@@ -183,7 +183,7 @@ _imalloc_fopen (s, fn, def, defbuf, defsiz)
sprintf (pidbuf, "%ld", l);
if ((strlen (pidbuf) + strlen (fn) + 2) >= sizeof (fname))
return;
return ((FILE *)0);
for (sp = 0, p = fname, q = fn; *q; )
{
if (sp == 0 && *q == '%' && q[1] == 'p')
+205
View File
@@ -0,0 +1,205 @@
/* stats.c - malloc statistics */
/* Copyright (C) 2001-2003 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/>.
*/
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include "imalloc.h"
#ifdef MALLOC_STATS
#include <stdio.h>
#ifdef HAVE_UNISTD_H
# include <unistd.h>
#endif
#include <string.h>
#include "mstats.h"
extern int malloc_free_blocks __P((int));
extern struct _malstats _mstats;
extern FILE *_imalloc_fopen __P((char *, char *, char *, char *, size_t));
struct bucket_stats
malloc_bucket_stats (size)
int size;
{
struct bucket_stats v;
v.nfree = 0;
if (size < 0 || size >= NBUCKETS)
{
v.blocksize = 0;
v.nused = v.nmal = v.nmorecore = v.nlesscore = v.nsplit = 0;
return v;
}
v.blocksize = 1 << (size + 3);
v.nused = _mstats.nmalloc[size];
v.nmal = _mstats.tmalloc[size];
v.nmorecore = _mstats.nmorecore[size];
v.nlesscore = _mstats.nlesscore[size];
v.nsplit = _mstats.nsplit[size];
v.ncoalesce = _mstats.ncoalesce[size];
v.nfree = malloc_free_blocks (size); /* call back to malloc.c */
return v;
}
/* Return a copy of _MSTATS, with two additional fields filled in:
BYTESFREE is the total number of bytes on free lists. BYTESUSED
is the total number of bytes in use. These two fields are fairly
expensive to compute, so we do it only when asked to. */
struct _malstats
malloc_stats ()
{
struct _malstats result;
struct bucket_stats v;
register int i;
result = _mstats;
result.bytesused = result.bytesfree = 0;
for (i = 0; i < NBUCKETS; i++)
{
v = malloc_bucket_stats (i);
result.bytesfree += v.nfree * v.blocksize;
result.bytesused += v.nused * v.blocksize;
}
return (result);
}
static void
_print_malloc_stats (s, fp)
char *s;
FILE *fp;
{
register int i;
unsigned long totused, totfree;
struct bucket_stats v;
fprintf (fp, "Memory allocation statistics: %s\n size\tfree\tin use\ttotal\tmorecore lesscore split\tcoalesce\n", s ? s : "");
for (i = totused = totfree = 0; i < NBUCKETS; i++)
{
v = malloc_bucket_stats (i);
if (v.nmal > 0)
fprintf (fp, "%8lu\t%4d\t%6d\t%5d\t%8d\t%d %5d %8d\n", (unsigned long)v.blocksize, v.nfree, v.nused, v.nmal, v.nmorecore, v.nlesscore, v.nsplit, v.ncoalesce);
totfree += v.nfree * v.blocksize;
totused += v.nused * v.blocksize;
}
fprintf (fp, "\nTotal bytes in use: %lu, total bytes free: %lu\n",
totused, totfree);
fprintf (fp, "\nTotal bytes requested by application: %lu\n", _mstats.bytesreq);
fprintf (fp, "Total mallocs: %d, total frees: %d, total reallocs: %d (%d copies)\n",
_mstats.nmal, _mstats.nfre, _mstats.nrealloc, _mstats.nrcopy);
fprintf (fp, "Total sbrks: %d, total bytes via sbrk: %d\n",
_mstats.nsbrk, _mstats.tsbrk);
fprintf (fp, "Total blocks split: %d, total block coalesces: %d\n",
_mstats.tbsplit, _mstats.tbcoalesce);
}
void
print_malloc_stats (s)
char *s;
{
_print_malloc_stats (s, stderr);
}
void
fprint_malloc_stats (s, fp)
char *s;
FILE *fp;
{
_print_malloc_stats (s, fp);
}
#define TRACEROOT "/var/tmp/maltrace/stats."
void
trace_malloc_stats (s, fn)
char *s, *fn;
{
FILE *fp;
char defname[sizeof (TRACEROOT) + 64];
static char mallbuf[1024];
fp = _imalloc_fopen (s, fn, TRACEROOT, defname, sizeof (defname));
if (fp)
{
setvbuf (fp, mallbuf, _IOFBF, sizeof (mallbuf));
_print_malloc_stats (s, fp);
fflush(fp);
fclose(fp);
}
}
#endif /* MALLOC_STATS */
#if defined (MALLOC_STATS) || defined (MALLOC_TRACE)
FILE *
_imalloc_fopen (s, fn, def, defbuf, defsiz)
char *s;
char *fn;
char *def;
char *defbuf;
size_t defsiz;
{
char fname[1024];
long l;
FILE *fp;
l = (long)getpid ();
if (fn == 0)
{
sprintf (defbuf, "%s%ld", def, l);
fp = fopen(defbuf, "w");
}
else
{
char *p, *q, *r;
char pidbuf[32];
int sp;
sprintf (pidbuf, "%ld", l);
if ((strlen (pidbuf) + strlen (fn) + 2) >= sizeof (fname))
return;
for (sp = 0, p = fname, q = fn; *q; )
{
if (sp == 0 && *q == '%' && q[1] == 'p')
{
sp = 1;
for (r = pidbuf; *r; )
*p++ = *r++;
q += 2;
}
else
*p++ = *q++;
}
*p = '\0';
fp = fopen (fname, "w");
}
return fp;
}
#endif /* MALLOC_STATS || MALLOC_TRACE */
+4
View File
@@ -330,11 +330,15 @@ extern UNDO_LIST *_rl_copy_undo_list PARAMS((UNDO_LIST *));
#if defined (USE_VARARGS) && defined (PREFER_STDARG)
extern void _rl_ttymsg (const char *, ...) __attribute__((__format__ (printf, 1, 2)));
extern void _rl_errmsg (const char *, ...) __attribute__((__format__ (printf, 1, 2)));
extern void _rl_trace (const char *, ...) __attribute__((__format__ (printf, 1, 2)));
#else
extern void _rl_ttymsg ();
extern void _rl_errmsg ();
extern void _rl_trace ();
#endif
extern int _rl_tropen PARAMS((void));
extern int _rl_abort_internal PARAMS((void));
extern char *_rl_strindex PARAMS((const char *, const char *));
extern int _rl_qsort_string_compare PARAMS((char **, char **));
+13 -13
View File
@@ -1,25 +1,24 @@
/* rlprivate.h -- functions and variables global to the readline library,
but not intended for use by applications. */
/* Copyright (C) 1999-2007 Free Software Foundation, Inc.
/* Copyright (C) 1999-2008 Free Software Foundation, Inc.
This file is part of the GNU Readline Library, a library for
reading lines of text with interactive input and history editing.
This file is part of the GNU Readline Library (Readline), a library
for reading lines of text with interactive input and history editing.
The GNU Readline Library is free software; you can redistribute it
and/or modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2, or
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.
The GNU Readline Library 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
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.
The GNU General Public License is often shipped with GNU software, and
is generally kept in a file called COPYING or LICENSE. If you do not
have a copy of the license, write to the Free Software Foundation,
59 Temple Place, Suite 330, Boston, MA 02111 USA. */
You should have received a copy of the GNU General Public License
along with Readline. If not, see <http://www.gnu.org/licenses/>.
*/
#if !defined (_RL_PRIVATE_H_)
#define _RL_PRIVATE_H_
@@ -371,6 +370,7 @@ extern int _rl_complete_show_all;
extern int _rl_complete_show_unmodified;
extern int _rl_complete_mark_directories;
extern int _rl_complete_mark_symlink_dirs;
extern int _rl_completion_prefix_display_length;
extern int _rl_print_completions_horizontally;
extern int _rl_completion_case_fold;
extern int _rl_match_hidden_files;
+2 -3
View File
@@ -50,11 +50,10 @@
#include <limits.h>
#endif
#include "bashansi.h"
#if DEBUG
#include <stdio.h>
#if STDC_HEADERS
#include <stdlib.h>
#endif
/* Make it work even if the system's libc has its own mktime routine. */
#define mktime my_mktime
#endif /* DEBUG */
+426
View File
@@ -0,0 +1,426 @@
/* mktime - convert struct tm to a time_t value */
/* Copyright (C) 1993-2002 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
Contributed by Paul Eggert (eggert@twinsun.com).
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/>.
*/
/* Define this to have a standalone program to test this implementation of
mktime. */
/* #define DEBUG 1 */
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#ifdef _LIBC
# define HAVE_LIMITS_H 1
# define HAVE_LOCALTIME_R 1
# define STDC_HEADERS 1
#endif
/* Assume that leap seconds are possible, unless told otherwise.
If the host has a `zic' command with a `-L leapsecondfilename' option,
then it supports leap seconds; otherwise it probably doesn't. */
#ifndef LEAP_SECONDS_POSSIBLE
#define LEAP_SECONDS_POSSIBLE 1
#endif
#ifndef VMS
#include <sys/types.h> /* Some systems define `time_t' here. */
#else
#include <stddef.h>
#endif
#include <time.h>
#if HAVE_LIMITS_H
#include <limits.h>
#endif
#if DEBUG
#include <stdio.h>
#if STDC_HEADERS
#include <stdlib.h>
#endif
/* Make it work even if the system's libc has its own mktime routine. */
#define mktime my_mktime
#endif /* DEBUG */
#ifndef __P
#if defined (__GNUC__) || (defined (__STDC__) && __STDC__)
#define __P(args) args
#else
#define __P(args) ()
#endif /* GCC. */
#endif /* Not __P. */
#ifndef CHAR_BIT
#define CHAR_BIT 8
#endif
#ifndef INT_MIN
#define INT_MIN (~0 << (sizeof (int) * CHAR_BIT - 1))
#endif
#ifndef INT_MAX
#define INT_MAX (~0 - INT_MIN)
#endif
#ifndef TIME_T_MIN
#define TIME_T_MIN (0 < (time_t) -1 ? (time_t) 0 \
: ~ (time_t) 0 << (sizeof (time_t) * CHAR_BIT - 1))
#endif
#ifndef TIME_T_MAX
#define TIME_T_MAX (~ (time_t) 0 - TIME_T_MIN)
#endif
#define TM_YEAR_BASE 1900
#define EPOCH_YEAR 1970
#ifndef __isleap
/* Nonzero if YEAR is a leap year (every 4 years,
except every 100th isn't, and every 400th is). */
#define __isleap(year) \
((year) % 4 == 0 && ((year) % 100 != 0 || (year) % 400 == 0))
#endif
/* How many days come before each month (0-12). */
const unsigned short int __mon_yday[2][13] =
{
/* Normal years. */
{ 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365 },
/* Leap years. */
{ 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366 }
};
static time_t ydhms_tm_diff __P ((int, int, int, int, int, const struct tm *));
time_t __mktime_internal __P ((struct tm *,
struct tm *(*) (const time_t *, struct tm *),
time_t *));
static struct tm *my_localtime_r __P ((const time_t *, struct tm *));
static struct tm *
my_localtime_r (t, tp)
const time_t *t;
struct tm *tp;
{
struct tm *l = localtime (t);
if (! l)
return 0;
*tp = *l;
return tp;
}
/* Yield the difference between (YEAR-YDAY HOUR:MIN:SEC) and (*TP),
measured in seconds, ignoring leap seconds.
YEAR uses the same numbering as TM->tm_year.
All values are in range, except possibly YEAR.
If overflow occurs, yield the low order bits of the correct answer. */
static time_t
ydhms_tm_diff (year, yday, hour, min, sec, tp)
int year, yday, hour, min, sec;
const struct tm *tp;
{
/* Compute intervening leap days correctly even if year is negative.
Take care to avoid int overflow. time_t overflow is OK, since
only the low order bits of the correct time_t answer are needed.
Don't convert to time_t until after all divisions are done, since
time_t might be unsigned. */
int a4 = (year >> 2) + (TM_YEAR_BASE >> 2) - ! (year & 3);
int b4 = (tp->tm_year >> 2) + (TM_YEAR_BASE >> 2) - ! (tp->tm_year & 3);
int a100 = a4 / 25 - (a4 % 25 < 0);
int b100 = b4 / 25 - (b4 % 25 < 0);
int a400 = a100 >> 2;
int b400 = b100 >> 2;
int intervening_leap_days = (a4 - b4) - (a100 - b100) + (a400 - b400);
time_t years = year - (time_t) tp->tm_year;
time_t days = (365 * years + intervening_leap_days
+ (yday - tp->tm_yday));
return (60 * (60 * (24 * days + (hour - tp->tm_hour))
+ (min - tp->tm_min))
+ (sec - tp->tm_sec));
}
static time_t localtime_offset;
/* Convert *TP to a time_t value. */
time_t
mktime (tp)
struct tm *tp;
{
#ifdef _LIBC
/* POSIX.1 8.1.1 requires that whenever mktime() is called, the
time zone names contained in the external variable `tzname' shall
be set as if the tzset() function had been called. */
__tzset ();
#endif
return __mktime_internal (tp, my_localtime_r, &localtime_offset);
}
/* Convert *TP to a time_t value, inverting
the monotonic and mostly-unit-linear conversion function CONVERT.
Use *OFFSET to keep track of a guess at the offset of the result,
compared to what the result would be for UTC without leap seconds.
If *OFFSET's guess is correct, only one CONVERT call is needed. */
time_t
__mktime_internal (tp, convert, offset)
struct tm *tp;
struct tm *(*convert) __P ((const time_t *, struct tm *));
time_t *offset;
{
time_t t, dt, t0;
struct tm tm;
/* The maximum number of probes (calls to CONVERT) should be enough
to handle any combinations of time zone rule changes, solar time,
and leap seconds. Posix.1 prohibits leap seconds, but some hosts
have them anyway. */
int remaining_probes = 4;
/* Time requested. Copy it in case CONVERT modifies *TP; this can
occur if TP is localtime's returned value and CONVERT is localtime. */
int sec = tp->tm_sec;
int min = tp->tm_min;
int hour = tp->tm_hour;
int mday = tp->tm_mday;
int mon = tp->tm_mon;
int year_requested = tp->tm_year;
int isdst = tp->tm_isdst;
/* Ensure that mon is in range, and set year accordingly. */
int mon_remainder = mon % 12;
int negative_mon_remainder = mon_remainder < 0;
int mon_years = mon / 12 - negative_mon_remainder;
int year = year_requested + mon_years;
/* The other values need not be in range:
the remaining code handles minor overflows correctly,
assuming int and time_t arithmetic wraps around.
Major overflows are caught at the end. */
/* Calculate day of year from year, month, and day of month.
The result need not be in range. */
int yday = ((__mon_yday[__isleap (year + TM_YEAR_BASE)]
[mon_remainder + 12 * negative_mon_remainder])
+ mday - 1);
#if LEAP_SECONDS_POSSIBLE
/* Handle out-of-range seconds specially,
since ydhms_tm_diff assumes every minute has 60 seconds. */
int sec_requested = sec;
if (sec < 0)
sec = 0;
if (59 < sec)
sec = 59;
#endif
/* Invert CONVERT by probing. First assume the same offset as last time.
Then repeatedly use the error to improve the guess. */
tm.tm_year = EPOCH_YEAR - TM_YEAR_BASE;
tm.tm_yday = tm.tm_hour = tm.tm_min = tm.tm_sec = 0;
t0 = ydhms_tm_diff (year, yday, hour, min, sec, &tm);
for (t = t0 + *offset;
(dt = ydhms_tm_diff (year, yday, hour, min, sec, (*convert) (&t, &tm)));
t += dt)
if (--remaining_probes == 0)
return -1;
/* Check whether tm.tm_isdst has the requested value, if any. */
if (0 <= isdst && 0 <= tm.tm_isdst)
{
int dst_diff = (isdst != 0) - (tm.tm_isdst != 0);
if (dst_diff)
{
/* Move two hours in the direction indicated by the disagreement,
probe some more, and switch to a new time if found.
The largest known fallback due to daylight savings is two hours:
once, in Newfoundland, 1988-10-30 02:00 -> 00:00. */
time_t ot = t - 2 * 60 * 60 * dst_diff;
while (--remaining_probes != 0)
{
struct tm otm;
if (! (dt = ydhms_tm_diff (year, yday, hour, min, sec,
(*convert) (&ot, &otm))))
{
t = ot;
tm = otm;
break;
}
if ((ot += dt) == t)
break; /* Avoid a redundant probe. */
}
}
}
*offset = t - t0;
#if LEAP_SECONDS_POSSIBLE
if (sec_requested != tm.tm_sec)
{
/* Adjust time to reflect the tm_sec requested, not the normalized value.
Also, repair any damage from a false match due to a leap second. */
t += sec_requested - sec + (sec == 0 && tm.tm_sec == 60);
(*convert) (&t, &tm);
}
#endif
if (TIME_T_MAX / INT_MAX / 366 / 24 / 60 / 60 < 3)
{
/* time_t isn't large enough to rule out overflows in ydhms_tm_diff,
so check for major overflows. A gross check suffices,
since if t has overflowed, it is off by a multiple of
TIME_T_MAX - TIME_T_MIN + 1. So ignore any component of
the difference that is bounded by a small value. */
double dyear = (double) year_requested + mon_years - tm.tm_year;
double dday = 366 * dyear + mday;
double dsec = 60 * (60 * (24 * dday + hour) + min) + sec_requested;
if (TIME_T_MAX / 3 - TIME_T_MIN / 3 < (dsec < 0 ? - dsec : dsec))
return -1;
}
*tp = tm;
return t;
}
#ifdef weak_alias
weak_alias (mktime, timelocal)
#endif
#if DEBUG
static int
not_equal_tm (a, b)
struct tm *a;
struct tm *b;
{
return ((a->tm_sec ^ b->tm_sec)
| (a->tm_min ^ b->tm_min)
| (a->tm_hour ^ b->tm_hour)
| (a->tm_mday ^ b->tm_mday)
| (a->tm_mon ^ b->tm_mon)
| (a->tm_year ^ b->tm_year)
| (a->tm_mday ^ b->tm_mday)
| (a->tm_yday ^ b->tm_yday)
| (a->tm_isdst ^ b->tm_isdst));
}
static void
print_tm (tp)
struct tm *tp;
{
printf ("%04d-%02d-%02d %02d:%02d:%02d yday %03d wday %d isdst %d",
tp->tm_year + TM_YEAR_BASE, tp->tm_mon + 1, tp->tm_mday,
tp->tm_hour, tp->tm_min, tp->tm_sec,
tp->tm_yday, tp->tm_wday, tp->tm_isdst);
}
static int
check_result (tk, tmk, tl, tml)
time_t tk;
struct tm tmk;
time_t tl;
struct tm tml;
{
if (tk != tl || not_equal_tm (&tmk, &tml))
{
printf ("mktime (");
print_tm (&tmk);
printf (")\nyields (");
print_tm (&tml);
printf (") == %ld, should be %ld\n", (long) tl, (long) tk);
return 1;
}
return 0;
}
int
main (argc, argv)
int argc;
char **argv;
{
int status = 0;
struct tm tm, tmk, tml;
time_t tk, tl;
char trailer;
if ((argc == 3 || argc == 4)
&& (sscanf (argv[1], "%d-%d-%d%c",
&tm.tm_year, &tm.tm_mon, &tm.tm_mday, &trailer)
== 3)
&& (sscanf (argv[2], "%d:%d:%d%c",
&tm.tm_hour, &tm.tm_min, &tm.tm_sec, &trailer)
== 3))
{
tm.tm_year -= TM_YEAR_BASE;
tm.tm_mon--;
tm.tm_isdst = argc == 3 ? -1 : atoi (argv[3]);
tmk = tm;
tl = mktime (&tmk);
tml = *localtime (&tl);
printf ("mktime returns %ld == ", (long) tl);
print_tm (&tmk);
printf ("\n");
status = check_result (tl, tmk, tl, tml);
}
else if (argc == 4 || (argc == 5 && strcmp (argv[4], "-") == 0))
{
time_t from = atol (argv[1]);
time_t by = atol (argv[2]);
time_t to = atol (argv[3]);
if (argc == 4)
for (tl = from; tl <= to; tl += by)
{
tml = *localtime (&tl);
tmk = tml;
tk = mktime (&tmk);
status |= check_result (tk, tmk, tl, tml);
}
else
for (tl = from; tl <= to; tl += by)
{
/* Null benchmark. */
tml = *localtime (&tl);
tmk = tml;
tk = tl;
status |= check_result (tk, tmk, tl, tml);
}
}
else
printf ("Usage:\
\t%s YYYY-MM-DD HH:MM:SS [ISDST] # Test given time.\n\
\t%s FROM BY TO # Test values FROM, FROM+BY, ..., TO.\n\
\t%s FROM BY TO - # Do not test those values (for benchmark).\n",
argv[0], argv[0], argv[0]);
return status;
}
#endif /* DEBUG */
/*
Local Variables:
compile-command: "gcc -DDEBUG=1 -Wall -O -g mktime.c -o mktime"
End:
*/
+3
View File
@@ -34,6 +34,9 @@
extern int errno;
#endif
extern ssize_t zread __P((int, char *, size_t));
extern ssize_t zreadc __P((int, char *));
/* Initial memory allocation for automatic growing buffer in zreadlinec */
#define GET_LINE_INITIAL_ALLOCATION 16
+112
View File
@@ -0,0 +1,112 @@
/* zgetline - read a line of input from a specified file descriptor and return
a pointer to a newly-allocated buffer containing the data. */
/* Copyright (C) 2008 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>
#include <sys/types.h>
#if defined (HAVE_UNISTD_H)
# include <unistd.h>
#endif
#include <errno.h>
#include "xmalloc.h"
#if !defined (errno)
extern int errno;
#endif
/* Initial memory allocation for automatic growing buffer in zreadlinec */
#define GET_LINE_INITIAL_ALLOCATION 16
/* Derived from GNU libc's getline.
The behavior is almost the same as getline. See man getline.
The differences are
(1) using file descriptor instead of FILE *,
(2) the order of arguments; the file descriptor comes the first, and
(3) the addtion of thired argument, UNBUFFERED_READ; this argument
controls whether get_line uses buffering or not to get a byte data
from FD. get_line uses zreadc if UNBUFFERED_READ is zero; and
uses zread if UNBUFFERED_READ is non-zero.
Returns number of bytes read or -1 on error. */
ssize_t
zgetline (fd, lineptr, n, unbuffered_read)
int fd;
char **lineptr;
size_t *n;
int unbuffered_read;
{
int nr, retval;
char *line, c;
if (lineptr == 0 || n == 0 || (*lineptr == 0 && *n != 0))
return -1;
nr = 0;
line = *lineptr;
while (1)
{
retval = unbuffered_read ? zread (fd, &c, 1) : zreadc(fd, &c);
if (retval <= 0)
{
line[nr] = '\0';
break;
}
if (nr + 2 >= *n)
{
size_t new_size;
new_size = (*n == 0) ? GET_LINE_INITIAL_ALLOCATION : *n * 2;
line = xrealloc (*lineptr, new_size);
if (line)
{
*lineptr = line;
*n = new_size;
}
else
{
if (*n > 0)
{
(*lineptr)[*n - 1] = '\0';
nr = *n - 2;
}
break;
}
}
line[nr] = c;
nr++;
if (c == '\n')
{
line[nr] = '\0';
break;
}
}
return nr - 1;
}
+1 -1
View File
@@ -518,7 +518,7 @@ it_init_joblist (itp, jstate)
JOB *j;
JOB_STATE ws; /* wanted state */
ws = -1;
ws = JNONE;
if (jstate == 0)
ws = JRUNNING;
else if (jstate == 1)
+13 -13
View File
@@ -1,23 +1,22 @@
/* pcomplete.c - functions to generate lists of matches for programmable
completion. */
/* pcomplete.c - functions to generate lists of matches for programmable completion. */
/* Copyright (C) 1999-2008 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 2, or (at your option) any later
version.
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.
Bash is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with Bash; see the file COPYING. If not, write to the Free Software
Foundation, 59 Temple Place, Suite 330, Boston, MA 02111 USA. */
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>
@@ -519,6 +518,7 @@ it_init_joblist (itp, jstate)
JOB *j;
JOB_STATE ws; /* wanted state */
ws = -1;
if (jstate == 0)
ws = JRUNNING;
else if (jstate == 1)
+1584 -1199
View File
File diff suppressed because it is too large Load Diff
+800 -1549
View File
File diff suppressed because it is too large Load Diff
+929 -283
View File
File diff suppressed because it is too large Load Diff
+1527 -3299
View File
File diff suppressed because it is too large Load Diff
+3
View File
@@ -53,6 +53,8 @@
#include "builtins/getopt.h"
#include "builtins/common.h"
#include "builtins/builtext.h"
#include <tilde/tilde.h>
#include <glob/strmatch.h>
@@ -2758,6 +2760,7 @@ expand_assignment_string_to_string (string, quoted)
char *
expand_arith_string (string, quoted)
char *string;
int quoted;
{
return (expand_string_if_necessary (string, quoted, expand_string));
}
+7
View File
@@ -2758,6 +2758,7 @@ expand_assignment_string_to_string (string, quoted)
char *
expand_arith_string (string, quoted)
char *string;
int quoted;
{
return (expand_string_if_necessary (string, quoted, expand_string));
}
@@ -6616,6 +6617,10 @@ parameter_brace_expand (string, indexp, quoted, quoted_dollar_atp, contains_doll
ret = alloc_word_desc ();
ret->word = temp1;
ret = alloc_word_desc ();
ret->word = temp1;
if (temp1 && QUOTED_NULL (temp1) && (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)))
ret->flags |= W_QUOTED|W_HASQUOTEDNULL;
return ret;
}
#if defined (CASEMOD_EXPANSIONS)
@@ -6633,6 +6638,8 @@ parameter_brace_expand (string, indexp, quoted, quoted_dollar_atp, contains_doll
ret = alloc_word_desc ();
ret->word = temp1;
if (temp1 && QUOTED_NULL (temp1) && (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)))
ret->flags |= W_QUOTED|W_HASQUOTEDNULL;
return ret;
}
#endif
+3
View File
@@ -47,6 +47,9 @@ extern char *optarg;
extern char *dist_version;
extern int patch_level;
extern char *shell_version_string __P((void));
extern void show_shell_version __P((int));
char *shell_name = "bash";
char *progname;
+147
View File
@@ -0,0 +1,147 @@
/* bashversion.c -- Display bash version information. */
/* Copyright (C) 2001 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"
#include "stdc.h"
#include <stdio.h>
#if defined (HAVE_UNISTD_H)
# include <unistd.h>
#endif
#include "bashansi.h"
#include "version.h"
#include "conftypes.h"
#define RFLAG 0x0001
#define VFLAG 0x0002
#define MFLAG 0x0004
#define PFLAG 0x0008
#define SFLAG 0x0010
#define LFLAG 0x0020
#define XFLAG 0x0040
extern int optind;
extern char *optarg;
extern char *dist_version;
extern int patch_level;
extern char *shell_version_string __P((void));
char *shell_name = "bash";
char *progname;
static void
usage()
{
fprintf(stderr, "%s: usage: %s [-hrvpmlsx]\n", progname, progname);
}
int
main (argc, argv)
int argc;
char **argv;
{
int opt, oflags;
char dv[128], *rv;
if (progname = strrchr (argv[0], '/'))
progname++;
else
progname = argv[0];
oflags = 0;
while ((opt = getopt(argc, argv, "hrvmpslx")) != EOF)
{
switch (opt)
{
case 'h':
usage ();
exit (0);
case 'r':
oflags |= RFLAG; /* release */
break;
case 'v':
oflags |= VFLAG; /* version */
break;
case 'm':
oflags |= MFLAG; /* machtype */
break;
case 'p':
oflags |= PFLAG; /* patchlevel */
break;
case 's': /* short version string */
oflags |= SFLAG;
break;
case 'l': /* long version string */
oflags |= LFLAG;
break;
case 'x': /* extended version information */
oflags |= XFLAG;
break;
default:
usage ();
exit (2);
}
}
argc -= optind;
argv += optind;
if (argc > 0)
{
usage ();
exit (2);
}
/* default behavior */
if (oflags == 0)
oflags = SFLAG;
if (oflags & (RFLAG|VFLAG))
{
strcpy (dv, dist_version);
rv = strchr (dv, '.');
if (rv)
*rv++ = '\0';
else
rv = "00";
}
if (oflags & RFLAG)
printf ("%s\n", dv);
else if (oflags & VFLAG)
printf ("%s\n", rv);
else if (oflags & MFLAG)
printf ("%s\n", MACHTYPE);
else if (oflags & PFLAG)
printf ("%d\n", patch_level);
else if (oflags & SFLAG)
printf ("%s\n", shell_version_string ());
else if (oflags & LFLAG)
show_shell_version (0);
else if (oflags & XFLAG)
show_shell_version (1);
exit (0);
}
+3
View File
@@ -60,3 +60,6 @@ argv[2] = <>
argv[3] = <>
FOO
0 0 0
0
0
1
+3
View File
@@ -93,3 +93,6 @@ ${THIS_SH} ./read4.sub
# test behavior when IFS is not the default -- bug through bash-2.05b
${THIS_SH} ./read5.sub
# test behavior of read -t 0
${THIS_SH} ./read6.sub
+95
View File
@@ -0,0 +1,95 @@
echo " a " | (read x; echo "$x.")
echo " a b " | ( read x y ; echo -"$x"-"$y"- )
echo " a b\ " | ( read x y ; echo -"$x"-"$y"- )
echo " a b " | ( read x ; echo -"$x"- )
echo " a b\ " | ( read x ; echo -"$x"- )
echo " a b\ " | ( read -r x y ; echo -"$x"-"$y"- )
echo " a b\ " | ( read -r x ; echo -"$x"- )
echo "\ a b\ " | ( read -r x y ; echo -"$x"-"$y"- )
echo "\ a b\ " | ( read -r x ; echo -"$x"- )
echo " \ a b\ " | ( read -r x y ; echo -"$x"-"$y"- )
echo " \ a b\ " | ( read -r x ; echo -"$x"- )
# make sure that CTLESC and CTLNUL are passed through correctly
echo $'\001' | ( read var ; recho "$var" )
echo $'\001' | ( read ; recho "$REPLY" )
echo $'\177' | ( read var ; recho "$var" )
echo $'\177' | ( read ; recho "$REPLY" )
# make sure a backslash-quoted \\n still disappears from the input when
# we're not reading in `raw' mode, and no stray CTLESC chars are left in
# the input stream
echo $'ab\\\ncd' | ( read ; recho "$REPLY" )
echo "A B " > /tmp/IN
unset x y z
read x y z < /tmp/IN
echo 1: "x[$x] y[$y] z[$z]"
echo 1a: ${z-z not set}
read x < /tmp/IN
echo 2: "x[$x]"
rm /tmp/IN
# this is where the bash `read' behavior with respect to $REPLY differs
# from ksh93
echo "A B " > /tmp/IN
read < /tmp/IN
echo "[$REPLY]"
rm /tmp/IN
echo " A B " > /tmp/IN
read < /tmp/IN
echo "[$REPLY]"
rm /tmp/IN
# make sure that read with more variables than words sets the extra
# variables to the empty string
bvar=bvar
cvar=cvar
echo aa > /tmp/IN
read avar bvar cvar < /tmp/IN
echo =="$avar"==
echo =="$bvar"==
echo =="$cvar"==
rm /tmp/IN
# test behavior of read with various settings of IFS
echo " foo" | { IFS= read line; recho "$line"; }
echo " foo" | { IFS= ; read line; recho "$line"; }
echo " foo" | { unset IFS ; read line; recho "$line"; }
echo " foo" | { IFS=$'\n' ; read line; recho "$line"; }
echo " foo" | { IFS=$' \n' ; read line; recho "$line"; }
echo " foo" | { IFS=$' \t\n' ; read line; recho "$line"; }
echo " foo" | { IFS=$':' ; read line; recho "$line"; }
# test read -d delim behavior
${THIS_SH} ./read1.sub
# test read -t timeout behavior
${THIS_SH} ./read2.sub
# test read -n nchars behavior
${THIS_SH} ./read3.sub
# test read -u fd behavior
${THIS_SH} ./read4.sub
# test behavior when IFS is not the default -- bug through bash-2.05b
${THIS_SH} ./read5.sub
+11
View File
@@ -0,0 +1,11 @@
# test read with a timeout of 0 -- input polling
echo abcde | read -t 0
echo $?
read -t 0 < $0
echo $?
read -t 0
echo $?
+12
View File
@@ -0,0 +1,12 @@
# test read with a timeout of 0 -- input polling
echo abcde | read -t 0
echo $?
read -t 0 < bash
echo $?
read -t 0
echo $?
+1
View File
@@ -38,6 +38,7 @@
#include "shell.h"
#include "flags.h"
#include "input.h" /* for save_token_state, restore_token_state */
#include "jobs.h"
#include "signames.h"
#include "builtins.h"
#include "builtins/common.h"
+12 -13
View File
@@ -1,23 +1,23 @@
/* trap.c -- Not the trap command, but useful functions for manipulating
those objects. The trap command is in builtins/trap.def. */
/* Copyright (C) 1987-2006 Free Software Foundation, Inc.
/* Copyright (C) 1987-2008 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 2, or (at your option) any later
version.
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.
Bash is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with Bash; see the file COPYING. If not, write to the Free Software
Foundation, 59 Temple Place, Suite 330, Boston, MA 02111 USA. */
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"
@@ -357,7 +357,6 @@ trap_handler (sig)
{
int oerrno;
itrace("trap_handler: signal %d", sig);
if ((sigmodes[sig] & SIG_TRAPPED) == 0)
{
#if defined (DEBUG)
+2
View File
@@ -1226,8 +1226,10 @@ brand ()
h = rseed / 127773;
l = rseed % 127773;
rseed = 16807 * l - 2836 * h;
#if 0
if (rseed < 0)
rseed += 0x7fffffff;
#endif
return ((unsigned int)(rseed & 32767)); /* was % 32768 */
#endif
}
+350 -90
View File
@@ -1,22 +1,22 @@
/* variables.c -- Functions for hacking shell variables. */
/* Copyright (C) 1987-2007 Free Software Foundation, Inc.
/* Copyright (C) 1987-2008 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 2, or (at your option)
any later version.
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.
Bash is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Bash; see the file COPYING. If not, write to the Free
Software Foundation, 59 Temple Place, Suite 330, Boston, MA 02111 USA. */
along with Bash. If not, see <http://www.gnu.org/licenses/>.
*/
#include "config.h"
@@ -50,6 +50,7 @@
#include "input.h"
#include "hashcmd.h"
#include "pathexp.h"
#include "alias.h"
#include "builtins/getopt.h"
#include "builtins/common.h"
@@ -169,30 +170,31 @@ static void uidset __P((void));
static void make_vers_array __P((void));
#endif
static SHELL_VAR *null_assign __P((SHELL_VAR *, char *, arrayind_t));
static SHELL_VAR *null_assign __P((SHELL_VAR *, char *, arrayind_t, char *));
#if defined (ARRAY_VARS)
static SHELL_VAR *null_array_assign __P((SHELL_VAR *, char *, arrayind_t));
static SHELL_VAR *null_array_assign __P((SHELL_VAR *, char *, arrayind_t, char *));
#endif
static SHELL_VAR *get_self __P((SHELL_VAR *));
#if defined (ARRAY_VARS)
static SHELL_VAR *init_dynamic_array_var __P((char *, sh_var_value_func_t *, sh_var_assign_func_t *, int));
static SHELL_VAR *init_dynamic_assoc_var __P((char *, sh_var_value_func_t *, sh_var_assign_func_t *, int));
#endif
static SHELL_VAR *assign_seconds __P((SHELL_VAR *, char *, arrayind_t));
static SHELL_VAR *assign_seconds __P((SHELL_VAR *, char *, arrayind_t, char *));
static SHELL_VAR *get_seconds __P((SHELL_VAR *));
static SHELL_VAR *init_seconds_var __P((void));
static int brand __P((void));
static void sbrand __P((unsigned long)); /* set bash random number generator. */
static void seedrand __P((void)); /* seed generator randomly */
static SHELL_VAR *assign_random __P((SHELL_VAR *, char *, arrayind_t));
static SHELL_VAR *assign_random __P((SHELL_VAR *, char *, arrayind_t, char *));
static SHELL_VAR *get_random __P((SHELL_VAR *));
static SHELL_VAR *assign_lineno __P((SHELL_VAR *, char *, arrayind_t));
static SHELL_VAR *assign_lineno __P((SHELL_VAR *, char *, arrayind_t, char *));
static SHELL_VAR *get_lineno __P((SHELL_VAR *));
static SHELL_VAR *assign_subshell __P((SHELL_VAR *, char *, arrayind_t));
static SHELL_VAR *assign_subshell __P((SHELL_VAR *, char *, arrayind_t, char *));
static SHELL_VAR *get_subshell __P((SHELL_VAR *));
static SHELL_VAR *get_bashpid __P((SHELL_VAR *));
@@ -201,13 +203,25 @@ static SHELL_VAR *get_bashpid __P((SHELL_VAR *));
static SHELL_VAR *get_histcmd __P((SHELL_VAR *));
#endif
#if defined (READLINE)
static SHELL_VAR *get_comp_wordbreaks __P((SHELL_VAR *));
static SHELL_VAR *assign_comp_wordbreaks __P((SHELL_VAR *, char *, arrayind_t, char *));
#endif
#if defined (PUSHD_AND_POPD) && defined (ARRAY_VARS)
static SHELL_VAR *assign_dirstack __P((SHELL_VAR *, char *, arrayind_t));
static SHELL_VAR *assign_dirstack __P((SHELL_VAR *, char *, arrayind_t, char *));
static SHELL_VAR *get_dirstack __P((SHELL_VAR *));
#endif
#if defined (ARRAY_VARS)
static SHELL_VAR *get_groupset __P((SHELL_VAR *));
static SHELL_VAR *build_hashcmd __P((SHELL_VAR *));
static SHELL_VAR *get_hashcmd __P((SHELL_VAR *));
static SHELL_VAR *assign_hashcmd __P((SHELL_VAR *, char *, arrayind_t, char *));
static SHELL_VAR *build_aliasvar __P((SHELL_VAR *));
static SHELL_VAR *get_aliasvar __P((SHELL_VAR *));
static SHELL_VAR *assign_aliasvar __P((SHELL_VAR *, char *, arrayind_t, char *));
#endif
static SHELL_VAR *get_funcname __P((SHELL_VAR *));
@@ -220,6 +234,7 @@ static SHELL_VAR *new_shell_variable __P((const char *));
static SHELL_VAR *make_new_variable __P((const char *, HASH_TABLE *));
static SHELL_VAR *bind_variable_internal __P((const char *, char *, HASH_TABLE *, int, int));
static void dispose_variable_value __P((SHELL_VAR *));
static void free_variable_hash_data __P((PTR_T));
static VARLIST *vlist_alloc __P((int));
@@ -941,6 +956,8 @@ print_assignment (var)
#if defined (ARRAY_VARS)
else if (array_p (var))
print_array_assignment (var, 0);
else if (assoc_p (var))
print_assoc_assignment (var, 0);
#endif /* ARRAY_VARS */
else
{
@@ -1052,21 +1069,32 @@ print_var_function (var)
} \
while (0)
#define INIT_DYNAMIC_ASSOC_VAR(var, gfunc, afunc) \
do \
{ \
v = make_new_assoc_variable (var); \
v->dynamic_value = gfunc; \
v->assign_func = afunc; \
} \
while (0)
static SHELL_VAR *
null_assign (self, value, unused)
null_assign (self, value, unused, key)
SHELL_VAR *self;
char *value;
arrayind_t unused;
char *key;
{
return (self);
}
#if defined (ARRAY_VARS)
static SHELL_VAR *
null_array_assign (self, value, ind)
null_array_assign (self, value, ind, key)
SHELL_VAR *self;
char *value;
arrayind_t ind;
char *key;
{
return (self);
}
@@ -1101,8 +1129,25 @@ init_dynamic_array_var (name, getfunc, setfunc, attrs)
VSETATTR (v, attrs);
return v;
}
#endif
static SHELL_VAR *
init_dynamic_assoc_var (name, getfunc, setfunc, attrs)
char *name;
sh_var_value_func_t *getfunc;
sh_var_assign_func_t *setfunc;
int attrs;
{
SHELL_VAR *v;
v = find_variable (name);
if (v)
return (v);
INIT_DYNAMIC_ASSOC_VAR (name, getfunc, setfunc);
if (attrs)
VSETATTR (v, attrs);
return v;
}
#endif
/* The value of $SECONDS. This is the number of seconds since shell
invocation, or, the number of seconds since the last assignment + the
@@ -1110,10 +1155,11 @@ init_dynamic_array_var (name, getfunc, setfunc, attrs)
static intmax_t seconds_value_assigned;
static SHELL_VAR *
assign_seconds (self, value, unused)
assign_seconds (self, value, unused, key)
SHELL_VAR *self;
char *value;
arrayind_t unused;
char *key;
{
if (legal_number (value, &seconds_value_assigned) == 0)
seconds_value_assigned = 0;
@@ -1205,10 +1251,11 @@ seedrand ()
}
static SHELL_VAR *
assign_random (self, value, unused)
assign_random (self, value, unused, key)
SHELL_VAR *self;
char *value;
arrayind_t unused;
char *key;
{
sbrand (strtoul (value, (char **)NULL, 10));
if (subshell_environment)
@@ -1254,10 +1301,11 @@ get_random (var)
}
static SHELL_VAR *
assign_lineno (var, value, unused)
assign_lineno (var, value, unused, key)
SHELL_VAR *var;
char *value;
arrayind_t unused;
char *key;
{
intmax_t new_value;
@@ -1283,10 +1331,11 @@ get_lineno (var)
}
static SHELL_VAR *
assign_subshell (var, value, unused)
assign_subshell (var, value, unused, key)
SHELL_VAR *var;
char *value;
arrayind_t unused;
char *key;
{
intmax_t new_value;
@@ -1329,7 +1378,7 @@ get_bash_command (var)
SHELL_VAR *var;
{
char *p;
if (the_printed_command_except_trap)
p = savestring (the_printed_command_except_trap);
else
@@ -1366,7 +1415,6 @@ get_comp_wordbreaks (var)
if (rl_completer_word_break_characters == 0 && bash_readline_initialized == 0)
enable_hostname_completion (perform_hostname_completion);
itrace("get: rl_completer_word_break_characters = `%s'", rl_completer_word_break_characters);
var_setvalue (var, rl_completer_word_break_characters);
return (var);
@@ -1375,27 +1423,28 @@ itrace("get: rl_completer_word_break_characters = `%s'", rl_completer_word_break
/* When this function returns, rl_completer_word_break_characters points to
malloced memory. */
static SHELL_VAR *
assign_comp_wordbreaks (self, value, unused)
assign_comp_wordbreaks (self, value, unused, key)
SHELL_VAR *self;
char *value;
arrayind_t unused;
char *key;
{
if (rl_completer_word_break_characters &&
rl_completer_word_break_characters != rl_basic_word_break_characters)
free (rl_completer_word_break_characters);
rl_completer_word_break_characters = savestring (value);
itrace("assign: rl_completer_word_break_characters = `%s'", rl_completer_word_break_characters);
return self;
}
#endif /* READLINE */
#if defined (PUSHD_AND_POPD) && defined (ARRAY_VARS)
static SHELL_VAR *
assign_dirstack (self, value, ind)
assign_dirstack (self, value, ind, key)
SHELL_VAR *self;
char *value;
arrayind_t ind;
char *key;
{
set_dirstack_element (ind, 1, value);
return self;
@@ -1438,6 +1487,112 @@ get_groupset (self)
}
return (self);
}
static SHELL_VAR *
build_hashcmd (self)
SHELL_VAR *self;
{
HASH_TABLE *h;
int i;
char *k, *v;
BUCKET_CONTENTS *item;
h = assoc_cell (self);
if (h)
assoc_dispose (h);
if (hashed_filenames == 0 || HASH_ENTRIES (hashed_filenames) == 0)
{
var_setvalue (self, (char *)NULL);
return self;
}
h = assoc_create (hashed_filenames->nbuckets);
for (i = 0; i < hashed_filenames->nbuckets; i++)
{
for (item = hash_items (i, hashed_filenames); item; item = item->next)
{
k = savestring (item->key);
v = pathdata(item)->path;
assoc_insert (h, k, v);
}
}
var_setvalue (self, (char *)h);
return self;
}
static SHELL_VAR *
get_hashcmd (self)
SHELL_VAR *self;
{
build_hashcmd (self);
return (self);
}
static SHELL_VAR *
assign_hashcmd (self, value, ind, key)
SHELL_VAR *self;
char *value;
arrayind_t ind;
char *key;
{
phash_insert (key, value, 0, 0);
return (build_hashcmd (self));
}
static SHELL_VAR *
build_aliasvar (self)
SHELL_VAR *self;
{
HASH_TABLE *h;
int i;
char *k, *v;
BUCKET_CONTENTS *item;
h = assoc_cell (self);
if (h)
assoc_dispose (h);
if (aliases == 0 || HASH_ENTRIES (aliases) == 0)
{
var_setvalue (self, (char *)NULL);
return self;
}
h = assoc_create (aliases->nbuckets);
for (i = 0; i < aliases->nbuckets; i++)
{
for (item = hash_items (i, aliases); item; item = item->next)
{
k = savestring (item->key);
v = ((alias_t *)(item->data))->value;
assoc_insert (h, k, v);
}
}
var_setvalue (self, (char *)h);
return self;
}
static SHELL_VAR *
get_aliasvar (self)
SHELL_VAR *self;
{
build_aliasvar (self);
return (self);
}
static SHELL_VAR *
assign_aliasvar (self, value, ind, key)
SHELL_VAR *self;
char *value;
arrayind_t ind;
char *key;
{
add_alias (key, value);
return (build_aliasvar (self));
}
#endif /* ARRAY_VARS */
/* If ARRAY_VARS is not defined, this just returns the name of any
@@ -1531,6 +1686,9 @@ initialize_dynamic_variables ()
# endif /* DEBUGGER */
v = init_dynamic_array_var ("BASH_SOURCE", get_self, null_array_assign, att_noassign|att_nounset);
v = init_dynamic_array_var ("BASH_LINENO", get_self, null_array_assign, att_noassign|att_nounset);
v = init_dynamic_assoc_var ("BASH_CMDS", get_hashcmd, assign_hashcmd, att_nofree);
v = init_dynamic_assoc_var ("BASH_ALIASES", get_aliasvar, assign_aliasvar, att_nofree);
#endif
v = init_funcname_var ();
@@ -1577,7 +1735,7 @@ var_lookup (name, vcontext)
then also search the temporarily built list of exported variables.
The lookup order is:
temporary_env
shell_variables list
shell_variables list
*/
SHELL_VAR *
@@ -1650,6 +1808,8 @@ get_variable_value (var)
#if defined (ARRAY_VARS)
else if (array_p (var))
return (array_reference (array_cell (var), 0));
else if (assoc_p (var))
return (assoc_reference (assoc_cell (var), "0"));
#endif
else
return (value_cell (var));
@@ -1759,7 +1919,7 @@ make_local_variable (name)
inherit its value. Watch to see if this causes problems with
things like `x=4 local x'. */
if (was_tmpvar)
var_setvalue (new_var, savestring (tmp_value));
var_setvalue (new_var, savestring (tmp_value));
new_var->attributes = exported_p (old_var) ? att_exported : 0;
}
@@ -1775,27 +1935,6 @@ make_local_variable (name)
return (new_var);
}
#if defined (ARRAY_VARS)
SHELL_VAR *
make_local_array_variable (name)
char *name;
{
SHELL_VAR *var;
ARRAY *array;
var = make_local_variable (name);
if (var == 0 || array_p (var))
return var;
array = array_create ();
FREE (value_cell(var));
var_setarray (var, array);
VSETATTR (var, att_array);
return var;
}
#endif /* ARRAY_VARS */
/* Create a new shell variable with name NAME. */
static SHELL_VAR *
new_shell_variable (name)
@@ -1854,10 +1993,64 @@ make_new_array_variable (name)
entry = make_new_variable (name, global_variables->table);
array = array_create ();
var_setarray (entry, array);
VSETATTR (entry, att_array);
return entry;
}
SHELL_VAR *
make_local_array_variable (name)
char *name;
{
SHELL_VAR *var;
ARRAY *array;
var = make_local_variable (name);
if (var == 0 || array_p (var))
return var;
array = array_create ();
dispose_variable_value (var);
var_setarray (var, array);
VSETATTR (var, att_array);
return var;
}
SHELL_VAR *
make_new_assoc_variable (name)
char *name;
{
SHELL_VAR *entry;
HASH_TABLE *hash;
entry = make_new_variable (name, global_variables->table);
hash = assoc_create (0);
var_setassoc (entry, hash);
VSETATTR (entry, att_assoc);
return entry;
}
SHELL_VAR *
make_local_assoc_variable (name)
char *name;
{
SHELL_VAR *var;
HASH_TABLE *hash;
var = make_local_variable (name);
if (var == 0 || assoc_p (var))
return var;
dispose_variable_value (var);
hash = assoc_create (0);
var_setassoc (var, hash);
VSETATTR (var, att_assoc);
return var;
}
#endif
char *
@@ -1868,7 +2061,7 @@ make_variable_value (var, value, flags)
{
char *retval, *oval;
intmax_t lval, rval;
int expok, olen;
int expok, olen, op;
/* If this variable has had its type set to integer (via `declare -i'),
then do expression evaluation on it and store the result. The
@@ -1897,6 +2090,34 @@ make_variable_value (var, value, flags)
rval += lval;
retval = itos (rval);
}
#if defined (CASEMOD_ATTRS)
else if (capcase_p (var) || uppercase_p (var) || lowercase_p (var))
{
if (flags & ASS_APPEND)
{
oval = get_variable_value (var);
if (oval == 0) /* paranoia */
oval = "";
olen = STRLEN (oval);
retval = (char *)xmalloc (olen + (value ? STRLEN (value) : 0) + 1);
strcpy (retval, oval);
if (value)
strcpy (retval+olen, value);
}
else if (*value)
retval = savestring (value);
else
{
retval = (char *)xmalloc (1);
retval[0] = '\0';
}
op = capcase_p (var) ? CASE_CAPITALIZE
: (uppercase_p (var) ? CASE_UPPER : CASE_LOWER);
oval = sh_modcase (retval, (char *)0, op);
free (retval);
retval = oval;
}
#endif /* CASEMOD_ATTRS */
else if (value)
{
if (flags & ASS_APPEND)
@@ -1947,9 +2168,9 @@ bind_variable_internal (name, value, table, hflags, aflags)
{
INVALIDATE_EXPORTSTR (entry);
newval = (aflags & ASS_APPEND) ? make_variable_value (entry, value, aflags) : value;
entry = (*(entry->assign_func)) (entry, newval, -1);
entry = (*(entry->assign_func)) (entry, newval, -1, 0);
if (newval != value)
free (newval);
free (newval);
return (entry);
}
else
@@ -1979,6 +2200,11 @@ bind_variable_internal (name, value, table, hflags, aflags)
array_insert (array_cell (entry), 0, newval);
free (newval);
}
else if (assoc_p (entry))
{
assoc_insert (assoc_cell (entry), "0", newval);
free (newval);
}
else
#endif
{
@@ -2024,11 +2250,11 @@ bind_variable (name, value, flags)
for (vc = shell_variables; vc; vc = vc->down)
{
if (vc_isfuncenv (vc) || vc_isbltnenv (vc))
{
v = hash_lookup (name, vc->table);
if (v)
{
v = hash_lookup (name, vc->table);
if (v)
return (bind_variable_internal (name, value, vc->table, 0, flags));
}
}
}
return (bind_variable_internal (name, value, global_variables->table, 0, flags));
}
@@ -2053,7 +2279,7 @@ bind_variable_value (var, value, aflags)
/* If we're appending, we need the old value, so use
make_variable_value */
t = (aflags & ASS_APPEND) ? make_variable_value (var, value, aflags) : value;
(*(var->assign_func)) (var, t, -1);
(*(var->assign_func)) (var, t, -1, 0);
if (t != value && t)
free (t);
}
@@ -2311,7 +2537,9 @@ copy_variable (var)
var_setfunc (copy, copy_command (function_cell (var)));
#if defined (ARRAY_VARS)
else if (array_p (var))
var_setarray (copy, dup_array (array_cell (var)));
var_setarray (copy, array_copy (array_cell (var)));
else if (assoc_p (var))
var_setassoc (copy, assoc_copy (assoc_cell (var)));
#endif
else if (value_cell (var))
var_setvalue (copy, savestring (value_cell (var)));
@@ -2336,6 +2564,22 @@ copy_variable (var)
/* **************************************************************** */
/* Dispose of the information attached to VAR. */
static void
dispose_variable_value (var)
SHELL_VAR *var;
{
if (function_p (var))
dispose_command (function_cell (var));
#if defined (ARRAY_VARS)
else if (array_p (var))
array_dispose (array_cell (var));
else if (assoc_p (var))
assoc_dispose (assoc_cell (var));
#endif
else
FREE (value_cell (var));
}
void
dispose_variable (var)
SHELL_VAR *var;
@@ -2343,14 +2587,8 @@ dispose_variable (var)
if (var == 0)
return;
if (function_p (var))
dispose_command (function_cell (var));
#if defined (ARRAY_VARS)
else if (array_p (var))
array_dispose (array_cell (var));
#endif
else
FREE (value_cell (var));
if (nofree_p (var) == 0)
dispose_variable_value (var);
FREE_EXPORTSTR (var);
@@ -2459,15 +2697,19 @@ makunbound (name, vc)
We also need to add it back into the correct hash table. */
if (old_var && local_p (old_var) && variable_context == old_var->context)
{
if (nofree_p (old_var))
var_setvalue (old_var, (char *)NULL);
#if defined (ARRAY_VARS)
if (array_p (old_var))
else if (array_p (old_var))
array_dispose (array_cell (old_var));
else
else if (assoc_p (old_var))
assoc_dispose (assoc_cell (old_var));
#endif
else
FREE (value_cell (old_var));
/* Reset the attributes. Preserve the export attribute if the variable
came from a temporary environment. Make sure it stays local, and
make it invisible. */
came from a temporary environment. Make sure it stays local, and
make it invisible. */
old_var->attributes = (exported_p (old_var) && tempvar_p (old_var)) ? att_exported : 0;
VSETATTR (old_var, att_local);
VSETATTR (old_var, att_invisible);
@@ -3030,7 +3272,7 @@ dispose_temporary_env (pushf)
{
hash_flush (temporary_env, pushf);
hash_dispose (temporary_env);
temporary_env = (HASH_TABLE *)NULL;
temporary_env = (HASH_TABLE *)NULL;
array_needs_making = 1;
@@ -3142,6 +3384,12 @@ make_env_array_from_var_list (vars)
value = array_to_assignment_string (array_cell (var));
# else
continue; /* XXX array vars cannot yet be exported */
# endif
else if (assoc_p (var))
# if 0
value = assoc_to_assignment_string (assoc_cell (var));
# else
continue; /* XXX associative array vars cannot yet be exported */
# endif
#endif
else
@@ -3162,7 +3410,7 @@ make_env_array_from_var_list (vars)
#if 0 /* not yet */
#if defined (ARRAY_VARS)
if (array_p (var))
if (array_p (var) || assoc_p (var))
free (value);
#endif
#endif
@@ -3316,7 +3564,7 @@ maybe_make_export_env ()
if (array_needs_making)
{
if (export_env)
strvec_flush (export_env);
strvec_flush (export_env);
/* Make a guess based on how many shell variables and functions we
have. Since there will always be array variables, and array
@@ -3333,24 +3581,24 @@ maybe_make_export_env ()
export_env[export_env_index = 0] = (char *)NULL;
/* Make a dummy variable context from the temporary_env, stick it on
the front of shell_variables, call make_var_export_array on the
whole thing to flatten it, and convert the list of SHELL_VAR *s
to the form needed by the environment. */
the front of shell_variables, call make_var_export_array on the
whole thing to flatten it, and convert the list of SHELL_VAR *s
to the form needed by the environment. */
if (temporary_env)
{
tcxt = new_var_context ((char *)NULL, 0);
tcxt->table = temporary_env;
tcxt->down = shell_variables;
}
{
tcxt = new_var_context ((char *)NULL, 0);
tcxt->table = temporary_env;
tcxt->down = shell_variables;
}
else
tcxt = shell_variables;
tcxt = shell_variables;
temp_array = make_var_export_array (tcxt);
if (temp_array)
add_temp_array_to_env (temp_array, 0, 0);
if (tcxt != shell_variables)
free (tcxt);
free (tcxt);
#if defined (RESTRICTED_SHELL)
/* Restricted shells may not export shell functions. */
@@ -3517,7 +3765,7 @@ push_func_var (data)
if (shell_variables == global_variables)
var->attributes &= ~(att_tempvar|att_propagate);
else
shell_variables->flags |= VC_HASTMPVAR;
shell_variables->flags |= VC_HASTMPVAR;
v->attributes |= var->attributes;
}
else
@@ -3564,7 +3812,7 @@ delete_all_contexts (vcxt)
{
t = v->down;
dispose_var_context (v);
}
}
delete_all_variables (global_variables->table);
shell_variables = global_variables;
@@ -3900,7 +4148,7 @@ find_special_var (name)
else if (r > 0)
/* Can't match any of rest of elements in sorted list. Take this out
if it causes problems in certain environments. */
break;
break;
}
return -1;
}
@@ -3926,6 +4174,18 @@ stupidly_hack_special_variables (name)
(*(special_vars[i].function)) (name);
}
/* Special variables that need hooks to be run when they are unset as part
of shell reinitialization should have their sv_ functions run here. */
void
reinit_special_variables ()
{
#if defined (READLINE)
sv_comp_wordbreaks ("COMP_WORDBREAKS");
#endif
sv_globignore ("GLOBIGNORE");
sv_opterr ("OPTERR");
}
void
sv_ifs (name)
char *name;