mirror of
https://https.git.savannah.gnu.org/git/bash.git
synced 2026-06-30 08:59:56 +02:00
commit bash-20071206 snapshot
This commit is contained in:
@@ -15049,3 +15049,55 @@ configure.in
|
||||
doc/{bash.1,bashref.texi}
|
||||
- slight change to the text describing the effect of set -e when
|
||||
in a || or && list
|
||||
|
||||
12/5
|
||||
----
|
||||
jobs.c
|
||||
- fix raw_job_exit_status to correct mixing of int/WAIT values (need
|
||||
to return a WAIT)
|
||||
- arrange so that children run as part of command substitutions also
|
||||
set the SIGINT handler to wait_sigint_handler, since they effectively
|
||||
don't do job control
|
||||
- in wait_for, if a child run as part of a command substitution exits
|
||||
due to SIGINT, resend the SIGINT to the waiting shell with kill(2).
|
||||
This makes sure the exit status propagates
|
||||
|
||||
doc/{bash.1,bashref.texi}
|
||||
- tighten up the language describing when bash tries to see if its
|
||||
stdin is a socket, so it can run the startup files. Suggested by
|
||||
Vincent Lefevre <vincent@vinc17.org>
|
||||
|
||||
eval.c
|
||||
- in the DISCARD case of a longjmp to top_level, make sure
|
||||
last_command_exit_value is set to EXECUTION_FAILURE if it's 0,
|
||||
but leave existing non-zero values alone
|
||||
|
||||
subst.c
|
||||
- in command_substitute, don't reset pipeline_pgrp in the child
|
||||
process -- this means that second and subsequent children spawned by
|
||||
this comsub shell get put into the wrong process group, not the
|
||||
shell's. Fix for bug reported by Ingo Molnar <mingo@elte.hu>
|
||||
|
||||
12/6
|
||||
----
|
||||
support/shobj-conf
|
||||
- make sure the cases for darwin8.x (Mac OS X 10.4.x) are extended to
|
||||
darwin9.x (Mac OS X 10.5.x). Fixes problem originally reported
|
||||
against readline-5.2 by schneecrash@gmail.com
|
||||
|
||||
12/8
|
||||
----
|
||||
subst.c
|
||||
- make sure to add the results of (successful) tilde expansion as a
|
||||
quoted string, to inhibit pathname expansion and word splitting.
|
||||
From recent Austin Group interpretation.
|
||||
|
||||
include/shtty.h, lib/sh/shtty.c
|
||||
- add ttfd_onechar, ttfd_noecho, ttfd_eightbit, ttfd_nocanon, and
|
||||
ttfd_cbreak to set tty attributes associated with a particular
|
||||
file descriptor (which is presumed to point to a terminal)
|
||||
|
||||
lib/readline/display.c
|
||||
- make sure we only use rl_invis_chars_first_line when the number of
|
||||
physical characters exceeds the screen width, since that's the
|
||||
only time expand_prompt sets it to a valid value
|
||||
|
||||
+53
-1
@@ -14999,7 +14999,7 @@ execute_cmd.c
|
||||
----
|
||||
builtins/read.def
|
||||
- make sure the return value from get_word_from_string is freed if
|
||||
non-null. Fixes bug reported by Lars Ellenberg
|
||||
non-null. Fixes memory leak bug reported by Lars Ellenberg
|
||||
<lars.ellenberg@linbit.com>
|
||||
|
||||
11/10
|
||||
@@ -15049,3 +15049,55 @@ configure.in
|
||||
doc/{bash.1,bashref.texi}
|
||||
- slight change to the text describing the effect of set -e when
|
||||
in a || or && list
|
||||
|
||||
12/5
|
||||
----
|
||||
jobs.c
|
||||
- fix raw_job_exit_status to correct mixing of int/WAIT values (need
|
||||
to return a WAIT)
|
||||
- arrange so that children run as part of command substitutions also
|
||||
set the SIGINT handler to wait_sigint_handler, since they effectively
|
||||
don't do job control
|
||||
- in wait_for, if a child run as part of a command substitution exits
|
||||
due to SIGINT, resend the SIGINT to the waiting shell with kill(2).
|
||||
This makes sure the exit status propagates
|
||||
|
||||
doc/{bash.1,bashref.texi}
|
||||
- tighten up the language describing when bash tries to see if its
|
||||
stdin is a socket, so it can run the startup files. Suggested by
|
||||
Vincent Lefevre <vincent@vinc17.org>
|
||||
|
||||
eval.c
|
||||
- in the DISCARD case of a longjmp to top_level, make sure
|
||||
last_command_exit_value is set to EXECUTION_FAILURE if it's 0,
|
||||
but leave existing non-zero values alone
|
||||
|
||||
subst.c
|
||||
- in command_substitute, don't reset pipeline_pgrp in the child
|
||||
process -- this means that second and subsequent children spawned by
|
||||
this comsub shell get put into the wrong process group, not the
|
||||
shell's. Fix for bug reported by Ingo Molnar <mingo@elte.hu>
|
||||
|
||||
12/6
|
||||
----
|
||||
support/shobj-conf
|
||||
- make sure the cases for darwin8.x (Mac OS X 10.4.x) are extended to
|
||||
darwin9.x (Mac OS X 10.5.x). Fixes problem originally reported
|
||||
against readline-5.2 by schneecrash@gmail.com
|
||||
|
||||
12/8
|
||||
----
|
||||
subst.c
|
||||
- make sure to add the results of (successful) tilde expansion as a
|
||||
quoted string, to inhibit pathname expansion and word splitting.
|
||||
From recent Austin Group interpretation.
|
||||
|
||||
include/shtty.h, lib/sh/shtty.c
|
||||
- add ttfd_onechar, ttfd_noecho, ttfd_eightbit, ttfd_nocanon, and
|
||||
ttfd_cbreak to set tty attributes associated with a particular
|
||||
file descriptor (which is presumed to point to the terminal)
|
||||
|
||||
lib/readline/display.c
|
||||
- make sure we only use rl_invis_chars_first_line when the number of
|
||||
physical characters exceeds the screen width, since that's the
|
||||
only time expand_prompt sets it to a valid value
|
||||
|
||||
+3
-1
@@ -88,5 +88,7 @@
|
||||
/* #define NON_INTERACTIVE_LOGIN_SHELLS */
|
||||
|
||||
/* Define this if you want bash to try to check whether it's being run by
|
||||
sshd and source the .bashrc if so (like the rshd behavior). */
|
||||
sshd and source the .bashrc if so (like the rshd behavior). This checks
|
||||
for the presence of SSH_CLIENT or SSH2_CLIENT in the initial environment,
|
||||
which can be fooled under certain not-uncommon circumstances. */
|
||||
/* #define SSH_SOURCE_BASHRC */
|
||||
|
||||
+1
-1
@@ -3,7 +3,7 @@
|
||||
/* This contains various user-settable options not under the control of
|
||||
autoconf. */
|
||||
|
||||
/* Copyright (C) 2002 Free Software Foundation, Inc.
|
||||
/* Copyright (C) 2002-2007 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Bash, the Bourne Again SHell.
|
||||
|
||||
|
||||
+6
-6
@@ -5,13 +5,12 @@
|
||||
.\" Case Western Reserve University
|
||||
.\" chet@po.cwru.edu
|
||||
.\"
|
||||
.\" Last Change: Wed Nov 21 22:39:33 EST 2007
|
||||
|
||||
.\" Last Change: Wed Dec 5 22:08:48 EST 2007
|
||||
.\"
|
||||
.\" bash_builtins, strip all but Built-Ins section
|
||||
.if \n(zZ=1 .ig zZ
|
||||
.if \n(zY=1 .ig zY
|
||||
.TH BASH 1 "2007 November 21" "GNU Bash-3.2"
|
||||
.TH BASH 1 "2007 December 5" "GNU Bash-3.2"
|
||||
.\"
|
||||
.\" There's some problem with having a `@'
|
||||
.\" in a tagged paragraph with the BSD man macros.
|
||||
@@ -410,11 +409,12 @@ whose name is the expanded value.
|
||||
No other startup files are read.
|
||||
.PP
|
||||
.B Bash
|
||||
attempts to determine when it is being run by the remote shell
|
||||
daemon, usually \fIrshd\fP.
|
||||
attempts to determine when it is being run with its standard input
|
||||
connected to a a network connection, as if by the remote shell
|
||||
daemon, usually \fIrshd\fP, or the secure shell daemon \fIsshd\fP.
|
||||
If
|
||||
.B bash
|
||||
determines it is being run by \fIrshd\fP, it reads and executes
|
||||
determines it is being run in this fashion, it reads and executes
|
||||
commands from \fI~/.bashrc\fP, if that file exists and is readable.
|
||||
It will not do this if invoked as \fBsh\fP.
|
||||
The
|
||||
|
||||
+5
-3
@@ -5158,9 +5158,11 @@ No other startup files are read.
|
||||
|
||||
@subsubheading Invoked by remote shell daemon
|
||||
|
||||
Bash attempts to determine when it is being run by the remote shell
|
||||
daemon, usually @code{rshd}. If Bash determines it is being run by
|
||||
rshd, it reads and executes commands from @file{~/.bashrc}, if that
|
||||
Bash attempts to determine when it is being run with its standard input
|
||||
connected to a a network connection, as if by the remote shell
|
||||
daemon, usually @code{rshd}, or the secure shell daemon @code{sshd}.
|
||||
If Bash determines it is being run in
|
||||
this fashion, it reads and executes commands from @file{~/.bashrc}, if that
|
||||
file exists and is readable.
|
||||
It will not do this if invoked as @code{sh}.
|
||||
The @option{--norc} option may be used to inhibit this behavior, and the
|
||||
|
||||
+3
-3
@@ -2,9 +2,9 @@
|
||||
Copyright (C) 1988-2007 Free Software Foundation, Inc.
|
||||
@end ignore
|
||||
|
||||
@set LASTCHANGE Wed Nov 21 22:41:34 EST 2007
|
||||
@set LASTCHANGE Wed Dec 5 22:08:02 EST 2007
|
||||
|
||||
@set EDITION 3.2
|
||||
@set VERSION 3.2
|
||||
@set UPDATED 21 November 2007
|
||||
@set UPDATED-MONTH November 2007
|
||||
@set UPDATED 5 December 2007
|
||||
@set UPDATED-MONTH December 2007
|
||||
|
||||
@@ -100,7 +100,11 @@ reader_loop ()
|
||||
goto exec_done;
|
||||
|
||||
case DISCARD:
|
||||
last_command_exit_value = 1;
|
||||
/* Make sure the exit status is reset to a non-zero value, but
|
||||
leave existing non-zero values (e.g., > 128 on signal)
|
||||
alone. */
|
||||
if (last_command_exit_value == 0)
|
||||
last_command_exit_value = EXECUTION_FAILURE;
|
||||
if (subshell_environment)
|
||||
{
|
||||
current_command = (COMMAND *)NULL;
|
||||
|
||||
@@ -714,7 +714,6 @@ execute_command_internal (command, asynchronous, pipe_in, pipe_out,
|
||||
subshells forked to execute builtin commands (e.g., in
|
||||
pipelines) to be waited for twice. */
|
||||
exec_result = wait_for (last_made_pid);
|
||||
itrace("execute_command_internal: wait_for (%d) = %d", last_made_pid, exec_result);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -894,7 +893,6 @@ itrace("execute_command_internal: wait_for (%d) = %d", last_made_pid, exec_resul
|
||||
#endif
|
||||
|
||||
last_command_exit_value = exec_result;
|
||||
itrace("execute_command_internal: last_command_exit_value -> %d last_command_exit_signal = %d", last_command_exit_value, last_command_exit_signal);
|
||||
run_pending_traps ();
|
||||
#if 0
|
||||
if (running_trap == 0)
|
||||
|
||||
@@ -91,6 +91,17 @@ extern int tt_setcbreak __P((TTYSTRUCT *));
|
||||
course), the right thing will happen, but more system calls will be
|
||||
executed than absolutely necessary. You can do all of this yourself
|
||||
with the other functions; these are only conveniences. */
|
||||
|
||||
/* These functions work with a given file descriptor and set terminal
|
||||
attributes */
|
||||
extern int ttfd_onechar __P((int, TTYSTRUCT *));
|
||||
extern int ttfd_noecho __P((int, TTYSTRUCT *));
|
||||
extern int ttfd_eightbit __P((int, TTYSTRUCT *));
|
||||
extern int ttfd_nocanon __P((int, TTYSTRUCT *));
|
||||
|
||||
extern int ttfd_cbreak __P((int, TTYSTRUCT *));
|
||||
|
||||
/* These functions work with fd 0 and the TTYSTRUCT saved with ttsave () */
|
||||
extern int ttonechar __P((void));
|
||||
extern int ttnoecho __P((void));
|
||||
extern int tteightbit __P((void));
|
||||
|
||||
@@ -0,0 +1,112 @@
|
||||
/* Copyright (C) 1999 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 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. */
|
||||
|
||||
/*
|
||||
* shtty.h -- include the correct system-dependent files to manipulate the
|
||||
* tty
|
||||
*/
|
||||
|
||||
#ifndef __SH_TTY_H_
|
||||
#define __SH_TTY_H_
|
||||
|
||||
#include "stdc.h"
|
||||
|
||||
#if defined (_POSIX_VERSION) && defined (HAVE_TERMIOS_H) && defined (HAVE_TCGETATTR) && !defined (TERMIOS_MISSING)
|
||||
# define TERMIOS_TTY_DRIVER
|
||||
#else
|
||||
# if defined (HAVE_TERMIO_H)
|
||||
# define TERMIO_TTY_DRIVER
|
||||
# else
|
||||
# define NEW_TTY_DRIVER
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/*
|
||||
* The _POSIX_SOURCE define is to avoid multiple symbol definitions
|
||||
* between sys/ioctl.h and termios.h. Ditto for the test against SunOS4
|
||||
* and the undefining of several symbols.
|
||||
*/
|
||||
|
||||
#ifdef TERMIOS_TTY_DRIVER
|
||||
# if (defined (SunOS4) || defined (SunOS5)) && !defined (_POSIX_SOURCE)
|
||||
# define _POSIX_SOURCE
|
||||
# endif
|
||||
# if defined (SunOS4)
|
||||
# undef ECHO
|
||||
# undef NOFLSH
|
||||
# undef TOSTOP
|
||||
# endif /* SunOS4 */
|
||||
# include <termios.h>
|
||||
# define TTYSTRUCT struct termios
|
||||
#else
|
||||
# ifdef TERMIO_TTY_DRIVER
|
||||
# include <termio.h>
|
||||
# define TTYSTRUCT struct termio
|
||||
# else /* NEW_TTY_DRIVER */
|
||||
# include <sgtty.h>
|
||||
# define TTYSTRUCT struct sgttyb
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* Functions imported from lib/sh/shtty.c */
|
||||
|
||||
/* Get and set terminal attributes for the file descriptor passed as
|
||||
an argument. */
|
||||
extern int ttgetattr __P((int, TTYSTRUCT *));
|
||||
extern int ttsetattr __P((int, TTYSTRUCT *));
|
||||
|
||||
/* Save and restore the terminal's attributes from static storage. */
|
||||
extern void ttsave __P((void));
|
||||
extern void ttrestore __P((void));
|
||||
|
||||
/* Return the attributes corresponding to the file descriptor (0 or 1)
|
||||
passed as an argument. */
|
||||
extern TTYSTRUCT *ttattr __P((int));
|
||||
|
||||
/* These functions only operate on the passed TTYSTRUCT; they don't
|
||||
actually change anything with the kernel's current tty settings. */
|
||||
extern int tt_setonechar __P((TTYSTRUCT *));
|
||||
extern int tt_setnoecho __P((TTYSTRUCT *));
|
||||
extern int tt_seteightbit __P((TTYSTRUCT *));
|
||||
extern int tt_setnocanon __P((TTYSTRUCT *));
|
||||
extern int tt_setcbreak __P((TTYSTRUCT *));
|
||||
|
||||
/* These functions are all generally mutually exclusive. If you call
|
||||
more than one (bracketed with calls to ttsave and ttrestore, of
|
||||
course), the right thing will happen, but more system calls will be
|
||||
executed than absolutely necessary. You can do all of this yourself
|
||||
with the other functions; these are only conveniences. */
|
||||
|
||||
/* These functions work with a given file descriptor and set terminal
|
||||
attributes */
|
||||
extern int ttfd_onechar __P((int, TTYSTRUCT *));
|
||||
extern int ttfd_noecho __P((int, TTYSTRUCT *));
|
||||
extern int ttfd_eightbit __P((int, TTYSTRUCT *));
|
||||
extern int ttfd_nocanon __P((int, TTYSTRUCT *));
|
||||
|
||||
extern int ttcbreak __P((int, TTYSTRUCT *));
|
||||
|
||||
/* These functions work with fd 0 and the TTYSTRUCT saved with ttsave () */
|
||||
extern int ttonechar __P((void));
|
||||
extern int ttnoecho __P((void));
|
||||
extern int tteightbit __P((void));
|
||||
extern int ttnocanon __P((void));
|
||||
|
||||
extern int ttcbreak __P((void));
|
||||
|
||||
#endif
|
||||
@@ -250,6 +250,7 @@ static int job_exit_status __P((int));
|
||||
static int job_exit_signal __P((int));
|
||||
static int set_job_status_and_cleanup __P((int));
|
||||
|
||||
static WAIT job_signal_status __P((int));
|
||||
static WAIT raw_job_exit_status __P((int));
|
||||
|
||||
static void notify_of_job_status __P((void));
|
||||
@@ -453,7 +454,6 @@ start_pipeline ()
|
||||
{
|
||||
cleanup_the_pipeline ();
|
||||
pipeline_pgrp = 0;
|
||||
itrace("start_pipeline: set pipeline_pgrp = 0");
|
||||
#if defined (PGRP_PIPE)
|
||||
pipe_close (pgrp_pipe);
|
||||
#endif
|
||||
@@ -567,7 +567,6 @@ stop_pipeline (async, deferred)
|
||||
the_pipeline = (PROCESS *)NULL;
|
||||
newjob->pgrp = pipeline_pgrp;
|
||||
pipeline_pgrp = 0;
|
||||
itrace("stop_pipeline: set pipeline_pgrp = 0");
|
||||
|
||||
newjob->flags = 0;
|
||||
|
||||
@@ -1686,8 +1685,6 @@ make_child (command, async_p)
|
||||
sigemptyset (&oset);
|
||||
sigprocmask (SIG_BLOCK, &set, &oset);
|
||||
|
||||
itrace("make_child start: pipeline_pgrp = %d", pipeline_pgrp);
|
||||
|
||||
making_children ();
|
||||
|
||||
#if defined (BUFFERED_INPUT)
|
||||
@@ -1746,10 +1743,7 @@ itrace("make_child start: pipeline_pgrp = %d", pipeline_pgrp);
|
||||
process group. */
|
||||
|
||||
if (pipeline_pgrp == 0) /* This is the first child. */
|
||||
{
|
||||
pipeline_pgrp = mypid;
|
||||
itrace("make_child: child proc: set pipeline_pgrp = %d (mypid)", pipeline_pgrp);
|
||||
}
|
||||
|
||||
/* Check for running command in backquotes. */
|
||||
if (pipeline_pgrp == shell_pgrp)
|
||||
@@ -1775,10 +1769,7 @@ itrace("make_child: child proc: set pipeline_pgrp = %d (mypid)", pipeline_pgrp);
|
||||
shell's process group (we could be in the middle of a
|
||||
pipeline, for example). */
|
||||
if (async_p == 0 && pipeline_pgrp != shell_pgrp && ((subshell_environment&SUBSHELL_ASYNC) == 0))
|
||||
{
|
||||
itrace("make_child: give terminal to %d shell_pgrp = %d subshell_environment = %d", pipeline_pgrp, shell_pgrp, subshell_environment);
|
||||
give_terminal_to (pipeline_pgrp, 0);
|
||||
}
|
||||
|
||||
#if defined (PGRP_PIPE)
|
||||
if (pipeline_pgrp == mypid)
|
||||
@@ -1788,10 +1779,7 @@ itrace("make_child: give terminal to %d shell_pgrp = %d subshell_environment = %
|
||||
else /* Without job control... */
|
||||
{
|
||||
if (pipeline_pgrp == 0)
|
||||
{
|
||||
pipeline_pgrp = shell_pgrp;
|
||||
itrace("make_child: child proc: set pipeline_pgrp = %d (shell_pgrp)", pipeline_pgrp);
|
||||
}
|
||||
|
||||
/* If these signals are set to SIG_DFL, we encounter the curious
|
||||
situation of an interactive ^Z to a running process *working*
|
||||
@@ -1836,7 +1824,6 @@ itrace("make_child: child proc: set pipeline_pgrp = %d (shell_pgrp)", pipeline_p
|
||||
if (pipeline_pgrp == 0)
|
||||
{
|
||||
pipeline_pgrp = pid;
|
||||
itrace("make_child: parent proc: set pipeline_pgrp = %d (pid)", pipeline_pgrp);
|
||||
/* Don't twiddle terminal pgrps in the parent! This is the bug,
|
||||
not the good thing of twiddling them in the child! */
|
||||
/* give_terminal_to (pipeline_pgrp, 0); */
|
||||
@@ -1850,11 +1837,7 @@ itrace("make_child: parent proc: set pipeline_pgrp = %d (pid)", pipeline_pgrp);
|
||||
else
|
||||
{
|
||||
if (pipeline_pgrp == 0)
|
||||
{
|
||||
pipeline_pgrp = shell_pgrp;
|
||||
itrace("make_child: parent proc: set pipeline_pgrp = %d (shell_pgrp)", pipeline_pgrp);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* Place all processes into the jobs array regardless of the
|
||||
@@ -2230,7 +2213,6 @@ wait_sigint_handler (sig)
|
||||
/* XXX - should this be interrupt_state? If it is, the shell will act
|
||||
as if it got the SIGINT interrupt. */
|
||||
wait_sigint_received = 1;
|
||||
itrace("wait_sigint_handler: wait_sigint_received -> 1");
|
||||
/* Otherwise effectively ignore the SIGINT and allow the running job to
|
||||
be killed. */
|
||||
SIGRETURN (0);
|
||||
@@ -2255,6 +2237,26 @@ process_exit_status (status)
|
||||
return (EXECUTION_SUCCESS);
|
||||
}
|
||||
|
||||
static WAIT
|
||||
job_signal_status (job)
|
||||
int job;
|
||||
{
|
||||
register PROCESS *p;
|
||||
WAIT s;
|
||||
|
||||
p = jobs[job]->pipe;
|
||||
do
|
||||
{
|
||||
s = p->status;
|
||||
if (WIFSIGNALED(s) || WIFSTOPPED(s))
|
||||
break;
|
||||
p = p->next;
|
||||
}
|
||||
while (p != jobs[job]->pipe);
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
/* Return the exit status of the last process in the pipeline for job JOB.
|
||||
This is the exit status of the entire job. */
|
||||
static WAIT
|
||||
@@ -2263,6 +2265,7 @@ raw_job_exit_status (job)
|
||||
{
|
||||
register PROCESS *p;
|
||||
int fail;
|
||||
WAIT ret;
|
||||
|
||||
if (pipefail_opt)
|
||||
{
|
||||
@@ -2270,11 +2273,13 @@ raw_job_exit_status (job)
|
||||
p = jobs[job]->pipe;
|
||||
do
|
||||
{
|
||||
if (WSTATUS (p->status) != EXECUTION_SUCCESS) fail = WSTATUS(p->status);
|
||||
if (WSTATUS (p->status) != EXECUTION_SUCCESS)
|
||||
fail = WSTATUS(p->status);
|
||||
p = p->next;
|
||||
}
|
||||
while (p != jobs[job]->pipe);
|
||||
return fail;
|
||||
WSTATUS (ret) = fail;
|
||||
return ret;
|
||||
}
|
||||
|
||||
for (p = jobs[job]->pipe; p->next != jobs[job]->pipe; p = p->next)
|
||||
@@ -2448,7 +2453,6 @@ wait_for (pid)
|
||||
/* XXX */
|
||||
if ((job != NO_JOB && JOBSTATE (job) == JSTOPPED) || WIFSTOPPED (child->status))
|
||||
termination_state = 128 + WSTOPSIG (child->status);
|
||||
itrace("wait_for (%d): termination_state = %d last_command_exit_signal = %d", pid, termination_state, last_command_exit_signal);
|
||||
|
||||
if (job == NO_JOB || IS_JOBCONTROL (job))
|
||||
{
|
||||
@@ -2491,15 +2495,7 @@ if (job == NO_JOB)
|
||||
to a signal. We might want to change this later to just check
|
||||
the last process in the pipeline. If no process exits due to a
|
||||
signal, S is left as the status of the last job in the pipeline. */
|
||||
p = jobs[job]->pipe;
|
||||
do
|
||||
{
|
||||
s = p->status;
|
||||
if (WIFSIGNALED(s) || WIFSTOPPED(s))
|
||||
break;
|
||||
p = p->next;
|
||||
}
|
||||
while (p != jobs[job]->pipe);
|
||||
s = job_signal_status (job);
|
||||
|
||||
if (WIFSIGNALED (s) || WIFSTOPPED (s))
|
||||
{
|
||||
@@ -2533,6 +2529,24 @@ if (job == NO_JOB)
|
||||
}
|
||||
}
|
||||
}
|
||||
else if ((subshell_environment & SUBSHELL_COMSUB) && wait_sigint_received)
|
||||
{
|
||||
/* If waiting for a job in a subshell started to do command
|
||||
substitution, simulate getting and being killed by the SIGINT to
|
||||
pass the status back to our parent. */
|
||||
s = job_signal_status (job);
|
||||
|
||||
if (WIFSIGNALED (s) && WTERMSIG (s) == SIGINT && signal_is_trapped (SIGINT) == 0)
|
||||
{
|
||||
UNBLOCK_CHILD (oset);
|
||||
restore_sigint_handler ();
|
||||
old_sigint_handler = set_signal_handler (SIGINT, SIG_DFL);
|
||||
if (old_sigint_handler == SIG_IGN)
|
||||
restore_sigint_handler ();
|
||||
else
|
||||
kill (getpid (), SIGINT);
|
||||
}
|
||||
}
|
||||
|
||||
/* Moved here from set_job_status_and_cleanup, which is in the SIGCHLD
|
||||
signal handler path */
|
||||
@@ -3026,7 +3040,6 @@ waitchld (wpid, block)
|
||||
wcontinued = 0;
|
||||
continue; /* jump back to the test and retry without WCONTINUED */
|
||||
}
|
||||
itrace("waitchld: waitpid returns %d (status %d)", pid, status);
|
||||
|
||||
/* The check for WNOHANG is to make sure we decrement sigchld only
|
||||
if it was non-zero before we called waitpid. */
|
||||
@@ -4047,10 +4060,7 @@ set_job_control (arg)
|
||||
/* If we're turning on job control, reset pipeline_pgrp so make_child will
|
||||
put new child processes into the right pgrp */
|
||||
if (job_control != old && job_control)
|
||||
{
|
||||
pipeline_pgrp = 0;
|
||||
itrace("set_job_control: set pipeline_pgrp = 0");
|
||||
}
|
||||
|
||||
return (old);
|
||||
}
|
||||
|
||||
@@ -137,8 +137,6 @@ extern int errno;
|
||||
/* The number of additional slots to allocate when we run out. */
|
||||
#define JOB_SLOTS 8
|
||||
|
||||
#define CTTYFD 2
|
||||
|
||||
typedef int sh_job_map_func_t __P((JOB *, int, int, int));
|
||||
|
||||
/* Variables used here but defined in other files. */
|
||||
@@ -252,6 +250,7 @@ static int job_exit_status __P((int));
|
||||
static int job_exit_signal __P((int));
|
||||
static int set_job_status_and_cleanup __P((int));
|
||||
|
||||
static WAIT job_signal_status __P((int));
|
||||
static WAIT raw_job_exit_status __P((int));
|
||||
|
||||
static void notify_of_job_status __P((void));
|
||||
@@ -1676,6 +1675,7 @@ make_child (command, async_p)
|
||||
char *command;
|
||||
int async_p;
|
||||
{
|
||||
int forksleep;
|
||||
sigset_t set, oset;
|
||||
pid_t pid;
|
||||
|
||||
@@ -1697,8 +1697,16 @@ make_child (command, async_p)
|
||||
sync_buffered_stream (default_buffered_input);
|
||||
#endif /* BUFFERED_INPUT */
|
||||
|
||||
/* Create the child, handle severe errors. */
|
||||
if ((pid = fork ()) < 0)
|
||||
/* Create the child, handle severe errors. Retry on EAGAIN. */
|
||||
while ((pid = fork ()) < 0 && errno == EAGAIN && forksleep < FORKSLEEP_MAX)
|
||||
{
|
||||
sys_error ("fork: retry");
|
||||
if (sleep (forksleep) != 0)
|
||||
break;
|
||||
forksleep <<= 1;
|
||||
}
|
||||
|
||||
if (pid < 0)
|
||||
{
|
||||
sys_error ("fork");
|
||||
|
||||
@@ -2205,7 +2213,6 @@ wait_sigint_handler (sig)
|
||||
/* XXX - should this be interrupt_state? If it is, the shell will act
|
||||
as if it got the SIGINT interrupt. */
|
||||
wait_sigint_received = 1;
|
||||
|
||||
/* Otherwise effectively ignore the SIGINT and allow the running job to
|
||||
be killed. */
|
||||
SIGRETURN (0);
|
||||
@@ -2230,6 +2237,26 @@ process_exit_status (status)
|
||||
return (EXECUTION_SUCCESS);
|
||||
}
|
||||
|
||||
static WAIT
|
||||
job_signal_status (job)
|
||||
int job;
|
||||
{
|
||||
register PROCESS *p;
|
||||
WAIT s;
|
||||
|
||||
p = jobs[job]->pipe;
|
||||
do
|
||||
{
|
||||
s = p->status;
|
||||
if (WIFSIGNALED(s) || WIFSTOPPED(s))
|
||||
break;
|
||||
p = p->next;
|
||||
}
|
||||
while (p != jobs[job]->pipe);
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
/* Return the exit status of the last process in the pipeline for job JOB.
|
||||
This is the exit status of the entire job. */
|
||||
static WAIT
|
||||
@@ -2238,6 +2265,7 @@ raw_job_exit_status (job)
|
||||
{
|
||||
register PROCESS *p;
|
||||
int fail;
|
||||
WAIT ret;
|
||||
|
||||
if (pipefail_opt)
|
||||
{
|
||||
@@ -2245,11 +2273,13 @@ raw_job_exit_status (job)
|
||||
p = jobs[job]->pipe;
|
||||
do
|
||||
{
|
||||
if (WSTATUS (p->status) != EXECUTION_SUCCESS) fail = WSTATUS(p->status);
|
||||
if (WSTATUS (p->status) != EXECUTION_SUCCESS)
|
||||
fail = WSTATUS(p->status);
|
||||
p = p->next;
|
||||
}
|
||||
while (p != jobs[job]->pipe);
|
||||
return fail;
|
||||
WSTATUS (ret) = fail;
|
||||
return ret;
|
||||
}
|
||||
|
||||
for (p = jobs[job]->pipe; p->next != jobs[job]->pipe; p = p->next)
|
||||
@@ -2312,11 +2342,14 @@ wait_for (pid)
|
||||
to finish. We don't want the shell to exit if an interrupt is
|
||||
received, only if one of the jobs run is killed via SIGINT. If
|
||||
job control is not set, the job will be run in the same pgrp as
|
||||
the shell, and the shell will see any signals the job gets. */
|
||||
the shell, and the shell will see any signals the job gets. In
|
||||
fact, we want this set every time the waiting shell and the waited-
|
||||
for process are in the same process group, including command
|
||||
substitution. */
|
||||
|
||||
/* This is possibly a race condition -- should it go in stop_pipeline? */
|
||||
wait_sigint_received = 0;
|
||||
if (job_control == 0)
|
||||
if (job_control == 0 || (subshell_environment&SUBSHELL_COMSUB))
|
||||
{
|
||||
old_sigint_handler = set_signal_handler (SIGINT, wait_sigint_handler);
|
||||
if (old_sigint_handler == SIG_IGN)
|
||||
@@ -2462,15 +2495,7 @@ if (job == NO_JOB)
|
||||
to a signal. We might want to change this later to just check
|
||||
the last process in the pipeline. If no process exits due to a
|
||||
signal, S is left as the status of the last job in the pipeline. */
|
||||
p = jobs[job]->pipe;
|
||||
do
|
||||
{
|
||||
s = p->status;
|
||||
if (WIFSIGNALED(s) || WIFSTOPPED(s))
|
||||
break;
|
||||
p = p->next;
|
||||
}
|
||||
while (p != jobs[job]->pipe);
|
||||
s = job_signal_status (job);
|
||||
|
||||
if (WIFSIGNALED (s) || WIFSTOPPED (s))
|
||||
{
|
||||
@@ -2504,6 +2529,24 @@ if (job == NO_JOB)
|
||||
}
|
||||
}
|
||||
}
|
||||
else if ((subshell_environment & SUBSHELL_COMSUB) && wait_sigint_received)
|
||||
{
|
||||
/* If waiting for a job in a subshell started to do command
|
||||
substitution, simulate getting and being killed by the SIGINT to
|
||||
pass the status back to our parent. */
|
||||
s = job_signal_status (job);
|
||||
|
||||
if (WIFSIGNALED (s) && WTERMSIG (s) == SIGINT && signal_is_trapped (SIGINT) == 0)
|
||||
{
|
||||
UNBLOCK_CHILD (oset);
|
||||
restore_sigint_handler ();
|
||||
old_sigint_handler = set_signal_handler (SIGINT, SIG_DFL);
|
||||
if (old_sigint_handler == SIG_IGN)
|
||||
restore_sigint_handler ();
|
||||
else
|
||||
kill (getpid (), SIGINT);
|
||||
}
|
||||
}
|
||||
|
||||
/* Moved here from set_job_status_and_cleanup, which is in the SIGCHLD
|
||||
signal handler path */
|
||||
@@ -3501,6 +3544,12 @@ initialize_job_control (force)
|
||||
else
|
||||
{
|
||||
shell_tty = -1;
|
||||
|
||||
/* If forced_interactive is set, we skip the normal check that stderr
|
||||
is attached to a tty, so we need to check here. If it's not, we
|
||||
need to see whether we have a controlling tty by opening /dev/tty,
|
||||
since trying to use job control tty pgrp manipulations on a non-tty
|
||||
is going to fail. */
|
||||
if (forced_interactive && isatty (fileno (stderr)) == 0)
|
||||
shell_tty = open ("/dev/tty", O_RDWR|O_NONBLOCK);
|
||||
|
||||
@@ -3844,7 +3893,7 @@ count_all_jobs ()
|
||||
{
|
||||
#if defined (DEBUG)
|
||||
if (i < js.j_firstj && jobs[i])
|
||||
itrace("count_all_jobs: job %d non-null before js.j_firstj (%d)", i, js.j_firstj);
|
||||
itrace<("count_all_jobs: job %d non-null before js.j_firstj (%d)", i, js.j_firstj);
|
||||
if (i > js.j_lastj && jobs[i])
|
||||
itrace("count_all_jobs: job %d non-null after js.j_lastj (%d)", i, js.j_lastj);
|
||||
#endif
|
||||
|
||||
@@ -938,8 +938,9 @@ rl_redisplay ()
|
||||
second and subsequent lines start at inv_lbreaks[N], offset by
|
||||
OFFSET (which has already been calculated above). */
|
||||
|
||||
#define INVIS_FIRST() (prompt_physical_chars > _rl_screenwidth ? prompt_invis_chars_first_line : wrap_offset)
|
||||
#define WRAP_OFFSET(line, offset) ((line == 0) \
|
||||
? (offset ? prompt_invis_chars_first_line : 0) \
|
||||
? (offset ? INVIS_FIRST() : 0) \
|
||||
: ((line == prompt_last_screen_line) ? wrap_offset-prompt_invis_chars_first_line : 0))
|
||||
#define W_OFFSET(line, offset) ((line) == 0 ? offset : 0)
|
||||
#define VIS_LLEN(l) ((l) > _rl_vis_botlin ? 0 : (vis_lbreaks[l+1] - vis_lbreaks[l]))
|
||||
|
||||
+62
-16
@@ -85,7 +85,7 @@ ttrestore()
|
||||
ttsaved = 0;
|
||||
}
|
||||
|
||||
/* Retrieve the attributes associated with tty fd FD. */
|
||||
/* Retrieve the internally-saved attributes associated with tty fd FD. */
|
||||
TTYSTRUCT *
|
||||
ttattr (fd)
|
||||
int fd;
|
||||
@@ -149,6 +149,17 @@ tt_setonechar(ttp)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Set the tty associated with FD and TTP into one-character-at-a-time mode */
|
||||
int
|
||||
ttfd_onechar (fd, ttp)
|
||||
int fd;
|
||||
TTYSTRUCT *ttp;
|
||||
{
|
||||
if (tt_setonechar(ttp) < 0)
|
||||
return -1;
|
||||
return (ttsetattr (fd, ttp));
|
||||
}
|
||||
|
||||
/* Set the terminal into one-character-at-a-time mode */
|
||||
int
|
||||
ttonechar ()
|
||||
@@ -158,9 +169,7 @@ ttonechar ()
|
||||
if (ttsaved == 0)
|
||||
return -1;
|
||||
tt = ttin;
|
||||
if (tt_setonechar(&tt) < 0)
|
||||
return -1;
|
||||
return (ttsetattr (0, &tt));
|
||||
return (ttfd_onechar (0, &tt));
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -180,6 +189,17 @@ tt_setnoecho(ttp)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Set the tty associated with FD and TTP into no-echo mode */
|
||||
int
|
||||
ttfd_noecho (fd, ttp)
|
||||
int fd;
|
||||
TTYSTRUCT *ttp;
|
||||
{
|
||||
if (tt_setnoecho (ttp) < 0)
|
||||
return -1;
|
||||
return (ttsetattr (fd, ttp));
|
||||
}
|
||||
|
||||
/* Set the terminal into no-echo mode */
|
||||
int
|
||||
ttnoecho ()
|
||||
@@ -189,9 +209,7 @@ ttnoecho ()
|
||||
if (ttsaved == 0)
|
||||
return -1;
|
||||
tt = ttin;
|
||||
if (tt_setnoecho (&tt) < 0)
|
||||
return -1;
|
||||
return (ttsetattr (0, &tt));
|
||||
return (ttfd_noecho (0, &tt));
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -213,6 +231,17 @@ tt_seteightbit (ttp)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Set the tty associated with FD and TTP into eight-bit mode */
|
||||
int
|
||||
ttfd_eightbit (fd, ttp)
|
||||
int fd;
|
||||
TTYSTRUCT *ttp;
|
||||
{
|
||||
if (tt_seteightbit (ttp) < 0)
|
||||
return -1;
|
||||
return (ttsetattr (fd, ttp));
|
||||
}
|
||||
|
||||
/* Set the terminal into eight-bit mode */
|
||||
int
|
||||
tteightbit ()
|
||||
@@ -222,9 +251,7 @@ tteightbit ()
|
||||
if (ttsaved == 0)
|
||||
return -1;
|
||||
tt = ttin;
|
||||
if (tt_seteightbit (&tt) < 0)
|
||||
return -1;
|
||||
return (ttsetattr (0, &tt));
|
||||
return (ttfd_eightbit (0, &tt));
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -242,6 +269,17 @@ tt_setnocanon (ttp)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Set the tty associated with FD and TTP into non-canonical mode */
|
||||
int
|
||||
ttfd_nocanon (fd, ttp)
|
||||
int fd;
|
||||
TTYSTRUCT *ttp;
|
||||
{
|
||||
if (tt_setnocanon (ttp) < 0)
|
||||
return -1;
|
||||
return (ttsetattr (fd, ttp));
|
||||
}
|
||||
|
||||
/* Set the terminal into non-canonical mode */
|
||||
int
|
||||
ttnocanon ()
|
||||
@@ -251,9 +289,7 @@ ttnocanon ()
|
||||
if (ttsaved == 0)
|
||||
return -1;
|
||||
tt = ttin;
|
||||
if (tt_setnocanon (&tt) < 0)
|
||||
return -1;
|
||||
return (ttsetattr (0, &tt));
|
||||
return (ttfd_nocanon (0, &tt));
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -269,6 +305,18 @@ tt_setcbreak(ttp)
|
||||
return (tt_setnoecho (ttp));
|
||||
}
|
||||
|
||||
/* Set the tty associated with FD and TTP into cbreak (no-echo,
|
||||
one-character-at-a-time) mode */
|
||||
int
|
||||
ttfd_cbreak (fd, ttp)
|
||||
int fd;
|
||||
TTYSTRUCT *ttp;
|
||||
{
|
||||
if (tt_setcbreak (ttp) < 0)
|
||||
return -1;
|
||||
return (ttsetattr (fd, ttp));
|
||||
}
|
||||
|
||||
/* Set the terminal into cbreak (no-echo, one-character-at-a-time) mode */
|
||||
int
|
||||
ttcbreak ()
|
||||
@@ -278,7 +326,5 @@ ttcbreak ()
|
||||
if (ttsaved == 0)
|
||||
return -1;
|
||||
tt = ttin;
|
||||
if (tt_setcbreak (&tt) < 0)
|
||||
return -1;
|
||||
return (ttsetattr (0, &tt));
|
||||
return (ttfd_cbreak (0, &tt));
|
||||
}
|
||||
|
||||
+329
@@ -0,0 +1,329 @@
|
||||
/* Copyright (C) 1999 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 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. */
|
||||
|
||||
/*
|
||||
* shtty.c -- abstract interface to the terminal, focusing on capabilities.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_UNISTD_H
|
||||
# include <unistd.h>
|
||||
#endif
|
||||
|
||||
#include <shtty.h>
|
||||
|
||||
static TTYSTRUCT ttin, ttout;
|
||||
static int ttsaved = 0;
|
||||
|
||||
int
|
||||
ttgetattr(fd, ttp)
|
||||
int fd;
|
||||
TTYSTRUCT *ttp;
|
||||
{
|
||||
#ifdef TERMIOS_TTY_DRIVER
|
||||
return tcgetattr(fd, ttp);
|
||||
#else
|
||||
# ifdef TERMIO_TTY_DRIVER
|
||||
return ioctl(fd, TCGETA, ttp);
|
||||
# else
|
||||
return ioctl(fd, TIOCGETP, ttp);
|
||||
# endif
|
||||
#endif
|
||||
}
|
||||
|
||||
int
|
||||
ttsetattr(fd, ttp)
|
||||
int fd;
|
||||
TTYSTRUCT *ttp;
|
||||
{
|
||||
#ifdef TERMIOS_TTY_DRIVER
|
||||
return tcsetattr(fd, TCSADRAIN, ttp);
|
||||
#else
|
||||
# ifdef TERMIO_TTY_DRIVER
|
||||
return ioctl(fd, TCSETAW, ttp);
|
||||
# else
|
||||
return ioctl(fd, TIOCSETN, ttp);
|
||||
# endif
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
ttsave()
|
||||
{
|
||||
if (ttsaved)
|
||||
return;
|
||||
ttgetattr (0, &ttin);
|
||||
ttgetattr (1, &ttout);
|
||||
ttsaved = 1;
|
||||
}
|
||||
|
||||
void
|
||||
ttrestore()
|
||||
{
|
||||
if (ttsaved == 0)
|
||||
return;
|
||||
ttsetattr (0, &ttin);
|
||||
ttsetattr (1, &ttout);
|
||||
ttsaved = 0;
|
||||
}
|
||||
|
||||
/* Retrieve the internally-saved attributes associated with tty fd FD. */
|
||||
TTYSTRUCT *
|
||||
ttattr (fd)
|
||||
int fd;
|
||||
{
|
||||
if (ttsaved == 0)
|
||||
return ((TTYSTRUCT *)0);
|
||||
if (fd == 0)
|
||||
return &ttin;
|
||||
else if (fd == 1)
|
||||
return &ttout;
|
||||
else
|
||||
return ((TTYSTRUCT *)0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Change attributes in ttp so that when it is installed using
|
||||
* ttsetattr, the terminal will be in one-char-at-a-time mode.
|
||||
*/
|
||||
int
|
||||
tt_setonechar(ttp)
|
||||
TTYSTRUCT *ttp;
|
||||
{
|
||||
#if defined (TERMIOS_TTY_DRIVER) || defined (TERMIO_TTY_DRIVER)
|
||||
|
||||
/* XXX - might not want this -- it disables erase and kill processing. */
|
||||
ttp->c_lflag &= ~ICANON;
|
||||
|
||||
ttp->c_lflag |= ISIG;
|
||||
# ifdef IEXTEN
|
||||
ttp->c_lflag |= IEXTEN;
|
||||
# endif
|
||||
|
||||
ttp->c_iflag |= ICRNL; /* make sure we get CR->NL on input */
|
||||
ttp->c_iflag &= ~INLCR; /* but no NL->CR */
|
||||
|
||||
# ifdef OPOST
|
||||
ttp->c_oflag |= OPOST;
|
||||
# endif
|
||||
# ifdef ONLCR
|
||||
ttp->c_oflag |= ONLCR;
|
||||
# endif
|
||||
# ifdef OCRNL
|
||||
ttp->c_oflag &= ~OCRNL;
|
||||
# endif
|
||||
# ifdef ONOCR
|
||||
ttp->c_oflag &= ~ONOCR;
|
||||
# endif
|
||||
# ifdef ONLRET
|
||||
ttp->c_oflag &= ~ONLRET;
|
||||
# endif
|
||||
|
||||
ttp->c_cc[VMIN] = 1;
|
||||
ttp->c_cc[VTIME] = 0;
|
||||
|
||||
#else
|
||||
|
||||
ttp->sg_flags |= CBREAK;
|
||||
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Set the tty associated with FD and TTP into one-character-at-a-time mode */
|
||||
int
|
||||
ttfd_onechar (fd, ttp)
|
||||
int fd;
|
||||
TTYSTRUCT *ttp;
|
||||
{
|
||||
if (tt_setonechar(ttp) < 0)
|
||||
return -1;
|
||||
return (ttsetattr (fd, ttp));
|
||||
}
|
||||
|
||||
/* Set the terminal into one-character-at-a-time mode */
|
||||
int
|
||||
ttonechar ()
|
||||
{
|
||||
TTYSTRUCT tt;
|
||||
|
||||
if (ttsaved == 0)
|
||||
return -1;
|
||||
tt = ttin;
|
||||
return (ttfd_onechar (0, &tt));
|
||||
}
|
||||
|
||||
/*
|
||||
* Change attributes in ttp so that when it is installed using
|
||||
* ttsetattr, the terminal will be in no-echo mode.
|
||||
*/
|
||||
int
|
||||
tt_setnoecho(ttp)
|
||||
TTYSTRUCT *ttp;
|
||||
{
|
||||
#if defined (TERMIOS_TTY_DRIVER) || defined (TERMIO_TTY_DRIVER)
|
||||
ttp->c_lflag &= ~(ECHO|ECHOK|ECHONL);
|
||||
#else
|
||||
ttp->sg_flags &= ~ECHO;
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Set the tty associated with FD and TTP into no-echo mode */
|
||||
int
|
||||
ttfd_noecho (fd, ttp)
|
||||
int fd;
|
||||
TTYSTRUCT *ttp;
|
||||
{
|
||||
if (tt_setnoecho (ttp) < 0)
|
||||
return -1;
|
||||
return (ttsetattr (fd, ttp));
|
||||
}
|
||||
|
||||
/* Set the terminal into no-echo mode */
|
||||
int
|
||||
ttnoecho ()
|
||||
{
|
||||
TTYSTRUCT tt;
|
||||
|
||||
if (ttsaved == 0)
|
||||
return -1;
|
||||
tt = ttin;
|
||||
return (ttfd_noecho (0, &tt));
|
||||
}
|
||||
|
||||
/*
|
||||
* Change attributes in ttp so that when it is installed using
|
||||
* ttsetattr, the terminal will be in eight-bit mode (pass8).
|
||||
*/
|
||||
int
|
||||
tt_seteightbit (ttp)
|
||||
TTYSTRUCT *ttp;
|
||||
{
|
||||
#if defined (TERMIOS_TTY_DRIVER) || defined (TERMIO_TTY_DRIVER)
|
||||
ttp->c_iflag &= ~ISTRIP;
|
||||
ttp->c_cflag |= CS8;
|
||||
ttp->c_cflag &= ~PARENB;
|
||||
#else
|
||||
ttp->sg_flags |= ANYP;
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Set the tty associated with FD and TTP into eight-bit mode */
|
||||
int
|
||||
ttfd_eightbit (fd, ttp)
|
||||
int fd;
|
||||
TTYSTRUCT *ttp;
|
||||
{
|
||||
if (tt_seteightbit (ttp) < 0)
|
||||
return -1;
|
||||
return (ttsetattr (fd, ttp));
|
||||
}
|
||||
|
||||
/* Set the terminal into eight-bit mode */
|
||||
int
|
||||
tteightbit ()
|
||||
{
|
||||
TTYSTRUCT tt;
|
||||
|
||||
if (ttsaved == 0)
|
||||
return -1;
|
||||
tt = ttin;
|
||||
return (ttfd_eightbit (0, &tt));
|
||||
}
|
||||
|
||||
/*
|
||||
* Change attributes in ttp so that when it is installed using
|
||||
* ttsetattr, the terminal will be in non-canonical input mode.
|
||||
*/
|
||||
int
|
||||
tt_setnocanon (ttp)
|
||||
TTYSTRUCT *ttp;
|
||||
{
|
||||
#if defined (TERMIOS_TTY_DRIVER) || defined (TERMIO_TTY_DRIVER)
|
||||
ttp->c_lflag &= ~ICANON;
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Set the tty associated with FD and TTP into non-canonical mode */
|
||||
int
|
||||
ttfd_nocanon (fd, ttp)
|
||||
int fd;
|
||||
TTYSTRUCT *ttp;
|
||||
{
|
||||
if (tt_setnocanon (ttp) < 0)
|
||||
return -1;
|
||||
return (ttsetattr (fd, ttp));
|
||||
}
|
||||
|
||||
/* Set the terminal into non-canonical mode */
|
||||
int
|
||||
ttnocanon ()
|
||||
{
|
||||
TTYSTRUCT tt;
|
||||
|
||||
if (ttsaved == 0)
|
||||
return -1;
|
||||
tt = ttin;
|
||||
return (ttfd_nocanon (0, &tt));
|
||||
}
|
||||
|
||||
/*
|
||||
* Change attributes in ttp so that when it is installed using
|
||||
* ttsetattr, the terminal will be in cbreak, no-echo mode.
|
||||
*/
|
||||
int
|
||||
tt_setcbreak(ttp)
|
||||
TTYSTRUCT *ttp;
|
||||
{
|
||||
if (tt_setonechar (ttp) < 0)
|
||||
return -1;
|
||||
return (tt_setnoecho (ttp));
|
||||
}
|
||||
|
||||
/* Set the terminal into cbreak (no-echo, one-character-at-a-time) mode */
|
||||
int
|
||||
ttfd_cbreak (fd, ttp)
|
||||
int fd;
|
||||
TTYSTRUCT *ttp;
|
||||
{
|
||||
if (tt_setcbreak (ttp) < 0)
|
||||
return -1;
|
||||
return (ttsetattr (fd, ttp));
|
||||
}
|
||||
|
||||
/* Set the terminal into cbreak (no-echo, one-character-at-a-time) mode */
|
||||
int
|
||||
ttcbreak ()
|
||||
{
|
||||
TTYSTRUCT tt;
|
||||
|
||||
if (ttsaved == 0)
|
||||
return -1;
|
||||
tt = ttin;
|
||||
return (ttfd_cbreak (0, &tt));
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
/* sig.c - interface for shell signal handlers and signal initialization. */
|
||||
|
||||
/* Copyright (C) 1994-2006 Free Software Foundation, Inc.
|
||||
/* Copyright (C) 1994-2007 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Bash, the Bourne Again SHell.
|
||||
|
||||
@@ -508,7 +508,7 @@ sigint_sighandler (sig)
|
||||
right. Should it be set unconditionally? */
|
||||
if (interrupt_state == 0)
|
||||
ADDINTERRUPT;
|
||||
itrace("sigint_sighandler");
|
||||
|
||||
if (interrupt_immediately)
|
||||
{
|
||||
interrupt_immediately = 0;
|
||||
|
||||
@@ -4391,6 +4391,7 @@ process_substitute (string, open_for_read_in_child)
|
||||
#if defined (JOB_CONTROL)
|
||||
set_sigchld_handler ();
|
||||
stop_making_children ();
|
||||
/* XXX - should we only do this in the parent? (as in command subst) */
|
||||
pipeline_pgrp = old_pipeline_pgrp;
|
||||
#endif /* JOB_CONTROL */
|
||||
|
||||
@@ -4666,10 +4667,7 @@ command_substitute (string, quoted)
|
||||
old_pipeline_pgrp = pipeline_pgrp;
|
||||
/* Don't reset the pipeline pgrp if we're already a subshell in a pipeline. */
|
||||
if ((subshell_environment & SUBSHELL_PIPE) == 0)
|
||||
{
|
||||
pipeline_pgrp = shell_pgrp;
|
||||
itrace("command_substitute: set pipeline_pgrp = shell_pgrp = %d", pipeline_pgrp);
|
||||
}
|
||||
cleanup_the_pipeline ();
|
||||
#endif /* JOB_CONTROL */
|
||||
|
||||
@@ -4687,10 +4685,7 @@ itrace("command_substitute: set pipeline_pgrp = shell_pgrp = %d", pipeline_pgrp)
|
||||
set_sigchld_handler ();
|
||||
stop_making_children ();
|
||||
if (pid != 0)
|
||||
{
|
||||
pipeline_pgrp = old_pipeline_pgrp;
|
||||
itrace("command_substitute: set pipeline_pgrp = %d (old_pipeline_pgrp)", pipeline_pgrp);
|
||||
}
|
||||
#else
|
||||
stop_making_children ();
|
||||
#endif /* JOB_CONTROL */
|
||||
@@ -4797,7 +4792,6 @@ itrace("command_substitute: set pipeline_pgrp = %d (old_pipeline_pgrp)", pipelin
|
||||
|
||||
current_command_subst_pid = pid;
|
||||
last_command_exit_value = wait_for (pid);
|
||||
itrace("command_substitute: waited for pid %d: status %d", pid, last_command_exit_value);
|
||||
last_command_subst_pid = pid;
|
||||
last_made_pid = old_pid;
|
||||
|
||||
@@ -7040,7 +7034,7 @@ add_string:
|
||||
free (temp);
|
||||
temp = temp1;
|
||||
sindex += t_index;
|
||||
goto add_string;
|
||||
goto add_quoted_string; /* XXX was add_string */
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -2370,9 +2370,6 @@ do_assignment_internal (word, expand)
|
||||
|
||||
stupidly_hack_special_variables (name);
|
||||
|
||||
if (entry)
|
||||
VUNSETATTR (entry, att_invisible);
|
||||
|
||||
#if 1
|
||||
/* Return 1 if the assignment seems to have been performed correctly. */
|
||||
if (entry == 0 || readonly_p (entry))
|
||||
@@ -2385,7 +2382,13 @@ do_assignment_internal (word, expand)
|
||||
else
|
||||
retval = 1;
|
||||
ASSIGN_RETURN (retval);
|
||||
|
||||
if (entry && retval != 0)
|
||||
VUNSETATTR (entry, att_invisible);
|
||||
#else
|
||||
if (entry)
|
||||
VUNSETATTR (entry, att_invisible);
|
||||
|
||||
ASSIGN_RETURN (entry ? ((readonly_p (entry) == 0) && noassign_p (entry) == 0) : 0);
|
||||
#endif
|
||||
}
|
||||
@@ -4388,6 +4391,7 @@ process_substitute (string, open_for_read_in_child)
|
||||
#if defined (JOB_CONTROL)
|
||||
set_sigchld_handler ();
|
||||
stop_making_children ();
|
||||
/* XXX - should we only do this in the parent? (as in command subst) */
|
||||
pipeline_pgrp = old_pipeline_pgrp;
|
||||
#endif /* JOB_CONTROL */
|
||||
|
||||
@@ -4677,9 +4681,11 @@ command_substitute (string, quoted)
|
||||
reset_signal_handlers ();
|
||||
|
||||
#if defined (JOB_CONTROL)
|
||||
/* XXX DO THIS ONLY IN PARENT ? XXX */
|
||||
set_sigchld_handler ();
|
||||
stop_making_children ();
|
||||
pipeline_pgrp = old_pipeline_pgrp;
|
||||
if (pid != 0)
|
||||
pipeline_pgrp = old_pipeline_pgrp;
|
||||
#else
|
||||
stop_making_children ();
|
||||
#endif /* JOB_CONTROL */
|
||||
@@ -6692,6 +6698,13 @@ comsub:
|
||||
t_index = zindex + 1;
|
||||
temp = extract_arithmetic_subst (string, &t_index);
|
||||
zindex = t_index;
|
||||
if (temp == 0)
|
||||
{
|
||||
temp = savestring (string);
|
||||
if (expanded_something)
|
||||
*expanded_something = 0;
|
||||
goto return0;
|
||||
}
|
||||
|
||||
/* Do initial variable expansion. */
|
||||
temp1 = expand_arith_string (temp, Q_DOUBLE_QUOTES);
|
||||
|
||||
+2
-2
@@ -142,7 +142,7 @@ freebsd[3-9]*|freebsdelf[3-9]*|freebsdaout[3-9]*|dragonfly*)
|
||||
;;
|
||||
|
||||
# Darwin/MacOS X
|
||||
darwin8*)
|
||||
darwin[89]*)
|
||||
SHOBJ_STATUS=supported
|
||||
SHLIB_STATUS=supported
|
||||
|
||||
@@ -171,7 +171,7 @@ darwin*|macosx*)
|
||||
SHLIB_LIBSUFF='dylib'
|
||||
|
||||
case "${host_os}" in
|
||||
darwin[78]*) SHOBJ_LDFLAGS=''
|
||||
darwin[789]*) SHOBJ_LDFLAGS=''
|
||||
SHLIB_XLDFLAGS='-dynamiclib -arch_only `/usr/bin/arch` -install_name $(libdir)/$@ -current_version $(SHLIB_MAJOR)$(SHLIB_MINOR) -compatibility_version $(SHLIB_MAJOR) -v'
|
||||
;;
|
||||
*) SHOBJ_LDFLAGS='-dynamic'
|
||||
|
||||
+5
-5
@@ -10,7 +10,7 @@
|
||||
# Chet Ramey
|
||||
# chet@po.cwru.edu
|
||||
|
||||
# Copyright (C) 1996-2002 Free Software Foundation, Inc.
|
||||
# Copyright (C) 1996-2007 Free Software Foundation, Inc.
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
@@ -153,7 +153,7 @@ darwin8*)
|
||||
SHLIB_LIBVERSION='$(SHLIB_MAJOR)$(SHLIB_MINOR).$(SHLIB_LIBSUFF)'
|
||||
SHLIB_LIBSUFF='dylib'
|
||||
|
||||
SHOBJ_LDFLAGS='-dynamiclib -dynamic -undefined dynamic_lookup'
|
||||
SHOBJ_LDFLAGS='-dynamiclib -dynamic -undefined dynamic_lookup -arch_only `/usr/bin/arch`'
|
||||
SHLIB_XLDFLAGS='-dynamiclib -arch_only `/usr/bin/arch` -install_name $(libdir)/$@ -current_version $(SHLIB_MAJOR)$(SHLIB_MINOR) -compatibility_version $(SHLIB_MAJOR) -v'
|
||||
|
||||
SHLIB_LIBS='-lncurses' # see if -lcurses works on MacOS X 10.1
|
||||
@@ -247,7 +247,7 @@ osf*)
|
||||
SHLIB_LIBVERSION='$(SHLIB_LIBSUFF).$(SHLIB_MAJOR)'
|
||||
;;
|
||||
|
||||
aix4.[2-9]*-*gcc*) # lightly tested by jik@cisco.com
|
||||
aix4.[2-9]*-*gcc*|aix[5-9].*-*gcc*) # lightly tested by jik@cisco.com
|
||||
SHOBJ_CFLAGS=-fpic
|
||||
SHOBJ_LD='ld'
|
||||
SHOBJ_LDFLAGS='-bdynamic -bnoentry -bexpall'
|
||||
@@ -258,7 +258,7 @@ aix4.[2-9]*-*gcc*) # lightly tested by jik@cisco.com
|
||||
SHLIB_LIBVERSION='$(SHLIB_LIBSUFF).$(SHLIB_MAJOR)'
|
||||
;;
|
||||
|
||||
aix4.[2-9]*)
|
||||
aix4.[2-9]*|aix[5-9].*)
|
||||
SHOBJ_CFLAGS=-K
|
||||
SHOBJ_LD='ld'
|
||||
SHOBJ_LDFLAGS='-bdynamic -bnoentry -bexpall'
|
||||
@@ -329,7 +329,7 @@ hpux10*-*gcc*)
|
||||
SHOBJ_LD='${CC}'
|
||||
# if you have problems linking here, moving the `-Wl,+h,$@' from
|
||||
# SHLIB_XLDFLAGS to SHOBJ_LDFLAGS has been reported to work
|
||||
SHOBJ_LDFLAGS='-shared -Wl,-b -Wl,+s'
|
||||
SHOBJ_LDFLAGS='-shared -fpic -Wl,-b -Wl,+s'
|
||||
|
||||
SHLIB_XLDFLAGS='-Wl,+h,$@ -Wl,+b,$(libdir)'
|
||||
SHLIB_LIBSUFF='sl'
|
||||
|
||||
Reference in New Issue
Block a user