Allan Odgaard mailinglist@textmate.org wrote:
On Mar 8, 2013, at 7:02 PM, Matt Neuburg matt@tidbits.com wrote:
following that up, I was able to discover this: system() and exec()
and spawn() and IO.popen() in ruby 2.0 apparently close non-standard file descriptors by default
Woah! That would cetainly explain it, assuming you use ruby 2.0 for the actual RubyMate script.
We generally recommend that you use ruby 1.8.7 for all the TextMate commands (i.e. have /usr/bin first in your PATH) and then set TM_RUBY to whatever ruby you want used for user scripts.
I don't think it's reasonable to assume that people will do something so complex. I for one have gone to great trouble to ensure that I am using one version of Ruby globally; it is unlikely that I would deliberately undermine that. Also it is shaky to assume that Ruby 1.8.7 will persist into the future. We are entering an age when Ruby 2 *is* Ruby. That is the future for which we must plan. TextMate's internal scripts must be prepared to deal with whatever version of Ruby they encounter in the real world that surrounds them...!
Do you have any reference on ruby 2.0 closing non-standard file descriptors? I only found the ":close_other" option for spawn, but it doesn't say it is the default behavior.
The key location that got me started is https://github.com/ruby/ruby/blob/v2_0_0_0/NEWS, where we read:
* incompatible changes: * system() and exec() closes non-standard file descriptors (The default of :close_others option is changed to true by default.)
I've seen this expressed elsewhere in a slightly different way:
"Kernel#system and #exec does not inherit non-standard file descriptor by default."
And, as I said, take a look at http://ruby-doc.org/core-2.0/Kernel.html - under "spawn" we are explicitly told that ":close_others is true by default for spawn and IO.popen", and then we are told under "system" and "exec" that their options are the same as for "spawn". Also, in http://www.ruby-doc.org/core-2.0/IO.html, we are told this:
"Ruby sets close-on-exec flags of all file descriptors by default since Ruby 2.0.0. So you don't need to set by yourself. Also, unsetting a close-on-exec flag can cause file descriptor leak if another thread use fork() and exec() (via system() method for example). If you really needs file descriptor inheritance to child process, use spawn()'s argument such as fd=>fd."
Hope this helps - m.