8000 [Console] reopen inputStream after a ctrl+D/ctrl+Z by epitre · Pull Request #38345 · symfony/symfony · GitHub
[go: up one dir, main page]

Skip to content

[Console] reopen inputStream after a ctrl+D/ctrl+Z #38345

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

Closed
wants to merge 1 commit into from

Conversation

epitre
Copy link
Contributor
@epitre epitre commented Sep 29, 2020
Q A
Branch? master
Bug fix? yes
New feature? no
Deprecations? no
Tickets I did not open a ticket
License MIT
Doc PR N/A

I encountered a problem with the new multiline question.

it appears when you ask a question AFTER a multiline question

It seems STDIN needs to be reopen (<- does it make sense ?).

I have no idea if this is the best way to fix it, but it does fix it ^^

@epitre epitre force-pushed the fix-bug-console-multiline branch from 06d6ace to 1165217 Compare September 29, 2020 13:01
@epitre epitre changed the title reopen inputStream after a ctrl+D/ctrl+Z [Console] reopen inputStream after a ctrl+D/ctrl+Z Sep 29, 2020
@@ -521,6 +521,7 @@ private function readInput($inputStream, Question $question)
while (false !== ($char = fgetc($inputStream))) {
$ret .= $char;
}
$this->inputStream = fopen('php://stdin', 'r');
Copy link
Member

Choose a reason for hiding this comment

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

what if the input stream being used is not php://stdin ? That's a supported use case (see isInteractiveInput supporting that case explicitly for instance).

Also, this method looks like the wrong place to me, as it is not designed to use $this->inputStream directly.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

That's a very valid point.
I have no idea how to deal with it ^^

Copy link
Contributor

Choose a reason for hiding this comment

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

I think I have a solution. I'm testing it on Windows to make sure it works there, as well.

@ramsey
Copy link
Contributor
ramsey commented Sep 29, 2020

@epitre Thanks for looking into this. I'm going to do some testing myself, since I think there's a more appropriate way to "reset" the input stream, since as @stof points out, the input stream being used might not be stdin.

@ramsey
Copy link
Contributor
ramsey commented Sep 29, 2020

It took a while since what I originally had worked on *nix but not on Windows, but I have a solution over here: #38351

@fabpot
Copy link
Member
fabpot commented Sep 30, 2020

Closing in favor of #38351

@fabpot fabpot closed this Sep 30, 2020
@xabbuh xabbuh added the Console label Sep 30, 2020
chalasr added a commit that referenced this pull request Sep 30, 2020
…'t close input (ramsey)

This PR was squashed before being merged into the 5.2-dev branch (closes #38351).

Discussion
----------

[Console] clone stream on multiline questions so EOT doesn't close input

| Q             | A
| ------------- | ---
| Branch?       | master
| Bug fix?      | yes
| New feature?  | no
| Deprecations? | no
| Tickets       | N/A
| License       | MIT
| Doc PR        | N/A

This fixes a bug in the multiline question feature that was introduced in #37683.

Today, @epitre commented on #37683 (comment):

> If I ask a question AFTER using the multiline option in a previous question, then it seems that the ctrl+d is kind of saved, and the command gets aborted.

I'm honestly not sure how I missed this while working on #37683, since I was testing it with multiple questions, but I think it might have resulted from some of the back-and-forth and the lack of ability to effectively test the EOT character from a unit test.

The solution was to _clone_ the input stream resource and use the clone to read the multiline input and capture the EOT byte. In this way, the primary input stream is not closed by the EOT.

This is similar to @epitre's solution in #38345, but I'm using the `uri` and `mode` from `stream_get_meta_data()` to create the new stream, and if the existing stream has any data and is seekable and writable (like the streams used in the tests), I add the data to the clone and seek to the same offset.

I've ensured that this solution works on a question that is in the middle of a series of other questions, and I've tested in on *nix and Windows. I've also improved the tests for multiline questions. While I'm unable to test (with a unit test) that an EOT character effectively stops reading from STDIN while continuing to the next question and prompt, I feel confident that the tests here provide sufficient coverage.

Commits
-------

ec688a3 [Console] clone stream on multiline questions so EOT doesn't close input
symfony-splitter pushed a commit to symfony/console that referenced this pull request Sep 30, 2020
…'t close input (ramsey)

This PR was squashed before being merged into the 5.2-dev branch (closes #38351).

Discussion
----------

[Console] clone stream on multiline questions so EOT doesn't close input

| Q             | A
| ------------- | ---
| Branch?       | master
| Bug fix?      | yes
| New feature?  | no
| Deprecations? | no
| Tickets       | N/A
| License       | MIT
| Doc PR        | N/A

This fixes a bug in the multiline question feature that was introduced in #37683.

Today, @epitre commented on symfony/symfony#37683 (comment):

> If I ask a question AFTER using the multiline option in a previous question, then it seems that the ctrl+d is kind of saved, and the command gets aborted.

I'm honestly not sure how I missed this while working on #37683, since I was testing it with multiple questions, but I think it might have resulted from some of the back-and-forth and the lack of ability to effectively test the EOT character from a unit test.

The solution was to _clone_ the input stream resource and use the clone to read the multiline input and capture the EOT byte. In this way, the primary input stream is not closed by the EOT.

This is similar to @epitre's solution in symfony/symfony#38345, but I'm using the `uri` and `mode` from `stream_get_meta_data()` to create the new stream, and if the existing stream has any data and is seekable and writable (like the streams used in the tests), I add the data to the clone and seek to the same offset.

I've ensured that this solution works on a question that is in the middle of a series of other questions, and I've tested in on *nix and Windows. I've also improved the tests for multiline questions. While I'm unable to test (with a unit test) that an EOT character effectively stops reading from STDIN while continuing to the next question and prompt, I feel confident that the tests here provide sufficient coverage.

Commits
-------

ec688a361e [Console] clone stream on multiline questions so EOT doesn't close input
@ramsey
Copy link
Contributor
ramsey commented Sep 30, 2020

@epitre, this fix for this was merged into master just now (see #38351). Can you pull that down and test to make sure this resolves the issue? Thanks!

@epitre
Copy link
Contributor Author
epitre commented Oct 1, 2020

@ramsey It works perfectly !
Thank you very much :)

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

Successfully merging this pull request may close these issues.

6 participants
0