Skip to content

Conversation

@step-
Copy link

@step- step- commented Dec 26, 2025

Issue

Dispatch within tmux can leave head -1 hanging.

Reproducible test

Linux target.

In tmux start vim and :let b:dispatch=./maker.sh, write maker.sh as follows:

echo "Press Enter to continue or Ctrl+C to abort ..."
read x
echo "Making ..."
echo "DONE"
exit 0

and set maker.sh executable. Then :Dispatch, and switch input focus to the compiler's output tmux pane, which shows "Press Enter to continue or...". Here you can either press Enter to simulate a full make or press Ctrl+C to abort. If you press Ctrl+C and check the process list afterwards, you should notice a head -1 /tmp/xyz.complete process under the vim parent process. head -1 is blocked on a fifo that will never receive input because Ctrl+C killed the process that was supposed to write to the fifo.

Proposed fix

This PR unblocks head -1 through a shell trap handler that writes to the fifo upon receiving the INT signal. If INT is handled, maker.sh exists 129 otherwise the value of $?.

**Issue**

Dispatch within tmux can leave `head -1` hanging.

**Reproducible test**

Linux target.

In tmux start vim and `:let b:dispatch=./maker.sh`, write maker.sh as follows:
```sh
echo "Press Enter to continue or Ctrl+C to abort ..."
read x
echo "Making ..."
echo "DONE"
exit 0
```

and set maker.sh executable. Then `:Dispatch`, and switch input focus to the compiler's output tmux pane, which shows "Press Enter to continue or...". Here you can either press Enter to simulate a full make or press Ctrl+C to abort. If you press Ctrl+C and check the process list afterwards, you should notice a `head -1 /tmp/xyz.complete` process under the vim parent process. `head -1` is blocked on a fifo that will never receive input because Ctrl+C killed the process that was supposed to write to the fifo.

**Proposed fix**

This PR unblocks `head -1` through a shell trap handler that writes to the fifo upon receiving the INT signal. If INT is handled, maker.sh exists 129 otherwise the value of `$?`.
else
let exec .= 'sleep 1; '
endif
let exec .= 'trap "trap \"\" INT; (exit 129); '. dispatch#complete_make(a:request) . '" INT; '
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you explain what's going here? I presume (exit 129), which exits a subshell, is supposed to set the exit status without itself exiting, but when I try a simpler version

sh -c '(exit 129); echo x > /tmp/test'

it exits successfully with a status of 0.

I'm also not clear why 129 was chosen (INT is typically 130), or why we need to trap "" INT if we're exiting anyways.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm also not clear why 129 was chosen (INT is typically 130), or why we need to trap "" INT if we're exiting anyways.

Right, it should be 130. With trap "" INT we ignore another INT -- should there be one -- while we write to the fifo. I'm thinking a user rapidly firing Ctrl+C keypresses on slow writing media, could enter the handler twice. It's standard practice to ignore signals while processing previous signals.

Can you explain what's going here? I presume (exit 129), which exits a subshell, is supposed to set the exit status without itself exiting, but when I try a simpler version

sh -c '(exit 129); echo x > /tmp/test'

it exits successfully with a status of 0.

Line 311 expands to

trap "trap \"\" INT; (exit 129); echo $? > /tmp/xyz.complete" INT;

Ignoring for a moment the fact I had the handler's exterior quotes wrong (should've been singles), (exit 129) is meant to set $? to 129 when it's written to /tmp/xyz.complete.

After fixing 129 and exterior quotes, this is what the last line of an actual .dispatch script looks like:

echo $$ > /tmp/vImJfxz/12.pid; sync; perl -e "select(undef,undef,undef,0.1)" 2>/dev/null; trap 'trap "" INT; (exit 130); echo $? > /tmp/vImJfxz/12.complete' INT; (./maker.sh; echo $? > /tmp/vImJfxz/12.complete) 2>&1| tee /tmp/vImJfxz/12; echo > /tmp/vImJfxz/12.callback

I will add the necessary corrections to this PR.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed in b7e87e0

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you directly echo 130 > instead? (exit 130) won't work with fish shell.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in 1cd9a55.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants