Skip to content

'exit' inside zshz() kills the interactive shell when the datafile is misconfigured #103

Description

@ahjota

Summary

Three exit calls in zsh-z.plugin.zsh execute in the user's current shell instead of just aborting the plugin:

  1. The source-time version check (is-at-least 4.3.11) — kills the shell during startup on old zsh.
  2. In zshz(): a custom datafile set without a directory path (ZSHZ_DATA not containing /).
  3. In zshz(): the datafile being a directory.

Because z is an alias for zshz 2>&1 running in the current shell, cases 2 and 3 terminate the interactive session. With terminals that close when the shell exits (e.g. Ptyxis' default exit-action=close), the tab or window disappears — same failure mode as the well-known gretzky/n.zsh exit 1 chpwd bug.

Reproducer

% mkdir /tmp/zdir
% export ZSHZ_DATA=/tmp/zdir   # or: ~/.z somehow becomes a directory
% z foo
ERROR: Zsh-z's datafile (/tmp/zdir) is a directory.
# shell exits; terminal tab closes

Non-interactive confirmation (zsh 5.9, macOS arm64; plugin @ acd0e19):

% zsh -c 'source zsh-z.plugin.zsh; ZSHZ_DATA=/tmp/zdir; zshz foo; print SURVIVED'
ERROR: Zsh-z's datafile (/tmp/zdir) is a directory.
%                        # <- SURVIVED never prints; the shell is gone (exit status 0)

The no-directory-path case behaves the same: ZSHZ_DATA=z z foo.

Expected behavior

Print the error and return 1, leaving the shell alive. The precmd path is unaffected either way — (zshz --add "$PWD" &) already runs in a subshell — so this only changes the interactive-alias and source-time behavior.

I have a patch ready on a branch in my fork (the three exits become return 1) and can open a PR if you'd like.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions