From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 826 invoked by alias); 22 Dec 2017 04:33:31 -0000 Mailing-List: contact zsh-workers-help@zsh.org; run by ezmlm Precedence: bulk X-No-Archive: yes List-Id: Zsh Workers List List-Post: List-Help: List-Unsubscribe: X-Seq: 42156 Received: (qmail 14041 invoked by uid 1010); 22 Dec 2017 04:33:30 -0000 X-Qmail-Scanner-Diagnostics: from mail-io0-f195.google.com by f.primenet.com.au (envelope-from , uid 7791) with qmail-scanner-2.11 (clamdscan: 0.99.2/21882. spamassassin: 3.4.1. Clear:RC:0(209.85.223.195):SA:0(-1.9/5.0):. Processed in 11.959008 secs); 22 Dec 2017 04:33:30 -0000 X-Spam-Checker-Version: SpamAssassin 3.4.1 (2015-04-28) on f.primenet.com.au X-Spam-Level: X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00,SPF_PASS, T_DKIM_INVALID autolearn=ham autolearn_force=no version=3.4.1 X-Envelope-From: dana@dana.is X-Qmail-Scanner-Mime-Attachments: | X-Qmail-Scanner-Zip-Files: | DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=dana-is.20150623.gappssmtp.com; s=20150623; h=from:content-transfer-encoding:mime-version:subject:message-id:date :to; bh=hEGU+3B/Pjp1x0PHEPn++QBzyOsEQpKnKHc2c0CRNrw=; b=WnX17K8tMcf8DYA0rsYQn96/HJKsVYvVmmtMo/pRqDdvXS1ORGHP8OBsl4aaeTCIiX Fu96VFkeMdLU8LR/JYipHArPKqONFBJDpcF1Tm4eZ0SnQ/Fb18IaYmcngG/FSlc1uYlQ B3QOtLqO7PuAGbbsZno6Ho8/JowXu81vgsBxT3FlU0RFVKl/zQMlZRlef4Na9yUa8Et/ 01c+n4farfcGdBFXRyFTKLgerwqj0kdHUXHdND5gUcSeRJecMjk5g1zQUxGxv5RS1R8Y MImbGEhPoyV8I+DUI73YVpwox/ypV4VtV11NLr2IABZ7Mi8JRngs4fRljmt7cqksg0B8 psvA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:content-transfer-encoding:mime-version :subject:message-id:date:to; bh=hEGU+3B/Pjp1x0PHEPn++QBzyOsEQpKnKHc2c0CRNrw=; b=odRqvXf47ypUUU7Vv589+EM5ySnen1mMPP3zm4s/lStBw5fU+LzVMCqgGJyYKmXlpG EtKcPFO6tQIK+FlCPY5SSi4BWE7lpFMrjMg104mvSHGQyuYN6Ggr3LG6iEOX08EssnNw XCZtgdOPtidc5CyjKF9YhvfCtrVz+D2QnlXrDqdJYyrFn0AnayF0r+yp8URP77Gy+k3J qktmBGngyDX5QCDkXoVobpmRgCC3CH7AEcNR9HBjLzUi8BKQHS6JuK+O0z4EPLV9cNpl IFMFitzK71xre9yxmu6wdiD4NbhL4EURfxlQ6Fk+bUZJ7cVQnHMtpnRAgmhzctNYJVSY 8igw== X-Gm-Message-State: AKGB3mKc21AQ7KhhLMO7Lfl+v9aH+iK/dkSM8Vddm60GuwBTwZWfdSvT zeMcVmGluNkWDj2V3J2P/UiOJTgUHRI= X-Google-Smtp-Source: ACJfBosq2as8cGd9j2kw+WHzHz1+cuoS2ghayfpjCP6X+93+/4q5VrSukUcV5Gy8LjFm6cikzD60nQ== X-Received: by 10.107.170.100 with SMTP id t97mr14071080ioe.122.1513917195421; Thu, 21 Dec 2017 20:33:15 -0800 (PST) From: dana Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: quoted-printable Mime-Version: 1.0 (Mac OS X Mail 10.3 \(3273\)) Subject: [PATCH] Add ability to ignore running jobs when check_jobs is set Message-Id: <491C71DF-5618-41F7-9823-A3AE769A3C62@dana.is> Date: Thu, 21 Dec 2017 22:33:13 -0600 To: zsh-workers@zsh.org X-Mailer: Apple Mail (2.3273) A bash convert on IRC wanted to know if there was a way to make the = check_jobs option work more like bash's default behaviour, which is to warn only if = there are stopped/suspended jobs (ignoring running ones). Refer to the = description for bash's own checkjobs option (which is disabled by default) here: = https://www.gnu.org/software/bash/manual/html_node/The-Shopt-Builtin.html This is useful apparently for people who want to be warned if they've = left their editor or something running, but otherwise don't care about background = jobs. Someone also asked for this functionality in users/{6055,15353} (though = they were ultimately given a 'user-land' work-around that solved their = particular issue): https://www.zsh.org/mla/users/2003/msg00351.html https://www.zsh.org/mla/users/2010/msg00653.html It seems like a useful option, and the work required was trivial, so = i've implemented it, along with some other minor things. Full change log: - Add and document check_running_jobs option - Fix minor formatting issue in documentation - Clarify effect of long_list_jobs option - Add tests for many interactive job-control features The tests seem to work well and are much more comprehensive than what = was there before (i.e., almost nothing), but they feel a bit strange somehow. Let = me know if you have any thoughts as to how to make them less brittle or more = idiomatic. dana diff --git a/Doc/Zsh/options.yo b/Doc/Zsh/options.yo index d043cf398..25b3d5736 100644 --- a/Doc/Zsh/options.yo +++ b/Doc/Zsh/options.yo @@ -817,7 +817,7 @@ zsh sessions will all have the new entries from = their history lists added to the history file, in the order that they exit. The file will still be periodically re-written to trim it when the number of lines grows 20% beyond the value specified by -tt($SAVEHIST) (see also the HIST_SAVE_BY_COPY option). +tt($SAVEHIST) (see also the tt(HIST_SAVE_BY_COPY) option). ) pindex(BANG_HIST) pindex(NO_BANG_HIST) @@ -1429,6 +1429,19 @@ ifnzman(the section Special Functions in = noderef(Functions))\ ifzman(the section SPECIAL FUNCTIONS in zmanref(zshmisc)) is not counted for this purpose. ) +pindex(CHECK_RUNNING_JOBS) +pindex(NO_CHECK_RUNNING_JOBS) +pindex(CHECKRUNNINGJOBS) +pindex(NOCHECKRUNNINGJOBS) +cindex(exiting, checking running jobs when) +cindex(logging out, checking running jobs when) +item(tt(CHECK_RUNNING_JOBS) )( +Check for both running and suspended jobs when tt(CHECK_JOBS) is = enabled. +When this option is disabled, zsh checks only for suspended jobs, which +matches the default behavior of bash. + +This option has no effect unless tt(CHECK_JOBS) is set. +) pindex(HUP) pindex(NO_HUP) pindex(NOHUP) @@ -1443,7 +1456,7 @@ pindex(LONGLISTJOBS) pindex(NOLONGLISTJOBS) cindex(jobs, list format) item(tt(LONG_LIST_JOBS) (tt(-R)))( -List jobs in the long format by default. +Print job notifications in the long format by default. ) pindex(MONITOR) pindex(NO_MONITOR) diff --git a/Src/builtin.c b/Src/builtin.c index f002b9912..0211f2721 100644 --- a/Src/builtin.c +++ b/Src/builtin.c @@ -5594,7 +5594,8 @@ checkjobs(void) =20 for (i =3D 1; i <=3D maxjob; i++) if (i !=3D thisjob && (jobtab[i].stat & STAT_LOCKED) && - !(jobtab[i].stat & STAT_NOPRINT)) + !(jobtab[i].stat & STAT_NOPRINT) && + (isset(CHECKRUNNINGJOBS) || jobtab[i].stat & STAT_STOPPED)) break; if (i <=3D maxjob) { if (jobtab[i].stat & STAT_STOPPED) { diff --git a/Src/options.c b/Src/options.c index 2b5795bab..590652ea9 100644 --- a/Src/options.c +++ b/Src/options.c @@ -111,6 +111,7 @@ static struct optname optns[] =3D { {{NULL, "chasedots", OPT_EMULATE}, CHASEDOTS}, {{NULL, "chaselinks", OPT_EMULATE}, CHASELINKS}, {{NULL, "checkjobs", OPT_EMULATE|OPT_ZSH}, CHECKJOBS}, +{{NULL, "checkrunningjobs", OPT_EMULATE|OPT_ZSH}, = CHECKRUNNINGJOBS}, {{NULL, "clobber", OPT_EMULATE|OPT_ALL}, CLOBBER}, {{NULL, "combiningchars", 0}, = COMBININGCHARS}, {{NULL, "completealiases", 0}, = COMPLETEALIASES}, diff --git a/Src/zsh.h b/Src/zsh.h index 24d06ba06..29267b842 100644 --- a/Src/zsh.h +++ b/Src/zsh.h @@ -2338,6 +2338,7 @@ enum { CHASEDOTS, CHASELINKS, CHECKJOBS, + CHECKRUNNINGJOBS, CLOBBER, APPENDCREATE, COMBININGCHARS, diff --git a/Test/W02jobs.ztst b/Test/W02jobs.ztst new file mode 100644 index 000000000..65b860072 --- /dev/null +++ b/Test/W02jobs.ztst @@ -0,0 +1,186 @@ +# Tests for interactive job control + +%prep + + if [[ $OSTYPE =3D=3D cygwin ]]; then + ZTST_unimplemented=3D'the zsh/zpty module does not work on Cygwin' + elif zmodload zsh/zpty 2> /dev/null; then + zpty_start() { + export PS1=3D PS2=3D + zpty -d + zpty zsh "${(q)ZTST_testdir}/../Src/zsh -fiV +Z" + } + zpty_input() { + zpty -w zsh "${(F)@}" $'\n' + } + zpty_stop() { + # exit twice in case of check_jobs + zpty -w zsh $'exit\nexit\n' + # zpty gives no output when piped without these braces (?) + { zpty -r zsh } | sed $'/[^[:space:]]/!d; s/\r$//;' + zpty -d + : + } + else + ZTST_unimplemented=3D'the zsh/zpty module is not available' + fi + +%test + + zpty_start + zpty_input 'setopt no_long_list_jobs' + zpty_input ': &' + zpty_input 'wait' + zpty_stop +0:job notification with no_long_list_jobs +*>\[1] [0-9]## +*>\[1] + done[[:space:]]##: + + zpty_start + zpty_input 'setopt long_list_jobs' + zpty_input ': &' + zpty_input 'wait' + zpty_stop +0:job notification with long_list_jobs +*>\[1] [0-9]## +*>\[1] + [0-9]## done[[:space:]]##: + + zpty_start + zpty_input 'setopt no_hup no_check_jobs' + zpty_input 'sleep 3 &' + zpty_stop +0:running job with no_hup + no_check_jobs +*>\[1] [0-9]## + + zpty_start + zpty_input 'setopt no_check_jobs' + zpty_input 'sleep 3 &' + zpty_stop +0:running job with no_check_jobs +*>\[1] [0-9]## +*>zsh:*SIGHUPed* + + zpty_start + zpty_input 'setopt check_jobs no_check_running_jobs' + zpty_input 'sleep 3 &' + zpty_stop +0:running job with check_jobs + no_check_running_jobs +*>\[1] [0-9]## +*>zsh:*SIGHUPed* + + zpty_start + zpty_input 'setopt check_jobs check_running_jobs' + zpty_input 'sleep 3 &' + zpty_stop +0:running job with check_jobs + check_running_jobs +*>\[1] [0-9]## +*>zsh:*running jobs* +*>zsh:*SIGHUPed* + + zpty_start + zpty_input 'setopt check_jobs no_check_running_jobs' + zpty_input 'sleep 3' + sleep 0.1 + zpty_input $'\C-z' + zpty_stop +0:suspended job with check_jobs + no_check_running_jobs +*>zsh:*(stopped|suspended)*sleep* +*>zsh:*(stopped|suspended) jobs* +# no 'SIGHUPed' message for suspended jobs + + zpty_start + zpty_input 'setopt check_jobs check_running_jobs' + zpty_input 'sleep 3' + sleep 0.1 + zpty_input $'\C-z' + zpty_stop +0:suspended job with check_jobs + check_running_jobs +*>zsh:*(stopped|suspended)*sleep* +*>zsh:*(stopped|suspended) jobs* +# no 'SIGHUPed' message for suspended jobs + + zpty_start + zpty_input 'sleep 5 & sleep 4 & sleep 3 &' + zpty_input 'jobs' + zpty_stop +0:`jobs` (misc.) with multiple running jobs +*>\[1] [0-9]## +*>\[2] [0-9]## +*>\[3] [0-9]## +*>\[1] running*sleep 5* +*>\[2] - running*sleep 4* +*>\[3] + running*sleep 3* +*>zsh:*SIGHUPed* + + zpty_start + zpty_input 'sleep 3 &' + zpty_input 'jobs -l' + zpty_input 'jobs -p' + zpty_stop +0:`jobs -l` and `jobs -p` with running job +*>\[1] [0-9]## +*>\[1] + [0-9]## running*sleep* +*>\[1] + [0-9]## running*sleep* +*>zsh:*SIGHUPed* + + zpty_start + zpty_input 'sleep 3 &' + zpty_input 'jobs -d' + zpty_stop +0:`jobs -d` with running job +*>\[1] [0-9]## +*>\[1] + running*sleep* +*>\(pwd : ?*\) +*>zsh:*SIGHUPed* + + zpty_start + zpty_input 'sleep 3 &' + zpty_input 'jobs -r' + zpty_input 'print -- -' + zpty_input 'jobs -s' + zpty_stop +0:`jobs -r` and `jobs -s` with running job +*>\[1] [0-9]## +*>\[1] + running*sleep* +*>- +*>zsh:*SIGHUPed* + + zpty_start + zpty_input 'sleep 5' + sleep 0.1 + zpty_input $'\C-z' + zpty_input 'jobs -r' + zpty_input 'print -- -' + zpty_input 'jobs -s' + zpty_stop +0:`jobs -r` and `jobs -s` with suspended job +*>zsh:*(stopped|suspended)*sleep* +*>- +*>\[1] + (stopped|suspended)*sleep* +# no 'SIGHUPed' message for suspended jobs + + zpty_start + zpty_input 'sleep 10 & sleep 9 & sleep 8 & sleep 7 &' + sleep 0.1 + zpty_input 'kill %4' + sleep 0.1 + zpty_input 'kill -HUP %3' + sleep 0.1 + zpty_input 'kill -INT %2' + sleep 0.1 + zpty_input 'kill -KILL %1' + sleep 0.1 + zpty_stop +0:various `kill` signals with multiple running jobs +*>\[1] [0-9]## +*>\[2] [0-9]## +*>\[3] [0-9]## +*>\[4] [0-9]## +*>\[4] ? terminate*sleep* +*>\[3] ? hangup*sleep* +*>\[2] ? interrupt*sleep* +*>\[1] ? kill*sleep* + +%clean + + zmodload -ui zsh/zpty