Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixes for zsh/zpty fd message exchange #45

Open
wants to merge 10 commits into
base: main
Choose a base branch
from
Open

Fixes for zsh/zpty fd message exchange #45

wants to merge 10 commits into from

Conversation

mafredri
Copy link
Owner

@mafredri mafredri commented Oct 22, 2020

  • Chunk worker output to 1024 characters
  • Force zpty fd to behave by wrapping message in newlines
  • Allow debugging the async worker
  • Fix tests

Fixes #44.
Maybe fixes #40.
Maybe fixes #18.

@mafredri mafredri changed the title zpty fixes Zpty fixes Oct 22, 2020
@mafredri mafredri changed the title Zpty fixes Fixes for zsh/zpty fd message exchange Oct 22, 2020
mafredri added a commit that referenced this pull request Oct 23, 2020
This change borrows the idea from #45 to introduce newlines to `zpty -w`
as well.

Consequently, when we want to properly escape _all_ inputs to
`async_job`, we can no longer accept scripts as the first argument,
as-is. Furthermore, it was discovered that the current implementation
is flawed in the sense that it's impossible to execute a single command
where the name or path has spaces in it (how did we not notice this
before?).

For this reason, `async_job` received the `-s` argument which allows
running scripts, for example:

	async_job myworker -s 'print hello; print world'

Whereas a command with spaces can now work without changes:

	async_job myworker /path/to/my\ executable
mafredri added a commit that referenced this pull request Oct 24, 2020
This change borrows the idea from #45 to introduce newlines to `zpty -w`
as well.

Consequently, when we want to properly escape _all_ inputs to
`async_job`, we can no longer accept scripts as the first argument,
as-is. Furthermore, it was discovered that the current implementation
is flawed in the sense that it's impossible to execute a single command
where the name or path has spaces in it (how did we not notice this
before?).

For this reason, `async_job` received the `-s` argument which allows
running scripts, for example:

	async_job myworker -s 'print hello; print world'

Whereas a command with spaces can now work without changes:

	async_job myworker /path/to/my\ executable
When we output too much data on the zpty fd it can become corrupt in
some cases, this commit protects against this by only printing 1024
bytes at a time.

Further, when notifying via kill signas, we notify the parent process
after every chunk so that the fd can be emptied.

In my testing, 1024 bytes seems to be the maximum safe limit that can be
used. Perhaps evidence to support this conclusion could be found in the
zsh code base.
There seems to be a chance that, when the zpty simultaneously outputs
and receives data, the output data is lost.

Introducing newlines seems to fix the issue. Simply introducing trailing
newlines did not. Reason is not entirely clear, perhaps there is
something special about the zpty fd or perhaps this is a property of
`zpty -r` / `read`.
@mafredri mafredri force-pushed the zpty-fixes branch 3 times, most recently from a2cc80e to 4850f57 Compare January 5, 2023 23:46
intelfx pushed a commit to intelfx/zsh-async that referenced this pull request May 4, 2024
This change borrows the idea from mafredri#45 to introduce newlines to `zpty -w`
as well.

Consequently, when we want to properly escape _all_ inputs to
`async_job`, we can no longer accept scripts as the first argument,
as-is. Furthermore, it was discovered that the current implementation
is flawed in the sense that it's impossible to execute a single command
where the name or path has spaces in it (how did we not notice this
before?).

For this reason, `async_job` received the `-s` argument which allows
running scripts, for example:

	async_job myworker -s 'print hello; print world'

Whereas a command with spaces can now work without changes:

	async_job myworker /path/to/my\ executable
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
1 participant