mirror of
https://https.git.savannah.gnu.org/git/bash.git
synced 2026-06-23 05:47:59 +02:00
commit bash-20080904 snapshot
This commit is contained in:
@@ -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>
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -30,6 +30,7 @@
|
||||
#include "bashintl.h"
|
||||
|
||||
#include "shell.h"
|
||||
#include "pathexp.h"
|
||||
|
||||
#include "shmbutil.h"
|
||||
|
||||
|
||||
+13
-18
@@ -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;
|
||||
|
||||
@@ -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),
|
||||
|
||||
@@ -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++;
|
||||
|
||||
@@ -294,6 +294,7 @@ sh_wrerror ()
|
||||
|
||||
int
|
||||
sh_chkwrite (s)
|
||||
int s;
|
||||
{
|
||||
fflush (stdout);
|
||||
if (ferror (stdout))
|
||||
|
||||
+36
-26
@@ -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 */
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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.
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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
|
||||
|
||||
@@ -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
@@ -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 *));
|
||||
|
||||
|
||||
@@ -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
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
@@ -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
|
||||
|
||||
|
||||
@@ -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
@@ -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')
|
||||
|
||||
@@ -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 */
|
||||
@@ -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
@@ -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
@@ -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 */
|
||||
|
||||
@@ -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:
|
||||
*/
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
@@ -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
@@ -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)
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
@@ -60,3 +60,6 @@ argv[2] = <>
|
||||
argv[3] = <>
|
||||
FOO
|
||||
0 0 0
|
||||
0
|
||||
0
|
||||
1
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
@@ -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 $?
|
||||
|
||||
@@ -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 $?
|
||||
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user