Skip to content

proc_open refactoring (1) #5507

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 28 commits into from

Conversation

alexdowad
Copy link
Contributor

Code cleanup and reorganization in proc_open.c, in readiness to implement PTY support.

Code review will be easier if you look through commit by commit. However, if you want them squashed together before actually merging, that is fine.

@alexdowad alexdowad force-pushed the proc-open-refactoring-1 branch 4 times, most recently from 6c91aec to b0f9b8f Compare May 1, 2020 20:15
@alexdowad
Copy link
Contributor Author

Still fixing this up, sorry...

@alexdowad alexdowad force-pushed the proc-open-refactoring-1 branch from b0f9b8f to 905e4a9 Compare May 1, 2020 21:26
@nikic
Copy link
Member

nikic commented May 2, 2020

AppVeyor failure may be legit, seems like it's hanging?

@cmb69
Copy link
Member

cmb69 commented May 2, 2020

It seems to me that the refactoring doesn't take into account that php_file_descriptor_t is a file descriptor (int) on POSIX systems, but may be an actual HANDLE on Windows; there are some conversions to a file descriptor, but the old code used CloseHandle() two times, while the refactored code no longer does.

Copy link
Member

@nikic nikic left a comment

Choose a reason for hiding this comment

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

Some quick notes, I'll have to check this more carefully.

add_assoc_long(return_value, "termsig", termsig);
add_assoc_long(return_value, "stopsig", stopsig);
add_assoc_long(return_value, "termsig", termsig);
add_assoc_long(return_value, "stopsig", stopsig);
Copy link
Member

Choose a reason for hiding this comment

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

This alignment is not necessary.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Do you mean you don't want things to be aligned (if it means adding whitespace)? Of course it's not necessary; I just did it because personally I find it easier to work on code that way.

If you don't like it, please just mention.

Copy link
Member

Choose a reason for hiding this comment

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

For this project, unless there is a strong reason to do it, I'd avoid alignment. (This is a complication of tab indentation, which means that half the people end up trying to tab-align as well, and we get a mess in the end. Every time I edit aligned code, I have to check a few lines to figure out whether it is predominantly tab-aligned or space-aligned.)

@cmb69 cmb69 added the Feature label May 2, 2020
@alexdowad
Copy link
Contributor Author

@nikic @cmb69 I am very impressed at the thoroughness of your review. This PR is still a WIP, but I will go through right now and respond to each of your comments.

@alexdowad
Copy link
Contributor Author

It seems to me that the refactoring doesn't take into account that php_file_descriptor_t is a file descriptor (int) on POSIX systems, but may be an actual HANDLE on Windows; there are some conversions to a file descriptor, but the old code used CloseHandle() two times, while the refactored code no longer does.

You mean the bit where all open file handles are closed if spawning a process fails on Windows? The refactored code uses a macro which expands to CloseHandle on Windows. That macro was already there before, but wasn't fully used to reduce code duplication.

But if there is any other place which I missed, I would appreciate being reminded.

alexdowad added 3 commits May 2, 2020 21:01
proc_open() is a huge function. Pulling out various pieces into helper functions will make
it much easier to read and follow.
@alexdowad
Copy link
Contributor Author

Still fixing things up... will push an update soon.

@alexdowad alexdowad force-pushed the proc-open-refactoring-1 branch 4 times, most recently from ab74c7b to 0c74bd2 Compare May 3, 2020 19:41
@alexdowad
Copy link
Contributor Author

I think we're ready for more code review. Thanks very much for the great suggestions for improvement made thus far.

@alexdowad
Copy link
Contributor Author

CI failure on Azure: In one of the jobs, apt failed to install libxml2 and libxslt, so all the test suite runs failed in that job.

@alexdowad
Copy link
Contributor Author

Another branch is ready which enables PTY support (with a simplified implementation suggested by @nikic). It's based on this one, so maybe I should wait for this one to be reviewed before pushing it...

Copy link
Member

@nikic nikic left a comment

Choose a reason for hiding this comment

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

This looks good, a few notes.

add_assoc_long(return_value, "termsig", termsig);
add_assoc_long(return_value, "stopsig", stopsig);
add_assoc_long(return_value, "termsig", termsig);
add_assoc_long(return_value, "stopsig", stopsig);
Copy link
Member

Choose a reason for hiding this comment

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

For this project, unless there is a strong reason to do it, I'd avoid alignment. (This is a complication of tab indentation, which means that half the people end up trying to tab-align as well, and we get a mess in the end. Every time I edit aligned code, I have to check a few lines to figure out whether it is predominantly tab-aligned or space-aligned.)

/* zend_strings which may be allocated while processing the descriptorspec
* we need to make sure that each one allocated is released once and only once */
zend_string *ztype = NULL, *zmode = NULL, *zfile = NULL;
#define cleanup_zend_string(ptr) do { if (ptr != NULL) { zend_string_release(ptr); ptr = NULL; } } while(0)
Copy link
Member

Choose a reason for hiding this comment

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

This is zend_tmp_string_release().

Copy link
Contributor Author

Choose a reason for hiding this comment

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

OK. Though the macros are still needed.

The point of these macros is that the function is loaded with goto exit_fail;s and it would be cumbersome to ensure that the correct zend_strings are released at each such point. So when releasing them, we set the pointer to NULL so there's no danger of freeing them twice.

Copy link
Member

@nikic nikic May 4, 2020

Choose a reason for hiding this comment

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

I see. I don't really like this, but let's leave it for now.

Copy link
Member

Choose a reason for hiding this comment

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

In the interest of reducing non-local state, I've moved the code that uses these strings into a separate function in 2dc4481.

if (!ztarget) {
zend_value_error("Missing redirection target");
goto exit_fail;
}
if (Z_TYPE_P(ztarget) != IS_LONG) {
zend_value_error("Redirection target must be an integer");
zend_value_error("Redirection target must be an integer; got %s", zend_get_type_by_const(Z_TYPE_P(ztarget)));
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
zend_value_error("Redirection target must be an integer; got %s", zend_get_type_by_const(Z_TYPE_P(ztarget)));
zend_value_error("Redirection target must be of type int, %s given", zend_get_type_by_const(Z_TYPE_P(ztarget)));

is the usual phrasing.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done.

Copy link
Member

Choose a reason for hiding this comment

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

I think this part is not done yet.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I think I was still running make test and hadn't pushed yet when you made this comment.

alexdowad added 6 commits May 4, 2020 13:09
Every time proc_open() is called on Windows, an identical SECURITY_ATTRIBUTES struct
is initialized. It is never modified, just used to tell CreateProcessW() that
subprocesses are allowed to inherit file handles from the parent.

Just allocate one of them statically and be done with it.
@alexdowad
Copy link
Contributor Author

I've noticed there is also a TODO comment left behind:

/* TODO Deprecate in favor of array command? */

Do you think that would be a good idea? (Deprecating the bypass_shell option on Windows in favor of the newer array-as-command style invocation of proc_open.)

@alexdowad alexdowad force-pushed the proc-open-refactoring-1 branch from 5cd6a91 to c1922e8 Compare May 4, 2020 12:24
@php-pulls php-pulls closed this in 51b0494 May 4, 2020
@cmb69
Copy link
Member

cmb69 commented May 4, 2020

Do you think that would be a good idea? (Deprecating the bypass_shell option on Windows in favor of the newer array-as-command style invocation of proc_open.)

May be, but I think that should be discussed on the internals@ mailing list first.

@alexdowad
Copy link
Contributor Author

I must say I love the thorough code reviews on this project.

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

Successfully merging this pull request may close these issues.

3 participants