From 866961ad8dd4ebb637fae0d9612d2d9d307840cc Mon Sep 17 00:00:00 2001 From: Chet Ramey Date: Wed, 7 Dec 2011 09:16:10 -0500 Subject: [PATCH] commit bash-20071206 snapshot --- CWRU/CWRU.chlog | 52 +++++++ CWRU/CWRU.chlog~ | 54 ++++++- config-top.h | 4 +- config-top.h~ | 2 +- doc/bash.1 | 12 +- doc/bashref.texi | 8 +- doc/version.texi | 6 +- eval.c | 6 +- execute_cmd.c | 2 - include/shtty.h | 11 ++ include/shtty.h~ | 112 ++++++++++++++ jobs.c | 80 +++++----- jobs.c~ | 87 ++++++++--- lib/readline/display.c | 3 +- lib/sh/shtty.c | 78 ++++++++-- lib/sh/shtty.c~ | 329 +++++++++++++++++++++++++++++++++++++++++ sig.c | 4 +- subst.c | 10 +- subst.c~ | 21 ++- support/shobj-conf | 4 +- support/shobj-conf~ | 10 +- 21 files changed, 785 insertions(+), 110 deletions(-) create mode 100644 include/shtty.h~ create mode 100644 lib/sh/shtty.c~ diff --git a/CWRU/CWRU.chlog b/CWRU/CWRU.chlog index 4e479eb3a..53e640173 100644 --- a/CWRU/CWRU.chlog +++ b/CWRU/CWRU.chlog @@ -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 + +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 + + 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 diff --git a/CWRU/CWRU.chlog~ b/CWRU/CWRU.chlog~ index 79ae7d8d2..0dd356aea 100644 --- a/CWRU/CWRU.chlog~ +++ b/CWRU/CWRU.chlog~ @@ -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 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 + +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 + + 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 diff --git a/config-top.h b/config-top.h index 26ea04036..fe7edde3e 100644 --- a/config-top.h +++ b/config-top.h @@ -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 */ diff --git a/config-top.h~ b/config-top.h~ index 524d4fb9c..26ea04036 100644 --- a/config-top.h~ +++ b/config-top.h~ @@ -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. diff --git a/doc/bash.1 b/doc/bash.1 index 556c8c5fa..c64d70f13 100644 --- a/doc/bash.1 +++ b/doc/bash.1 @@ -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 diff --git a/doc/bashref.texi b/doc/bashref.texi index fbf22a57b..797740d9d 100644 --- a/doc/bashref.texi +++ b/doc/bashref.texi @@ -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 diff --git a/doc/version.texi b/doc/version.texi index 6d23fe956..77b967117 100644 --- a/doc/version.texi +++ b/doc/version.texi @@ -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 diff --git a/eval.c b/eval.c index a1c80b24b..f77b76c87 100644 --- a/eval.c +++ b/eval.c @@ -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; diff --git a/execute_cmd.c b/execute_cmd.c index 4a04920c5..be51a3334 100644 --- a/execute_cmd.c +++ b/execute_cmd.c @@ -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) diff --git a/include/shtty.h b/include/shtty.h index e3e52e366..9d755ec43 100644 --- a/include/shtty.h +++ b/include/shtty.h @@ -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)); diff --git a/include/shtty.h~ b/include/shtty.h~ new file mode 100644 index 000000000..d3a0b0c98 --- /dev/null +++ b/include/shtty.h~ @@ -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 +# define TTYSTRUCT struct termios +#else +# ifdef TERMIO_TTY_DRIVER +# include +# define TTYSTRUCT struct termio +# else /* NEW_TTY_DRIVER */ +# include +# 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 diff --git a/jobs.c b/jobs.c index 6c0dff1a6..df2ef7595 100644 --- a/jobs.c +++ b/jobs.c @@ -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); } diff --git a/jobs.c~ b/jobs.c~ index a5ac42211..eb328a0c1 100644 --- a/jobs.c~ +++ b/jobs.c~ @@ -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 diff --git a/lib/readline/display.c b/lib/readline/display.c index c0532ca05..8cfd693ba 100644 --- a/lib/readline/display.c +++ b/lib/readline/display.c @@ -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])) diff --git a/lib/sh/shtty.c b/lib/sh/shtty.c index 15cc82f80..73394672b 100644 --- a/lib/sh/shtty.c +++ b/lib/sh/shtty.c @@ -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)); } diff --git a/lib/sh/shtty.c~ b/lib/sh/shtty.c~ new file mode 100644 index 000000000..2381ee2fa --- /dev/null +++ b/lib/sh/shtty.c~ @@ -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 +#endif + +#ifdef HAVE_UNISTD_H +# include +#endif + +#include + +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)); +} diff --git a/sig.c b/sig.c index 5bb91e0b3..f6c4b42c9 100644 --- a/sig.c +++ b/sig.c @@ -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; diff --git a/subst.c b/subst.c index 306092e44..0a74b9d08 100644 --- a/subst.c +++ b/subst.c @@ -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 { diff --git a/subst.c~ b/subst.c~ index 56a6294fd..c9171b168 100644 --- a/subst.c~ +++ b/subst.c~ @@ -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); diff --git a/support/shobj-conf b/support/shobj-conf index e467dd9d0..358b27815 100755 --- a/support/shobj-conf +++ b/support/shobj-conf @@ -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' diff --git a/support/shobj-conf~ b/support/shobj-conf~ index 2f163913d..e467dd9d0 100755 --- a/support/shobj-conf~ +++ b/support/shobj-conf~ @@ -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' -- 2.47.3