Message333839
| Author |
vstinner |
| Recipients |
gregory.p.smith, izbyshev, kevans, koobs, nanjekyejoannah, pablogsal, serhiy.storchaka, vstinner |
| Date |
2019年01月17日.10:00:47 |
| SpamBayes Score |
-1.0 |
| Marked as misclassified |
Yes |
| Message-id |
<1547719247.63.0.45116374231.issue35537@roundup.psfhosted.org> |
| In-reply-to |
| Content |
Alexey Izbyshev
> So, if we can't change os.execvp() and/or current subprocess behavior, posix_spawnp seems to be ruled out.
My main motivation for using posix_spawn() is performance. An optimization should not justify to introduce a backward incompatible change. I agree wth posix_spawnp() cannot be used directly in subprocess because of that. But os.posix_spawnp() addition in Python 3.8 remains useful because it allows to use it directly (avoid subprocess).
> A naive emulation of posix_spawnp would be repeatedly calling posix_spawn for each PATH entry, but that's prohibitively expensive.
It should be compared to the current code. Currently, _posixsubprocess uses a loop calling execv(). I don't think that calling posix_spawn() in a loop until one doesn't fail is more inefficient.
The worst case would be when applying process attributes and run file actions would dominate performances... I don't think that such case exists. Syscalls like dup2() and close() should be way faster than the final successful execv() in the overall posix_spawn() call. I'm talking about the case when the program exists.
> Iterate over PATH entries and perform a quick check for common exec errors (ENOENT, ENOTDIR, EACCES) manually (e.g. by stat()).
I dislike this option. There is a high risk of race condition if the program is created, deleted or modified between the check and exec. It can cause subtle bugs, or worse: security vulnerabilities. IMHO the only valid check, to test if a program exists, is to call exec().
Alexey: Do you want to work on a PR to reimplement the "executable_list" and loop used by subprocess with _posixsubproces? You should keep the latest exception to re-raise it if no posix_spawn() successed. Don't forget to clear the exception on success, to not create a reference cycle:
commit acb9fa79fa6453c2bbe3ccfc9cad2837feb90093
Author: Victor Stinner <victor.stinner@gmail.com>
Date: Wed Sep 13 10:10:10 2017 -0700
bpo-31234, socket.create_connection(): Fix ref cycle (#3546) |
|