diff options
author | Axel Beckert <abe@deuxchevaux.org> | 2014-01-05 21:25:07 +0100 |
---|---|---|
committer | Axel Beckert <abe@deuxchevaux.org> | 2014-01-05 21:25:07 +0100 |
commit | 8f137a4ae2a5c93918760cb960539d17e56560e0 (patch) | |
tree | 9fbe622e12f91733b7e4a7e8609edd3516452709 | |
parent | f07aa702dda26a4fb5f4dab71dc895109f304808 (diff) | |
parent | 79abe00e1d73b3f0681343a70e3e7f84e5e3d647 (diff) | |
download | zsh-8f137a4ae2a5c93918760cb960539d17e56560e0.tar.gz zsh-8f137a4ae2a5c93918760cb960539d17e56560e0.zip |
New upstream release
(Merge branch 'upstream' into debian)
-rw-r--r-- | ChangeLog | 102 | ||||
-rw-r--r-- | Completion/Base/Completer/_expand | 4 | ||||
-rw-r--r-- | Completion/Linux/Command/_sysstat | 150 | ||||
-rw-r--r-- | Completion/Solaris/Command/_svcadm | 9 | ||||
-rw-r--r-- | Completion/Solaris/Command/_zoneadm | 20 | ||||
-rw-r--r-- | Completion/Unix/Command/_chmod | 6 | ||||
-rw-r--r-- | Completion/Unix/Command/_zfs | 139 | ||||
-rw-r--r-- | Completion/Unix/Command/_zpool | 21 | ||||
-rw-r--r-- | Completion/Unix/Type/_zfs_dataset | 3 | ||||
-rw-r--r-- | Completion/Zsh/Command/_cd | 4 | ||||
-rw-r--r-- | Config/version.mk | 4 | ||||
-rw-r--r-- | Doc/Zsh/compsys.yo | 8 | ||||
-rw-r--r-- | Etc/FAQ.yo | 145 | ||||
-rw-r--r-- | LICENCE | 10 | ||||
-rw-r--r-- | MACHINES | 3 | ||||
-rw-r--r-- | README | 7 | ||||
-rw-r--r-- | Src/Zle/zle_misc.c | 2 | ||||
-rw-r--r-- | Src/Zle/zle_tricky.c | 11 | ||||
-rw-r--r-- | Src/exec.c | 9 | ||||
-rw-r--r-- | Src/jobs.c | 42 | ||||
-rw-r--r-- | Src/params.c | 8 | ||||
-rw-r--r-- | Test/A05execution.ztst | 14 | ||||
-rw-r--r-- | Test/Y01completion.ztst | 24 |
23 files changed, 678 insertions, 67 deletions
@@ -1,3 +1,97 @@ +2014-01-05 Peter Stephenson <p.w.stephenson@ntlworld.com> + + * unposted: Config/version.mk, Doc/Zsh/compsys.yo: update + release to 5.0.5 and correct typo in compsys.yo making texinfo + format unusable. + + * unposted but c.f. 32231: Doc/Zsh/compsys.yo: the parameter + 'line' doesn't include the original command. + + * Jun T: 32231: Completion/Unix/Command/_chmod: was confused by + options before the mode argument. + + * Axel Beckert: 32229: LICENCE: was not correctly referring to + Gnu General Public License. + +2014-01-03 Peter Stephenson <p.w.stephenson@ntlworld.com> + + * unposted: README: update another reference to 5.0.5. + + * users/18271 plus some additional rewriting: Etc/FAQ.yo: add + FAQ entry to explain pattern exclusions. + + * unposted: README, Etc/FAQ.yo: update source documentation for + 5.0.5. + +2014-01-02 Peter Stephenson <p.w.stephenson@ntlworld.com> + + * Danek Duvall: 32216: Completion/Solaris/Command/_svcadm, + Completion/Solaris/Command/_zoneadm, + Completion/Unix/Command/_zfs, Completion/Unix/Command/_zpool, + Completion/Unix/Type/_zfs_dataset: updates for Solaris 11, + Update 1. + + * 32196: Carl Drougge: Src/Zle/zle_misc.c: copy-prev-shell-word + needs an extra flag to work properly. + +2013-12-31 Barton E. Schaefer <schaefer@zsh.org> + + * Eric Cook: 32210: Completion/Linux/Command/_sysstat: completion + for mpstat, iostat, etc. + +2013-12-30 Barton E. Schaefer <schaefer@zsh.org> + + * 32208: Src/params.c: always reset pathchecked when the path + array is modified in arrvarsetfn(), to avoid bad dereference + + * 32205: Completion/Zsh/Command/_cd: skip cdpath search when + the prefix begins with "../" (bug introduced by 31714) + + * unposted (cf. Carlo: 32202): MACHINES: OS X 10.9.1. gcc problem + +2013-12-28 Barton E. Schaefer <schaefer@zsh.org> + + * 32190 (cf. Alexey Bezhan: 32189): Completion/Zsh/Command/_cd: + quote _path_files -W path in case of spaces or special characters + when completing relative to ../ + + * 32186: Completion/Base/Completer/_expand: fix bad backreference; + handle glob patterns that include backslashed quote characters + +2013-12-26 Barton E. Schaefer <schaefer@zsh.org> + + * unposted (cf. Jun Takimoto: 32184): Test/comptest, + Test/Y01completion.ztst: back 32183 out of comptest and instead + reset path in the individual tests in Y01completion.ztst + +2013-12-25 Barton E. Schaefer <schaefer@zsh.org> + + * 32183: Test/comptest, Test/Y01completion.ztst: regression tests + for 32182 and 31611 + + * 32182: Src/Zle/zle_tricky.c: re-enable command completion after + a separator (tweak to 31611) + + * 32178: Src/jobs.c: fix another acquire_pgrp() infinite loop + +2013-12-21 Barton E. Schaefer <schaefer@zsh.org> + + * PWS + Bart: 32176: plug additional descriptor leaks causing + deadlock via different code paths; expand regression test + +2013-12-21 Peter Stephenson <p.w.stephenson@ntlworld.com> + + * Config/version.mk: update version to 5.0.4-dev-0 so as + not to clash with release. + +2013-12-20 Barton E. Schaefer <schaefer@zsh.org> + + * 32172; Test/A05execution.ztst: regression test for 32171 + + * 32171: Src/exec.c: fix leaked pipe descriptor that could + deadlock a pipeline from a complex shell construct or function + into an external command + 2013-12-20 Peter Stephenson <p.w.stephenson@ntlworld.com> * unposted: Config/version.mk, Etc/FAQ.yo, README: release 5.0.4. @@ -31,10 +125,12 @@ * unposted: NEWS: add ZLE_PROMPT_INDENT. + * 32119: Src/Zle/zle_tricky.c: left square bracket completed in + command position is not part of a subscript expression + * Patrick Oscity + pws: 32114: Doc/Zsh/params.yo, - Src/Zle/zle_refresh.c, Src/Zle/zle_tricky.c: ZLE_RPROMPT_INDENT - allows you to make the right prompt flush if your terminal - supports it. + Src/Zle/zle_refresh.c: ZLE_RPROMPT_INDENT allows you to make the + right prompt flush if your terminal supports it. 2013-12-16 Barton E. Schaefer <schaefer@zsh.org> diff --git a/Completion/Base/Completer/_expand b/Completion/Base/Completer/_expand index 44954a2a8..e52144cb7 100644 --- a/Completion/Base/Completer/_expand +++ b/Completion/Base/Completer/_expand @@ -103,8 +103,8 @@ subd=("$exp[@]") # Now try globbing. [[ "$force" = *g* ]] || zstyle -T ":completion:${curcontext}:" glob && - eval 'exp=( ${~exp//(#b)\\[ -]/$match[1]} ); exp=( ${(q)exp} )' 2>/dev/null + eval 'exp=( ${~exp//(#b)\\([ \"'"\'"' +])/$match[1]} ); exp=( ${(q)exp} )' 2>/dev/null ### Don't remember why we once used this instead of the (q) above. # eval 'exp=( ${~exp} ); exp=( ${exp//(#b)([][()|*?^#~<>\\=])/\\${match[1]}} )' 2>/dev/null diff --git a/Completion/Linux/Command/_sysstat b/Completion/Linux/Command/_sysstat new file mode 100644 index 000000000..60de9d899 --- /dev/null +++ b/Completion/Linux/Command/_sysstat @@ -0,0 +1,150 @@ +#compdef -P mpstat (|cifs)iostat isag sadf sar pidstat +# -V can appear with other options, so (- *) isn't needed. +#TODO: +# sysstat-nfsiostat - there seems to be two nfsiostat(1)s. one from oracle and one by redhat. + +_mpstat() { + local ret=1 + _arguments : \ + '-A[equivalent to -u -I ALL -P ALL]' \ + '-I[report interrupt statistics]:interrupts:(SUM CPU SCPU ALL)' \ + '-P[specify processor number]:processor: _values -s "," processor ON ALL' \ + '-u[report CPU utilization]' \ + '-V[print version number]' \ + '1:interval:_guard "[0-9]#" "interval"' \ + '2:count:_guard "[0-9]#" "count"' && ret=0 + return ret +} + +_iostat() { + local ret=1 + _arguments : \ + '-c[display CPU utilization report]' \ + '-d[display device utilization report]' \ + '-T[only display global statistics for group_name]' \ + '-g[display statistics for a group of devices]:group name: _message "group name"' \ + '-h[human readable device utilization report]' \ + '-j[display persistent device name]' \ + '(-m)-k[display statistics in kB/s]' \ + '(-k)-m[display statistics in MB/s]' \ + '-N[display registered device mapper names]' \ + '1:interval:_guard "[0-9]#" "interval"' \ + '2:count:_guard "[0-9]#" "count"' && ret=0 + return ret +} + +_cifsiostat() { + local ret=1 + _arguments : \ + '-h[human readable]' \ + '(-m)-k[display statistics in kB/s]' \ + '(-k)-m[display statistics in MB/s]' \ + '-t[print timestamp for each report]' \ + '-V[print version number]' \ + '1:interval:_guard "[0-9]#" "interval"' \ + '2:count:_guard "[0-9]#" "count"' && ret=0 + return ret +} + +_isag() { + local ret=1 + _arguments : \ + '-p[Pathname to daily data files]:data files: _files -/' \ + '-c[Specify configuration file]:configuration file: _files' \ + '-ght[Specify height of the chart]:height: _message "height"' \ + '-gwd[Specify width of the chart]:width: _message "width"' && ret=0 + return ret +} + +_sadf() { + local ret=1 line state context expl + typeset -A opt_args + # any options after `--' are for sar(1) + if ! (( CURRENT > $words[(i)--] )); then + _arguments : \ + '-C[display comments in file]' \ + '(-j -p -x)-d[output file in SQL format]' \ + '-e[set ending time of report]:ending time: _message "ending time in localtime(HH\:MM\:SS 24-hour format)"' \ + '-H[display only the header of the report]' \ + '(-j -p -x)-h[print on a single line when used with -d]' \ + '(-d -p -x)-j[output file in JSON]' \ + '-P[restrict processor dependant statistics]:processor number(zero indexed) or ALL:(ALL)' \ + '(-j -x -d)-p[print in format parsable by tools like awk]' \ + '-s[set starting time of report]:starting time: _message "starting time in localtime(HH\:MM\:SS 24-hour format)"' \ + '(-t -U)-T[display timestamp in local time]' \ + '(-T -U)-t[display timestamp in file\''s original localtime]' \ + '(-t -T)-U[display in seconds from epoch(UTC)]' \ + '-V[print version number]' \ + '(-j -d -p)-x[output file in XML]' \ + '1:interval:_guard "[0-9]#" "interval"' \ + '2:count:_guard "[0-9]#" "count"' && ret=0 + else + _arguments : '*::sar: _sar' && ret=0 + fi + return ret +} + +_sar() { + local ret=1 + _arguments : \ + '-A[equivalent to -bBdFHqrRSuvwWy -I SUM -I XALL -m ALL -n ALL -u ALL -P ALL]' \ + '-B[report paging statistics]' \ + '-b[report I/O and transfer rate statistics]' \ + '-C[display comments from sadc]' \ + '-d[report activity for each block device]' \ + '-e[set ending time of report]:ending time: _message "ending time (HH\:MM\:SS 24-hour format)"' \ + '-F[display statistics for mounted filesystems]' \ + '-f[extract records from file]:record:_files' \ + '-H[report hugepages utilization]' \ + '-h[display help]' \ + '*-I[report statistics for interrupts]:interrupts: _values -s "," interrupts 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 SUM ALL XALL' \ + '-i[select records as close as possible to interval]:interval: _message "interval"' \ + '-j[display persistent device names]:type:(ID LABEL PATH UUID)' \ + '-m[report power management statistics]:keywords: _values -s "," keywords CPU FAN FREQ IN TEMP USB ALL' \ + '-n[report network statistics]:keywords: _values -s "," keywords DEV EDEV NFS NFSD SOCK IP EIP ICMP EICMP TCP ETCP UDP SOCK6 IP6 EIP6 ICMP6 EICMP6 UDP6 ALL' \ + '-P[report per-processor statistics]:processor: _values -s "," processors ALL' \ + '-p[pretty-print device names]' \ + '-q[report queue length and load averages]' \ + '-R[report memory statistics]' \ + '-r[report memory utilization statistics]' \ + '-S[report swap space utilization]' \ + '-s[set starting time of report]:start time: _message "start time (HH\:MM\:SS 24-hour format)"' \ + '-u[report CPU utilization]: :(ALL)' \ + '-V[print version number]' \ + '-v[report status of kernel tables]' \ + '-W[report swapping statistics]' \ + '-w[report task creation and system switching activity]' \ + '-y[report TTY device activity]' \ + '1:interval:_guard "[0-9]#" "interval"' \ + '2:count:_guard "[0-9]#" "count"' && ret=0 + return ret +} + +_pidstat() { + local ret=1 + _arguments : \ + '-C[filter tasks by string]:task: _message "string or regex"' \ + '-d[report I/O statistics]' \ + '-h[display on horizontally]' \ + '-I[divide CPU usage by number of processors]' \ + '-l[display process name along with arguments]' \ + '-p[select pid]:pid: _pids' \ + '-r[report page faults and memory]' \ + '-s[report stack utilization]' \ + '-T[specifies what to monitor]:type:(TASK CHILD ALL)' \ + '-t[display statistics for threads]' \ + '-U[display real username of tasks]::username:_users' \ + '-u[report cpu utilization]' \ + '-V[print version number]' \ + '-v[display values from kernel table]' \ + '-w[report task switching activity]' && ret=0 + return ret +} + +_sysstat() { + local ret=1 + _call_function ret _$service + return ret +} + +_sysstat "$@" diff --git a/Completion/Solaris/Command/_svcadm b/Completion/Solaris/Command/_svcadm index f24675b41..347e25e2a 100644 --- a/Completion/Solaris/Command/_svcadm +++ b/Completion/Solaris/Command/_svcadm @@ -24,6 +24,7 @@ _svcadm() { _arguments -A "-*" \ '-r[Recursively enable dependencies]' \ '-s[Wait for service to come online]' \ + '-T[Timeout for -s]:seconds:' \ '-t[State change is temporary]' \ '*:instance FMRI:_svcs_fmri -i' ;; @@ -31,6 +32,7 @@ _svcadm() { (disable) _arguments -A "-*" \ '-s[Wait for service to become disabled]' \ + '-T[Timeout for -s]:seconds:' \ '-t[State change is temporary]' \ '*:instance FMRI:_svcs_fmri -i' ;; @@ -38,6 +40,8 @@ _svcadm() { (mark) _arguments -A "-*" \ '-I[Change state immediately]' \ + "-s[Wait for service to reach the new state]" \ + '-T[Timeout for -s]:seconds:' \ '-t[State change is temporary]' \ ':state:(degraded maintenance)' \ ':instance FMRI:_svcs_fmri -i' @@ -45,12 +49,15 @@ _svcadm() { (restart|refresh|clear) _arguments \ + "-s[Wait for service to $service]" \ + '-T[Timeout for -s]:seconds:' \ '*:instance FMRI:_svcs_fmri -i' ;; (delegate) _arguments -A "-*" \ '-s[Wait for instances to come online]' \ + '-T[Timeout for -s]:seconds:' \ ':restarter FMRI:_svcs_fmri -r' \ '*:FMRI:_svcs_fmri -i' ;; @@ -58,6 +65,8 @@ _svcadm() { (milestone) _arguments -A "-*" \ '-d[Make milestone the default]' \ + '-s[Wait for the transition to the new milestone]' \ + '-T[Timeout for -s]:seconds:' \ '*:milestone FMRI:_svcs_fmri -m' ;; diff --git a/Completion/Solaris/Command/_zoneadm b/Completion/Solaris/Command/_zoneadm index 3f42673e1..ab63dc0b6 100644 --- a/Completion/Solaris/Command/_zoneadm +++ b/Completion/Solaris/Command/_zoneadm @@ -1,5 +1,5 @@ #compdef zoneadm -# Synced with the S11U1 build 19 man page +# Synced with the S11U1 man page _zoneadm_bootargs() { # This is a subset of the arguments to kernel(1M) @@ -15,6 +15,7 @@ _zoneadm() { local -a subcmds fields local -a solaris_attach solaris_install local -a solaris10_attach solaris10_install + local -a extended_create_options extended_destroy_options local brand brand_args subcmds=( @@ -22,6 +23,17 @@ _zoneadm() { ready reboot uninstall verify ) + extended_create_options=( + "force-zpool-import" + "force-zpool-create:ZFS pool: " + "force-zpool-create-all" + ) + + extended_destroy_options=( + "force-zpool-destroy:ZFS pool: " + "force-zpool-destroy-all" + ) + solaris_attach=( '(-d)-a[Path to archive]:path:_path_files' '(-a)-d[Path to zonepath]:directory:_path_files -/' @@ -82,6 +94,7 @@ _zoneadm() { _arguments -A "-*" \ '-m[Clone mode]:mode:_values "mode" copy' \ '-s[Source snapshot]:snapshot:_zfs_dataset -t snap' \ + '-x[Extended options]:extended option:_values -w "extended option" $extended_create_options' \ ':source zone:_zones' ;; @@ -94,6 +107,7 @@ _zoneadm() { '-F[Force attach]' \ '-n[Path to zone manifest]:path to zone manifest:_path_files' \ '-u[Update on attach]' \ + '-x[Extended options]:extended option:_values -w "extended option" $extended_create_options' \ ${(P)brand_args} ;; @@ -116,6 +130,7 @@ _zoneadm() { brand_args=${brand}_install fi _arguments -A "-*" \ + '-x[Extended options]:extended option:_values -w "extended option" $extended_create_options' \ ${(P)brand_args} ;; @@ -139,7 +154,8 @@ _zoneadm() { ("uninstall") _arguments -A "-*" \ - '-F[Force]' + '-F[Force]' \ + '-x[Extended options]:extended option:_values -w "extended option" $extended_destroy_options' ;; esac } diff --git a/Completion/Unix/Command/_chmod b/Completion/Unix/Command/_chmod index 6cb310d57..5d3cb2c78 100644 --- a/Completion/Unix/Command/_chmod +++ b/Completion/Unix/Command/_chmod @@ -57,12 +57,12 @@ case "$state" in zmodload -F zsh/stat b:zstat 2>/dev/null typeset -i8 ref=$(zstat +mode $opt_args[--reference]) _wanted files expl file _files -g "*(-.^f${ref#??})" && ret=0 - elif [[ $words[2] = [0-7]## ]]; then - _wanted files expl file _files -g "*(-.^f$words[2])" && ret=0 + elif [[ $line[1] = [0-7]## ]]; then + _wanted files expl file _files -g "*(-.^f$line[1])" && ret=0 else local spec who op priv local -a specs - for spec in ${(s:,:)words[2]}; do + for spec in ${(s:,:)line[1]}; do if [[ ${spec#*[+-=]} != [rwxst]## ]]; then _files && ret=0 return ret diff --git a/Completion/Unix/Command/_zfs b/Completion/Unix/Command/_zfs index 4cc24a59f..a9707ce36 100644 --- a/Completion/Unix/Command/_zfs +++ b/Completion/Unix/Command/_zfs @@ -1,10 +1,13 @@ #compdef zfs -# Synced with the S11U1 build 20 man page +# Synced with the S11U1 man page _zfs() { local context state line expl typeset -A opt_args local -a subcmds rw_properties rw_propnames ro_properties create_properties + local -a share_nfs_ro_properties share_nfs_rw_properties + local -a share_smb_ro_properties share_nfs_rw_properties + local -a share_ro_properties share_rw_properties local -a difffields delegatable_perms subcmds=( @@ -15,6 +18,115 @@ _zfs() { "diff" "key" "help" ) + share_nfs_ro_properties=( + "share.nfs.all" + ) + + share_nfs_rw_properties=( + "share.nfs:value:(on off)" + "share.nfs.aclok:value:(on off)" + "share.nfs.acflfab:value:(on off)" + "share.nfs.anon:uid:" + "share.nfs.charset.euc-cn:access-list:" + "share.nfs.charset.euc-jpms:access-list:" + "share.nfs.charset.euc-kr:access-list:" + "share.nfs.charset.euc-tw:access-list:" + "share.nfs.charset.iso8859-1:access-list:" + "share.nfs.charset.iso8859-2:access-list:" + "share.nfs.charset.iso8859-5:access-list:" + "share.nfs.charset.iso8859-6:access-list:" + "share.nfs.charset.iso8859-7:access-list:" + "share.nfs.charset.iso8859-8:access-list:" + "share.nfs.charset.iso8859-9:access-list:" + "share.nfs.charset.iso8859-13:access-list:" + "share.nfs.charset.iso8859-15:access-list:" + "share.nfs.charset.koi8-r:access-list:" + "share.nfs.index:file:_files" + "share.nfs.log:nfslog.conf tag:" + "share.nfs.nosub:value:(on off)" + "share.nfs.nosuid:value:(on off)" + "share.nfs.public:value:(on off)" + "share.nfs.sec:security-mode-list:" + "share.nfs.sec.default.none:access-list:" + "share.nfs.sec.default.ro:access-list:" + "share.nfs.sec.default.root:access-list:" + "share.nfs.sec.default.root_mapping:uid:" + "share.nfs.sec.default.rw:access-list:" + "share.nfs.sec.default.window:seconds" + "share.nfs.sec.dh.none:access-list:" + "share.nfs.sec.dh.ro:access-list:" + "share.nfs.sec.dh.root:access-list:" + "share.nfs.sec.dh.root_mapping:uid:" + "share.nfs.sec.dh.rw:access-list:" + "share.nfs.sec.dh.window:seconds" + "share.nfs.sec.krb5.none:access-list:" + "share.nfs.sec.krb5.ro:access-list:" + "share.nfs.sec.krb5.root:access-list:" + "share.nfs.sec.krb5.root_mapping:uid:" + "share.nfs.sec.krb5.rw:access-list:" + "share.nfs.sec.krb5.window:seconds" + "share.nfs.sec.krb5i.none:access-list:" + "share.nfs.sec.krb5i.ro:access-list:" + "share.nfs.sec.krb5i.root:access-list:" + "share.nfs.sec.krb5i.root_mapping:uid:" + "share.nfs.sec.krb5i.rw:access-list:" + "share.nfs.sec.krb5i.window:seconds" + "share.nfs.sec.krb5p.none:access-list:" + "share.nfs.sec.krb5p.ro:access-list:" + "share.nfs.sec.krb5p.root:access-list:" + "share.nfs.sec.krb5p.root_mapping:uid:" + "share.nfs.sec.krb5p.rw:access-list:" + "share.nfs.sec.krb5p.window:seconds" + "share.nfs.sec.none.none:access-list:" + "share.nfs.sec.none.ro:access-list:" + "share.nfs.sec.none.root:access-list:" + "share.nfs.sec.none.root_mapping:uid:" + "share.nfs.sec.none.rw:access-list:" + "share.nfs.sec.none.window:seconds" + "share.nfs.sec.sys.none:access-list:" + "share.nfs.sec.sys.ro:access-list:" + "share.nfs.sec.sys.root:access-list:" + "share.nfs.sec.sys.root_mapping:uid:" + "share.nfs.sec.sys.rw:access-list:" + "share.nfs.sec.sys.window:seconds" + ) + + share_smb_ro_properties=( + "share.smb.all" + ) + + share_smb_rw_properties=( + "share.smb:value:(on off)" + "share.smb.ad-container" + "share.smb.abe" + "share.smb.csc:value:(disabled manual auto vdo)" + "share.smb.catia:value:(on off)" + "share.smb.dfsroot:value:(on off)" + "share.smb.guestok:value:(on off)" + "share.smb.ro:access-list:" + "share.smb.rw:access-list:" + "share.smb.none:access-list:" + ) + + share_ro_properties=( + "share.all" + "share.fs" + "share.name" + "share.point" + "share.protocols" + "share.state" + $share_nfs_ro_properties + $share_smb_ro_properties + ) + + share_rw_properties=( + "share.desc:description:" + "share.noauto:value:(on off)" + "share.path:path:" + $share_nfs_rw_properties + $share_smb_rw_properties + ) + # TODO: userused@ and groupused@ could have more extensive handling ro_properties=( "name" "type" "creation" "used" "available" "referenced" @@ -22,6 +134,7 @@ _zfs() { "usedbydataset" "usedbyrefreservation" "usedbysnapshots" "defer_destroy" "userused@" "userrefs" "groupused@" "keychangedate" "keystatus" "rekeydate" + $share_ro_properties ) # TODO: Be cleverer about what values can be set. Is there any way to @@ -57,8 +170,6 @@ _zfs() { "setuid:value:(on off)" "shadow:value:" # TODO: complete URI|none "share:share properties:" - "sharenfs:value:(on off)" - "sharesmb:value:(on off)" "snapdir:value:(hidden visible)" "sync:value:(standard always disabled)" "userquota@:value:" # TODO: complete user=size|none @@ -67,6 +178,7 @@ _zfs() { "vscan:value:(on off)" "xattr:value:(on off)" "zoned:value:(on off)" + $share_rw_properties ) create_properties=( @@ -246,7 +358,14 @@ _zfs() { - set1 \ '-a[Share all available ZFS filesystems]' \ - set2 \ - ':filesystem:_zfs_dataset -t fs' + '-r[Share filesystems recursively]' \ + ':filesystem:_zfs_dataset -t fs' \ + - set3 \ + '*-o[Create a share with these properties]:property:_values -w "share properties" $share_rw_properties' \ + '-u[Create a share without sharing it]' \ + ':filesystem:_zfs_dataset -t fs' \ + - set4 \ + ':filesystem:_zfs_dataset -t fs -t mtpt -t share' ;; ("unshare") @@ -254,7 +373,10 @@ _zfs() { - set1 \ '-a[Unshare all shared ZFS filesystems]' \ - set2 \ - ':filesystem:_zfs_dataset -t fs -t mtpt' + '-r[Unshare filesystems recursively]' \ + ':filesystem:_zfs_dataset -t fs' \ + - set3 \ + ':filesystem:_zfs_dataset -t fs -t mtpt -t share' ;; ("send") @@ -410,7 +532,12 @@ _zfs() { ;; ("help") - compadd property $subcmds $ro_properties ${rw_properties%%:*} + _arguments -A "-*" \ + - set1 \ + ':command:($subcmds $delegatable_perms $ro_properties ${rw_properties%%:*} properties)' \ + - set2 \ + '-l[Display property information]' \ + ': :(properties)' ;; (*) diff --git a/Completion/Unix/Command/_zpool b/Completion/Unix/Command/_zpool index 0af2ab32d..0f18eefb5 100644 --- a/Completion/Unix/Command/_zpool +++ b/Completion/Unix/Command/_zpool @@ -1,5 +1,5 @@ #compdef zpool -# Synced with the S11U1 build 19 man page +# Synced with the S11U1 man page _zpool() { local context state line expl @@ -8,7 +8,7 @@ _zpool() { subcmds=( create destroy add remove list iostat status online offline clear attach detach replace scrub import export - upgrade history get set split + upgrade history get set split help ) versions=( @@ -35,7 +35,9 @@ _zpool() { "dedupditto[Threshold for number of copies]:value:" "delegation[Delegated administration]:value:(on off)" "failmode[Failure-mode behavior]:value:(wait continue panic)" + "listshares[Show shares in 'zfs list']:value:(on off)" "listsnaps[Show snapshots in 'zfs list']:value:(on off)" + "readonly[Controls whether the pool can be modified]:value:(on off)" "version[Pool version]:version:($versions)" ) @@ -97,9 +99,19 @@ _zpool() { fi case $service in + (help) + _arguments -A "-*" \ + - set1 \ + ':command/property:($subcmds ${fields%%\[*} properties)' \ + - set2 \ + '-l[Display property information]' \ + ': :(properties)' + ;; + (clear) _arguments -A "-*" \ '-F[Discard transactions to allow pool opening]' \ + '-f[Ignore fmadm acquit and fmadm repair failures]' \ '-n[With -F, check if discarding transactions would work]' \ ':pool name:_zfs_pool' \ '*:virtual device:_files' @@ -216,10 +228,13 @@ _zpool() { _arguments -A "-*" \ '-D[Destroyed pools]' \ '(-d)*-c[Use cache file]:cache file:_files' \ - '(-c)*-d[Search for devices or files in directory]:directory:_files -/' \ + '(-c,-D)*-d[Search for devices or files in directory]:directory:_files -/' \ + '-F[Recovery mode: discard transactions if required]' \ '-f[Force import]' \ '-l[Display configuration in /dev/chassis location form]' \ '-m[Ignore missing log devices]' \ + '-N[Import pool without mounting any filesystems]' \ + '-n[With -F; do not perform input]' \ '-R[Alternate root]:alternate root:_files -/' \ '-o[Set pool or dataset property]:property:_values -s , "property" $create_properties_dataset $rw_props' \ - set1 \ diff --git a/Completion/Unix/Type/_zfs_dataset b/Completion/Unix/Type/_zfs_dataset index d862011ac..64e343f3a 100644 --- a/Completion/Unix/Type/_zfs_dataset +++ b/Completion/Unix/Type/_zfs_dataset @@ -14,6 +14,7 @@ zparseopts -D -E e:=expl_type_arr p=paths_allowed r1=rsrc r2=rdst t+:=type [[ -n $type[(r)fs] ]] && typearg=( filesystem ) [[ -n $type[(r)vol] ]] && typearg=( $typearg volume ) [[ -n $type[(r)snap] ]] && typearg=( $typearg snapshot ) +[[ -n $type[(r)share] ]] && typearg=( $typearg share ) if [[ -n $typearg ]]; then typearg=( -t ${(j:,:)typearg} ) # We know we're in zfs list if paths_allowed is non-empty. @@ -34,7 +35,7 @@ if [[ ${#rsrc} -gt 0 ]]; then elif [[ -n $words[(r)-p] ]]; then typearg=( -t filesystem,volume ) else - typearg=( -t filesystem,snapshot,volume ) + typearg=( -t filesystem,share,snapshot,volume ) fi fi diff --git a/Completion/Zsh/Command/_cd b/Completion/Zsh/Command/_cd index a5d328fc5..6b8d7ebeb 100644 --- a/Completion/Zsh/Command/_cd +++ b/Completion/Zsh/Command/_cd @@ -63,7 +63,7 @@ else fi fi - if [[ $PREFIX != (\~|/|./|../)* ]]; then + if [[ $PREFIX != (\~|/|./|../)* && $IPREFIX != ../* ]]; then local tmpcdpath alt alt=() @@ -100,7 +100,7 @@ else # already handled by _command_names (see _autocd) [[ CURRENT -ne 1 || ( -z "$path[(r).]" && $PREFIX != */* ) ]] && - alt=( "${cdpath+local-}directories:${cdpath+local }directory:_path_files $tmpWpath -/" "$alt[@]" ) + alt=( "${cdpath+local-}directories:${cdpath+local }directory:_path_files ${(j: :)${(@q)tmpWpath}} -/" "$alt[@]" ) if [[ CURRENT -eq argstart && noopts -eq 0 && $PREFIX = -* ]] && zstyle -t ":completion:${curcontext}:options" complete-options; then diff --git a/Config/version.mk b/Config/version.mk index b554719e9..7d49df4f6 100644 --- a/Config/version.mk +++ b/Config/version.mk @@ -27,5 +27,5 @@ # This must also serve as a shell script, so do not add spaces around the # `=' signs. -VERSION=5.0.4 -VERSION_DATE='December 20, 2013' +VERSION=5.0.5 +VERSION_DATE='January 5, 2014' diff --git a/Doc/Zsh/compsys.yo b/Doc/Zsh/compsys.yo index d42ad9779..b9038cfa5 100644 --- a/Doc/Zsh/compsys.yo +++ b/Doc/Zsh/compsys.yo @@ -3824,10 +3824,10 @@ elements of the array. ) enditem() -During the performance of the action the array `tt(line)' -will be set to the command name and normal arguments from the command -line, i.e. the words from the command line excluding all options -and their arguments. Options are stored in the associative array +During the performance of the action the array `tt(line)' will be set to +the normal arguments from the command line, i.e. the words from the +command line after the command name excluding all options and their +arguments. Options are stored in the associative array `tt(opt_args)' with option names as keys and their arguments as the values. For options that have more than one argument these are given as one string, separated by colons. All colons in the original diff --git a/Etc/FAQ.yo b/Etc/FAQ.yo index ce24c7cd8..82053d003 100644 --- a/Etc/FAQ.yo +++ b/Etc/FAQ.yo @@ -122,6 +122,7 @@ Chapter 3: How to get various things to work 3.24. What's wrong with cut and paste on my xterm? 3.25. How do I get coloured prompts on my colour xterm? 3.26. Why is my output duplicated with `tt(foo 2>&1 >foo.out | bar)'? +3.27. What are these `^' and `~' pattern characters, anyway? Chapter 4: The mysteries of completion 4.1. What is completion? @@ -301,7 +302,7 @@ sect(On what machines will it run?) sect(What's the latest version?) - Zsh 5.0.4 is the latest production version. For details of all the + Zsh 5.0.5 is the latest production version. For details of all the changes, see the NEWS file in the source distribution. A beta of the next version is sometimes available. Development of zsh is @@ -545,14 +546,8 @@ tt(EXTENDED_GLOB). option tt(KSH_GLOB) is in effect; for previous versions you must use the table above. - [1] Note that mytt(~) is the only globbing operator to have a lower - precedence than mytt(/). For example, mytt(**/foo~*bar*) matches any - file in a subdirectory called mytt(foo), except where mytt(bar) - occurred somewhere in the path (e.g. mytt(users/barstaff/foo) will - be excluded by the mytt(~) operator). As the mytt(**) operator cannot - be grouped (inside parentheses it is treated as mytt(*)), this is - one way to exclude some subdirectories from matching a mytt(**). - The form (^foo/)# also works. + [1] See question link(3.27)(327) for more on the mysteries of + mytt(~) and mytt(^). it() Unquoted assignments do file expansion after mytt(:)s (intended for PATHs). it()* mytt(typeset) and mytt(integer) have special behaviour for @@ -1452,6 +1447,8 @@ sect(Why does mytt(bindkey ^a command-name) or mytt(stty intr ^-) do something f are metacharacters. tt(^a) matches any file except one called tt(a), so the line is interpreted as bindkey followed by a list of files. Quote the tt(^) with a backslash or put quotation marks around tt(^a). + See link(3.27)(327) if you want to know more about the pattern + character mytt(^). sect(Why can't I bind tt(\C-s) and tt(\C-q) any more?) @@ -1668,6 +1665,7 @@ sect(How do I prevent the prompt overwriting output when there is no newline?) One final alternative is to put a newline in your prompt -- see question link(3.13)(313) for that. + sect(What's wrong with cut and paste on my xterm?) On the majority of modern UNIX systems, cutting text from one window and @@ -1700,6 +1698,7 @@ sect(What's wrong with cut and paste on my xterm?) fixes referred to above in order to be reliable). ) + sect(How do I get coloured prompts on my colour xterm?) (Or `color xterm', if you're reading this in black and white.) @@ -1743,6 +1742,7 @@ sect(How do I get coloured prompts on my colour xterm?) `mytt(<ESC>[0m)' puts printing back to normal so that the rest of the line is unchanged. + sect(Why is my output duplicated with `tt(foo 2>&1 >foo.out | bar)'?) This is a slightly unexpected effect of the option tt(MULTIOS), which is @@ -1780,6 +1780,133 @@ sect(Why is my output duplicated with `tt(foo 2>&1 >foo.out | bar)'?) to unset the option mytt(MULTIOS). +sect(What are these `^' and `~' pattern characters, anyway?) +label(327) + + The characters mytt(^) and mytt(~) are active when the option + tt(EXTENDED_GLOB) is set. Both are used to exclude patterns, i.e. to + say `match something other than ...'. There are some confusing + differences, however. Here are the descriptions for mytt(^) and mytt(~). + + mytt(^) means `anything except the pattern that follows'. You can + think of the combination tt(^)em(pat) as being like a tt(*) except + that it doesn't match em(pat). So, for example, mytt(myfile^.txt) + matches anything that begins with tt(myfile) except tt(myfile.txt). + Because it works with patterns, not just strings, mytt(myfile^*.c) + matches anything that begins with tt(myfile) unless it ends with + tt(.c), whatever comes in the middle --- so it matches tt(myfile1.h) + but not tt(myfile1.c). + + Also like mytt(*), mytt(^) doesn't match across directories if you're + matching files when `globbing', i.e. when you use an unquoted pattern + in an ordinary command line to generate file names. So + mytt(^dir1/^file1) matches any subdirectory of the current directory + except one called tt(dir1), and within any directory it matches it + picks any file except one called tt(file1). So the overall pattern + matches tt(dir2/file2) but not tt(dir1/file1) nor tt(dir1/file2) nor + tt(dir2/file1). (The rule that all the different bits of the pattern + must match is exactly the same as for any other pattern character, + it's just a little confusing that what em(does) match in each bit is + found by telling the shell em(not) to match something or other.) + + As with any other pattern, a mytt(^) expression doesn't treat the + character `tt(/)' specially if it's not matching files, for example + when pattern matching in a command like mytt([[ $string = ^pat1/pat2 ]]). + Here the whole string tt(pat1/pat2) is treated as the argument that + follows the mytt(^). So anything matches but that one string + tt(pat1/pat1). + + It's not obvious what something like mytt([[ $string = ^pat1^pat2 ]]) + means. You won't often have cause to use it, but the rule is that + each mytt(^) takes em(everything) that follows as an argument (unless + it's already inside parentheses --- I'll explain this below). To see + this more clearly, put those arguments in parentheses: the pattern is + equivalent to mytt(^(pat1^(pat2))). where now you can see exactly what + each mytt(^) takes as its argument. I'll leave it as an exercise for + you to work out what this does and doesn't match. + + mytt(~) is always used between two patterns --- never right at the + beginning or right at the end. Note that the other special meaning of + mytt(~), at the start of a filename to refer to your home directory or + to another named directory, doesn't require the option + tt(EXTENDED_GLOB) to be set. (At the end of an argument mytt(~) is + never special at all. This is useful if you have Emacs backup files.) + It means `match what's in front of the tilde, but only if it doesn't + match what's after the tilde'. So mytt(*.c~f*) matches any file + ending in tt(.c) except one that begins with tt(f). You'll see that, + unlike mytt(^), the parts before and after the mytt(~) both refer + separately to the entire test string. + + For matching files by globbing, mytt(~) is the only globbing operator + to have a lower precedence than mytt(/). In other words, when you + have mytt(/a/path/to/match~/a/path/not/to/match) the mytt(~) considers + what's before as a complete path to a file name, and what's after as a + pattern to match against that file. You can put any other pattern + characters in the expressions before and after the mytt(~), but as I + said the pattern after the tt(~) is really just a single pattern to + match against the name of every file found rather than a pattern to + generate a file. That means, for example, that a tt(*) after the + tt(~) em(will) match a tt(/). If that's confusing, you can think of + how mytt(~) works like this: take the pattern on the left, use it as + normal to make a list of files, then for each file found see if it + matches the pattern on the right and if it does take that file out of + the list. Note, however, that this removal of files happens + immediately, before anything else happens to the file list --- before + any glob qualifiers are applied, for example. + + One rule that is common to both mytt(^) and mytt(~) is that they can + be put inside parentheses and the arguments to them don't extend past + the parentheses. So mytt((^README).txt) matches any file ending in + tt(.txt) unless the string before that was tt(README), the same as + mytt(*.txt~README.txt) or mytt((*~README).txt). In fact, you can + always turn mytt(^something) into mytt((*~something)), where + mytt(something) mustn't contain tt(/) if the pattern is being used for + globbing. + + Likewise, mytt(abc(<->~<10-100>).txt) matches a file consisting of + tt(abc), then some digits, then tt(.txt), unless the digits happen to + match a number from 10 to 100 inclusive (remember the handy mytt(<->) + pattern for matching integers with optional limits to the range). So + this pattern matches tt(abc1.txt) or tt(abc200.txt) but not + tt(abc20.txt) nor tt(abc100.txt) nor even tt(abc0030.txt). However, + if you're matching files by globbing note you can't put mytt(/)s + inside the parentheses since the groups can't stretch across multiple + directories. (You can do that, of course, whenever the character + mytt(/) isn't special.) This means that you need to take care when + using exclusions across multiple directories; see some examples below. + + You may like to know that from zsh 5.0.3 you can disable any pattern + character separately. So if you find mytt(^) gets in your way and + you're happy using mytt(~), put mytt(disable -p "^") in tt(~/.zshrc). + You still need to turn on tt(EXTENDED_GLOB); the tt(disable) command + only deactivates things that would otherwise be active, you can't + specially enable something not allowed by the syntax options in effect. + + Here are some examples with files to illustrate the points. We'll + assume the option tt(EXTENDED_GLOB) is set and none of the pattern + characters is disabled. + + enumerate( + myeit() mytt(**/foo~*bar*) matches any file called mytt(foo) in any + subdirectory, except where mytt(bar) occurred somewhere in the path. + For example, mytt(users/barstaff/foo) will be excluded by the mytt(~) + operator. As the mytt(**) operator cannot be grouped (inside + parentheses it is treated as mytt(*)), this is one way to exclude some + subdirectories from matching a mytt(**). Note that this can be quite + inefficent because the shell performs a complete search for + mytt(**/foo) before it uses the pattern after the mytt(~) to exclude + files from the match. The file is excluded if mytt(bar) occurs + em(anywhere), in any directory segment or the final file name. + myeit() The form mytt((^foo/)#) can be used to match any hierarchy of + directories where none of the path components is tt(foo). For + example, mytt((^CVS/)#) selects all subdirectories to any depth + except where one component is named mytt(CVS). (The form + mytt((pat/)#) is very useful in other cases; for example, + mytt((../)#.cvsignore) finds the file tt(.cvsignore) if it exists + in the current directory or any parent.) + ) + + chapter(The mysteries of completion) @@ -2,11 +2,11 @@ Unless otherwise noted in the header of specific files, files in this distribution have the licence shown below. However, note that certain shell functions are licensed under versions -of the GNU Public Licence. Anyone distributing the shell as a binary -including those files needs to take account of this. Search shell -functions for "Copyright" for specific copyright information. -None of the core functions are affected by this, so those files -may simply be omitted. +of the GNU General Public Licence. Anyone distributing the shell as a +binary including those files needs to take account of this. Search +shell functions for "Copyright" for specific copyright information. +None of the core functions are affected by this, so those files may +simply be omitted. -- @@ -35,6 +35,9 @@ Apple: MacOS X/Darwin 10.x Reported to compile with no problems on 10.4. + Compiling with GCC on 10.9.1 (Mavericks) reportedly causes a crash + due to a libiconv problem. Compile with clang instead. + Multibyte support works; you probably wish to set the option COMBINING_CHARS, which is not enabled by default. Problems have been noted when outputting multibyte characters @@ -5,9 +5,10 @@ THE Z SHELL (ZSH) Version ------- -This is version 5.0.4 of the shell. This is a stable release. +This is version 5.0.5 of the shell. This is a stable release. There are minor new features as well as bug fixes since 5.0.2. -5.0.3 was a short-lived release with most of the features of 5.0.4. +5.0.3 and 5.0.4 were short-lived releases with most of the features of +5.0.5 that were replaced owing to significant bugs. Installing Zsh -------------- @@ -28,7 +29,7 @@ Zsh is a shell with lots of features. For a list of some of these, see the file FEATURES, and for the latest changes see NEWS. For more details, see the documentation. -Incompatibilities between 5.0.2 and 5.0.4 +Incompatibilities between 5.0.2 and 5.0.5 ----------------------------------------- The "zshaddhistory" hook mechanism documented in the zshmisc manual page diff --git a/Src/Zle/zle_misc.c b/Src/Zle/zle_misc.c index 25404c1bd..7be0ebbd1 100644 --- a/Src/Zle/zle_misc.c +++ b/Src/Zle/zle_misc.c @@ -843,7 +843,7 @@ copyprevshellword(UNUSED(char **args)) if (zmult <= 0) return 1; - if ((l = bufferwords(NULL, NULL, &i, 0))) { + if ((l = bufferwords(NULL, NULL, &i, LEXFLAGS_ZLE))) { i -= (zmult-1); if (i < 0) return 1; diff --git a/Src/Zle/zle_tricky.c b/Src/Zle/zle_tricky.c index 25f09c459..9d163ad9e 100644 --- a/Src/Zle/zle_tricky.c +++ b/Src/Zle/zle_tricky.c @@ -1071,7 +1071,7 @@ has_real_token(const char *s) static char * get_comp_string(void) { - enum lextok t0, tt0; + enum lextok t0, tt0, cmdtok; int i, j, k, cp, rd, sl, ocs, ins, oins, ia, parct, varq = 0; int ona = noaliases; /* @@ -1146,6 +1146,7 @@ get_comp_string(void) linredir = inredir; zsfree(cmdstr); cmdstr = NULL; + cmdtok = NULLTOK; zsfree(varname); varname = NULL; insubscr = 0; @@ -1264,6 +1265,7 @@ get_comp_string(void) ins = (tok == REPEAT ? 2 : (tok != STRING)); zsfree(cmdstr); cmdstr = ztrdup(tokstr); + cmdtok = tok; /* If everything before is a redirection, don't reset the index */ if (wordpos != redirpos) wordpos = redirpos = 0; @@ -1271,10 +1273,11 @@ get_comp_string(void) /* * A following DOLOOP should cause us to reset to the start * of the command line. For some reason we only recognise - * DOLOOP for this purpose (above) if ins is set. Why? - * Don't ask pointless questions. + * DOLOOP for this purpose (above) if ins is set. Why? To + * handle completing multiple SEPER-ated command positions on + * the same command line, e.g., pipelines. */ - ins = 1; + ins = (cmdtok != STRING); } if (!lexflags && tt0 == NULLTOK) { /* This is done when the lexer reached the word the cursor is on. */ diff --git a/Src/exec.c b/Src/exec.c index dccdc2b0d..f16cfd391 100644 --- a/Src/exec.c +++ b/Src/exec.c @@ -1691,6 +1691,7 @@ execpline2(Estate state, wordcode pcode, execcmd(state, input, output, how, last1 ? 1 : 2); else { int old_list_pipe = list_pipe; + int subsh_close = -1; Wordcode next = state->pc + (*state->pc), pc; wordcode code; @@ -1738,6 +1739,7 @@ execpline2(Estate state, wordcode pcode, } else { /* otherwise just do the pipeline normally. */ addfilelist(NULL, pipes[0]); + subsh_close = pipes[0]; execcmd(state, input, pipes[1], how, 0); } zclose(pipes[1]); @@ -1750,6 +1752,8 @@ execpline2(Estate state, wordcode pcode, execpline2(state, *state->pc++, how, pipes[0], output, last1); list_pipe = old_list_pipe; cmdpop(); + if (subsh_close != pipes[0]) + zclose(pipes[0]); } } @@ -2385,7 +2389,7 @@ static void execcmd(Estate state, int input, int output, int how, int last1) { HashNode hn = NULL; - LinkList args; + LinkList args, filelist = NULL; LinkNode node; Redir fn; struct multio *mfds[10]; @@ -2907,6 +2911,7 @@ execcmd(Estate state, int input, int output, int how, int last1) flags |= ESUB_KEEPTRAP; if (type == WC_SUBSH && !(how & Z_ASYNC)) flags |= ESUB_JOB_CONTROL; + filelist = jobtab[thisjob].filelist; entersubsh(flags); close(synch[1]); forked = 1; @@ -3260,6 +3265,7 @@ execcmd(Estate state, int input, int output, int how, int last1) if (is_shfunc) { /* It's a shell function */ + pipecleanfilelist(filelist); execshfunc((Shfunc) hn, args); } else { /* It's a builtin */ @@ -3338,6 +3344,7 @@ execcmd(Estate state, int input, int output, int how, int last1) DPUTS(varspc, "BUG: assignment before complex command"); list_pipe = 0; + pipecleanfilelist(filelist); /* If we're forked (and we should be), no need to return */ DPUTS(last1 != 1 && !forked, "BUG: not exiting?"); DPUTS(type != WC_SUBSH, "Not sure what we're doing."); diff --git a/Src/jobs.c b/Src/jobs.c index 371b8eb32..871946598 100644 --- a/Src/jobs.c +++ b/Src/jobs.c @@ -1173,6 +1173,30 @@ addfilelist(const char *name, int fd) zaddlinknode(ll, jf); } +/* Clean up pipes no longer needed associated with a job */ + +/**/ +void +pipecleanfilelist(LinkList filelist) +{ + LinkNode node; + + if (!filelist) + return; + node = firstnode(filelist); + while (node) { + Jobfile jf = (Jobfile)getdata(node); + if (jf->is_fd) { + LinkNode next = nextnode(node); + zclose(jf->u.fd); + (void)remnode(filelist, node); + zfree(jf, sizeof(*jf)); + node = next; + } else + incnode(node); + } +} + /* Finished with list of files for a job */ /**/ @@ -1415,19 +1439,7 @@ zwaitjob(int job, int wait_cmd) * we can't deadlock on the fact that those still exist, so * that's not a problem. */ - LinkNode node = firstnode(jn->filelist); - while (node) { - Jobfile jf = (Jobfile)getdata(node); - if (jf->is_fd) { - LinkNode next = nextnode(node); - (void)remnode(jn->filelist, node); - zclose(jf->u.fd); - zfree(jf, sizeof(*jf)); - node = next; - } else { - incnode(node); - } - } + pipecleanfilelist(jn->filelist); } while (!errflag && jn->stat && !(jn->stat & STAT_DONE) && @@ -2607,6 +2619,7 @@ acquire_pgrp(void) sigset_t blockset, oldset; if ((mypgrp = GETPGRP()) > 0) { + long lastpgrp = mypgrp; sigemptyset(&blockset); sigaddset(&blockset, SIGTTIN); sigaddset(&blockset, SIGTTOU); @@ -2627,6 +2640,9 @@ acquire_pgrp(void) if (read(0, NULL, 0) != 0) {} /* Might generate SIGT* */ signal_block(blockset); mypgrp = GETPGRP(); + if (mypgrp == lastpgrp && !interact) + break; /* Unlikely that pgrp will ever change */ + lastpgrp = mypgrp; } if (mypgrp != mypid) { if (setpgrp(0, 0) == 0) { diff --git a/Src/params.c b/Src/params.c index 26ad6b221..ad9e3470b 100644 --- a/Src/params.c +++ b/Src/params.c @@ -3380,8 +3380,12 @@ arrvarsetfn(Param pm, char **x) *dptr = mkarray(NULL); else *dptr = x; - if (pm->ename && x) - arrfixenv(pm->ename, x); + if (pm->ename) { + if (x) + arrfixenv(pm->ename, x); + else if (*dptr == path) + pathchecked = path; + } } /**/ diff --git a/Test/A05execution.ztst b/Test/A05execution.ztst index c8320a14d..6abfd8b1f 100644 --- a/Test/A05execution.ztst +++ b/Test/A05execution.ztst @@ -202,3 +202,17 @@ F:the bug is still there or it reappeared. See workers-29973 for details. 0:Check $pipestatus with a known difficult case >1 0 1 0 0 F:This similar test was triggering a reproducible failure with pipestatus. + + { unsetopt MONITOR } 2>/dev/null + coproc { read -Et 5 || kill -INT $$ } + print -u $ZTST_fd 'This test takes 5 seconds to fail...' + { printf "%d\n" {1..20000} } | ( read -E ) + hang(){ printf "%d\n" {2..20000} | cat }; hang | ( read -E ) + print -p done + read -Ep +0:Bug regression: piping a shell construct to an external process may hang +>1 +>2 +>done +F:This test checks for a file descriptor leak that could cause the left +F:side of a pipe to block on write after the right side has exited diff --git a/Test/Y01completion.ztst b/Test/Y01completion.ztst index 1d21c2a33..a2aa00717 100644 --- a/Test/Y01completion.ztst +++ b/Test/Y01completion.ztst @@ -45,7 +45,7 @@ >line: {: ~user1}{} comptest $'echo ;:\C-b\C-b\t' -0:tilde +0:directories and files before separator >line: {echo }{;:} >DESCRIPTION:{file} >DI:{dir1} @@ -53,6 +53,28 @@ >FI:{file1} >FI:{file2} +# Depends on path assignment in comptestinit + comptesteval "path=( $ZTST_srcdir:A )" + comptest $'zt\t' +0:command +>line: {ztst.zsh }{} + + comptesteval "path=( $ZTST_srcdir:A )" + comptest $':;zt\t' +0:command after separator +>line: {:;ztst.zsh }{} +F:regression test workers/32182 + + comptest $'for f in 1; do < x\C-b\C-b\t' +0:redirection after "for ...; do" +>line: {for f in 1; do <}{ x} +>DESCRIPTION:{file} +>DI:{dir1} +>DI:{dir2} +>FI:{file1} +>FI:{file2} +F:regression test workers/31611 + %clean zmodload -ui zsh/zpty |