diff --git a/tcsh-6.18.01-wait-hang.patch b/tcsh-6.18.01-wait-hang.patch new file mode 100644 index 0000000..24aff3a --- /dev/null +++ b/tcsh-6.18.01-wait-hang.patch @@ -0,0 +1,91 @@ +From 788faac41b56f8b08e60f3456ad56c5a36fffa4c Mon Sep 17 00:00:00 2001 +From: Pavel Raiskup +Date: Tue, 27 Jan 2015 07:05:26 +0100 +Subject: [PATCH 16/16] tcsh: fix 'wait' hang + +Make sure that SIGCHLD is blocked before we call +handle_pending_signals() for the first time and before we actually +check for pp->p_flags & PRUNNING to make sure that the SIGCHLD is +not leaked meanwhile. + +Resolves: rhbz#1181685 + +--- + Fixes | 4 ++++ + sh.proc.c | 26 +++++++++++++++++++++++++- + 2 files changed, 29 insertions(+), 1 deletion(-) + +diff --git a/Fixes b/Fixes +index 8eac9d4..56915a9 100644 +--- a/Fixes ++++ b/Fixes +@@ -1,3 +1,7 @@ ++ 29. Pavel Raiskup fix hang with: ++ while (1) ++ ( date & ; wait ) ++ end + 6. V6.18.01 - 20120214 + 5. fix interruptible wait again + 4. ignore bogus compiler overflow message +diff --git a/sh.proc.c b/sh.proc.c +index e32ebda..0c5fc25 100644 +--- a/sh.proc.c ++++ b/sh.proc.c +@@ -593,22 +593,44 @@ void + dowait(Char **v, struct command *c) + { + struct process *pp; ++ ++ /* the current block mask to be able to restore */ ++ sigset_t old_mask; ++ ++ /* block mask for critical section: OLD_MASK U {SIGCHLD} */ ++ sigset_t block_mask; ++ ++ /* ignore those during blocking sigsuspend: ++ OLD_MASK / {SIGCHLD, possibly(SIGINT)} */ + sigset_t pause_mask; ++ + int opintr_disabled, gotsig; + + USE(c); + USE(v); + pjobs++; ++ + sigprocmask(SIG_BLOCK, NULL, &pause_mask); + sigdelset(&pause_mask, SIGCHLD); + if (setintr) + sigdelset(&pause_mask, SIGINT); ++ ++ /* critical section, block also SIGCHLD */ ++ sigprocmask(SIG_BLOCK, NULL, &block_mask); ++ sigaddset(&block_mask, SIGCHLD); ++ sigprocmask(SIG_BLOCK, &block_mask, &old_mask); ++ ++ /* detect older SIGCHLDs and remove PRUNNING flag from proclist */ ++ (void)handle_pending_signals(); ++ + loop: + for (pp = proclist.p_next; pp; pp = pp->p_next) + if (pp->p_procid && /* pp->p_procid == pp->p_jobid && */ + pp->p_flags & PRUNNING) { +- (void)handle_pending_signals(); ++ /* wait for (or pick up alredy blocked) SIGCHLD */ + sigsuspend(&pause_mask); ++ ++ /* make the 'wait' interuptable by CTRL-C */ + opintr_disabled = pintr_disabled; + pintr_disabled = 0; + gotsig = handle_pending_signals(); +@@ -618,6 +640,8 @@ loop: + goto loop; + } + pjobs = 0; ++ ++ sigprocmask(SIG_SETMASK, &old_mask, NULL); + } + + /* +-- +2.1.0 + diff --git a/tcsh.spec b/tcsh.spec index 6e5b6c5..96c0c4e 100644 --- a/tcsh.spec +++ b/tcsh.spec @@ -1,7 +1,7 @@ Summary: An enhanced version of csh, the C shell Name: tcsh Version: 6.18.01 -Release: 12%{?dist} +Release: 13%{?dist} License: BSD Group: System Environment/Shells Source: http://ftp.funet.fi/pub/unix/shells/tcsh/%{name}-%{version}.tar.gz @@ -27,6 +27,11 @@ Patch36: tcsh-6.18.01-introduce-tcsh_posix_status.patch Patch37: tcsh-6.18.01-reverse-history-handling-in-loops.patch Patch38: tcsh-6.18.01-skip-tty-tests.patch +# wait hang fix +# ~> #1181685 +# ~> upstream: git diff 9178ceb5..0d8de594 +Patch39: tcsh-6.18.01-wait-hang.patch + Provides: csh = %{version} Provides: /bin/tcsh, /bin/csh Requires(post): grep @@ -46,14 +51,14 @@ like syntax. %prep -%autosetup -p1 -S git - for i in Fixes WishList; do iconv -f iso-8859-1 -t utf-8 "$i" > "${i}_" && \ touch -r "$i" "${i}_" && \ mv "${i}_" "$i" done +%autosetup -p1 -S git + %build # For tcsh-6.14.00-tinfo.patch @@ -131,6 +136,11 @@ fi %changelog +* Tue Jan 27 2015 Pavel Raiskup - 6.18.01-13 +- fix 'wait' built-in hang (#1181685) +- call %%autosetup after iconv, this avoids having uncommitted changes in + srcdir after patches are applied + * Wed Aug 27 2014 Pavel Raiskup - 6.18.01-12 - use the %%autosetup macro - enable testsuite in %%check