https://bugs.ruby-lang.org/https://bugs.ruby-lang.org/favicon.ico?17113305112011-07-21T07:53:07ZRuby Issue Tracking SystemRuby master - Feature #5041: Set FD_CLOEXEC for all fds (except 0, 1, 2)https://bugs.ruby-lang.org/issues/5041?journal_id=194142011-07-21T07:53:07Znormalperson (Eric Wong)normalperson@yhbt.net
<ul></ul><p>Akira Tanaka <a href="mailto:akr@fsij.org" class="email">akr@fsij.org</a> wrote:</p>
<blockquote>
<p>I'd like to set FD_CLOEXEC for all file descriptors (except 0, 1, 2,<br>
i.e. standard input/output/error).</p>
<p>I talked this issue with kosaki and matz at RubyKaigi 2011 and<br>
matz said "do it" and see that someone will cry or not.</p>
</blockquote>
<p>I support this proposal for Ruby 2.0. Very few applications depend on<br>
FD passing via exec() and they can easily be updated to set<br>
close_on_exec=false.</p>
<p>I've just updated git://bogomips.org/unicorn.git myself.</p> Ruby master - Feature #5041: Set FD_CLOEXEC for all fds (except 0, 1, 2)https://bugs.ruby-lang.org/issues/5041?journal_id=194152011-07-21T08:25:04Zakr (Akira Tanaka)akr@fsij.org
<ul><li><strong>Assignee</strong> set to <i>akr (Akira Tanaka)</i></li></ul><p>Eric Wong wrote:</p>
<blockquote>
<p>I support this proposal for Ruby 2.0. Very few applications depend on<br>
FD passing via exec() and they can easily be updated to set<br>
close_on_exec=false.</p>
<p>I've just updated git://bogomips.org/unicorn.git myself.</p>
</blockquote>
<p>Thank you for your support for this issue.</p>
<p>My (and matz's) intent is for 1.9.4.<br>
I'm not sure the next version will be 1.9.4 or 2.0, though.</p>
<p>I don't recommend io.close_on_exec = false for multithreaded programs.<br>
There is a race condition which cause fd leakage if another thread invokes<br>
system().<br>
(I guess unicorn has no problem because it is not multithreaded.)</p>
<p>So I may change the default of :close_others to true even for system() and<br>
exec().</p> Ruby master - Feature #5041: Set FD_CLOEXEC for all fds (except 0, 1, 2)https://bugs.ruby-lang.org/issues/5041?journal_id=194162011-07-21T08:48:55Zkstephens (Kurt Stephens)
<ul></ul><blockquote>
<p>Eric Wong wrote:<br>
I don't recommend io.close_on_exec = false for multithreaded programs.<br>
There is a race condition which cause fd leakage if another thread invokes<br>
system().<br>
(I guess unicorn has no problem because it is not multithreaded.)</p>
</blockquote>
<p>We commonly dup FD 2 so subprocesses can drill back out to parent's $STDERR, after parent has redirected FD 2 to /dev/null.</p>
<p>Ruby needs a generic callback upon Process.fork.</p>
<p>See:<br>
<a href="https://github.com/kstephens/ruby_is_forked" class="external">https://github.com/kstephens/ruby_is_forked</a><br>
<a href="https://github.com/kstephens/rails_is_forked" class="external">https://github.com/kstephens/rails_is_forked</a></p> Ruby master - Feature #5041: Set FD_CLOEXEC for all fds (except 0, 1, 2)https://bugs.ruby-lang.org/issues/5041?journal_id=194192011-07-21T09:23:08Znormalperson (Eric Wong)normalperson@yhbt.net
<ul></ul><p>Akira Tanaka <a href="mailto:akr@fsij.org" class="email">akr@fsij.org</a> wrote:</p>
<blockquote>
<p>Eric Wong wrote:</p>
<blockquote>
<p>I support this proposal for Ruby 2.0. Very few applications depend on<br>
FD passing via exec() and they can easily be updated to set<br>
close_on_exec=false.</p>
<p>I've just updated git://bogomips.org/unicorn.git myself.</p>
</blockquote>
</blockquote>
> I don't recommend io.close_on_exec = false for multithreaded programs.
> There is a race condition which cause fd leakage if another thread invokes
> system().
> (I guess unicorn has no problem because it is not multithreaded.)
<p>Yeah, and even in Rainbows!, threads only get used in the worker<br>
processes, not the master process[1] that calls exec()</p>
<blockquote>
<p>So I may change the default of :close_others to true even for system() and<br>
exec().</p>
</blockquote>
<p>If so, I would like a way specify a set/array/hash of FDs/IOs we don't<br>
want :close_others to automatically close on us.</p>
<p>[1] - Zbatery is a different story, but that's just one extra caveat to<br>
running with (optional) threads :<</p>
<p>--<br>
Eric Wong</p> Ruby master - Feature #5041: Set FD_CLOEXEC for all fds (except 0, 1, 2)https://bugs.ruby-lang.org/issues/5041?journal_id=195502011-07-22T23:53:06Zakr (Akira Tanaka)akr@fsij.org
<ul></ul><p>2011/7/21 Eric Wong <a href="mailto:normalperson@yhbt.net" class="email">normalperson@yhbt.net</a>:</p>
<blockquote>
<blockquote>
<p>So I may change the default of :close_others to true even for system() and<br>
exec().</p>
</blockquote>
<p>If so, I would like a way specify a set/array/hash of FDs/IOs we don't<br>
want :close_others to automatically close on us.</p>
</blockquote>
<p>If you want to disable automatic close fd1, fd2, ..., use follows.</p>
<p>h = { fd1 => fd1, fd2 => fd2, ... }<br>
system("command", h)</p>
<p>system() (, exec(), IO.popen and spawn()) can take an option hash<br>
to specify fds to inherit to child process.</p>
<a name="See-the-manual-of-spawn-for-details"></a>
<h2 >See the manual of spawn() for details.<a href="#See-the-manual-of-spawn-for-details" class="wiki-anchor">¶</a></h2>
<p>Tanaka Akira</p> Ruby master - Feature #5041: Set FD_CLOEXEC for all fds (except 0, 1, 2)https://bugs.ruby-lang.org/issues/5041?journal_id=195512011-07-22T23:59:11Zakr (Akira Tanaka)akr@fsij.org
<ul></ul><p>2011/7/21 Kurt Stephens <a href="mailto:ks.ruby@kurtstephens.com" class="email">ks.ruby@kurtstephens.com</a>:</p>
<blockquote>
<p>We commonly dup FD 2 so subprocesses can drill back out to parent's $STDERR, after parent has redirected FD 2 to /dev/null.</p>
<p>We need a generic callback on Process.fork.</p>
</blockquote>
<a name="I-cant-understand-how-it-is-related-to-this-issue"></a>
<h2 >I can't understand how it is related to this issue.<a href="#I-cant-understand-how-it-is-related-to-this-issue" class="wiki-anchor">¶</a></h2>
<p>Tanaka Akira</p> Ruby master - Feature #5041: Set FD_CLOEXEC for all fds (except 0, 1, 2)https://bugs.ruby-lang.org/issues/5041?journal_id=202192011-08-11T14:43:32Zakr (Akira Tanaka)akr@fsij.org
<ul><li><strong>File</strong> <a href="/attachments/1994">close-on-exec-by-default.patch</a> <a class="icon-only icon-download" title="Download" href="/attachments/download/1994/close-on-exec-by-default.patch">close-on-exec-by-default.patch</a> added</li></ul><p>I made a patch to set FD_CLOEXEC by default.<br>
It changes close_others option true by default for system() and exec().</p> Ruby master - Feature #5041: Set FD_CLOEXEC for all fds (except 0, 1, 2)https://bugs.ruby-lang.org/issues/5041?journal_id=202292011-08-12T05:23:12Znormalperson (Eric Wong)normalperson@yhbt.net
<ul></ul><p>Akira Tanaka <a href="mailto:akr@fsij.org" class="email">akr@fsij.org</a> wrote:</p>
<blockquote>
<p>Issue <a class="issue tracker-2 status-5 priority-4 priority-default closed parent" title="Feature: Set FD_CLOEXEC for all fds (except 0, 1, 2) (Closed)" href="https://bugs.ruby-lang.org/issues/5041">#5041</a> has been updated by Akira Tanaka.</p>
<p>File close-on-exec-by-default.patch added</p>
<p>I made a patch to set FD_CLOEXEC by default.<br>
It changes close_others option true by default for system() and exec().</p>
</blockquote>
<p>Thanks, unicorn.git works great with your patch after the following<br>
change:</p>
<p><a href="http://bogomips.org/unicorn.git/patch?id=6ab27beeda" class="external">http://bogomips.org/unicorn.git/patch?id=6ab27beeda</a></p> Ruby master - Feature #5041: Set FD_CLOEXEC for all fds (except 0, 1, 2)https://bugs.ruby-lang.org/issues/5041?journal_id=214502011-10-22T18:58:18Zakr (Akira Tanaka)akr@fsij.org
<ul><li><strong>Status</strong> changed from <i>Open</i> to <i>Closed</i></li><li><strong>% Done</strong> changed from <i>0</i> to <i>100</i></li></ul><p>This issue was solved with changeset r33507.<br>
Akira, thank you for reporting this issue.<br>
Your contribution to Ruby is greatly appreciated.<br>
May Ruby be with you.</p>
<hr>
<ul>
<li>
<p>include/ruby/intern.h (rb_fd_set_cloexec): declared.</p>
</li>
<li>
<p>io.c (rb_fd_set_cloexec): new function.<br>
(ruby_dup): call rb_fd_set_cloexec to set close-on-exec flag.<br>
(rb_sysopen_internal): ditto.<br>
(rb_pipe): ditto.<br>
(io_reopen): ditto.<br>
(io_cntl): ditto.</p>
</li>
<li>
<p>process.c (rb_f_exec): change the default :close_others option to<br>
true.<br>
(rb_f_system): ditto.<br>
(move_fds_to_avoid_crash): call rb_fd_set_cloexec to set<br>
close-on-exec flag.<br>
(ruby_setsid): ditto.<br>
(rb_daemon): ditto.</p>
</li>
<li>
<p>thread_pthread.c (rb_thread_create_timer_thread): call<br>
rb_fd_set_cloexec to set close-on-exec flag.</p>
</li>
<li>
<p>ruby.c (load_file_internal): ditto.</p>
</li>
<li>
<p>file.c (rb_file_s_truncate): ditto.<br>
(file_load_ok): ditto.</p>
</li>
<li>
<p>random.c (fill_random_seed): ditto.</p>
</li>
<li>
<p>ext/pty/pty.c (chfunc): ditto.<br>
(get_device_once): ditto.</p>
</li>
<li>
<p>ext/openssl/ossl_bio.c (ossl_obj2bio): ditto.</p>
</li>
<li>
<p>ext/socket/init.c (rsock_socket): ditto.<br>
(rsock_s_accept_nonblock): ditto.<br>
(rsock_s_accept): ditto.</p>
</li>
<li>
<p>ext/socket/socket.c (rsock_sock_s_socketpair): ditto.</p>
</li>
<li>
<p>ext/socket/ancdata.c (discard_cmsg): ditto.<br>
(make_io_for_unix_rights): ditto.</p>
</li>
<li>
<p>ext/socket/unixsocket.c (unix_recv_io): ditto.</p>
</li>
<li>
<p>ext/io/console/console.c (console_dev): ditto.</p>
</li>
</ul>
<p><a href="/issues/5041">[ruby-core:38140]</a> [Feature <a class="issue tracker-2 status-5 priority-4 priority-default closed parent" title="Feature: Set FD_CLOEXEC for all fds (except 0, 1, 2) (Closed)" href="https://bugs.ruby-lang.org/issues/5041">#5041</a>]</p>