Patches item #5111, was opened at 2006-07-18 14:36
You can respond by visiting: 
http://rubyforge.org/tracker/?func=detail&atid=1700&aid=5111&group_id=426

Category: Ruby1.8
>Group: v1.8.x
Status: Open
Resolution: None
Priority: 3
Submitted By: Jonathan Paisley (jzp)
Assigned to: Nobody (None)
Summary: Instability around popen due to missing rb_thread_atfork

Initial Comment:
A Ruby program with multiple threads making calls to IO.popen (or indirectly via backticks) can get some nasty race conditions if existing threads get a chance to run in the child.

This can happen, for example, if the rb_warn("Insecure world writable dir...") from file.c:path_check_0() gets invoked in the child.

Solution is to add a call to 'rb_thread_atfork()' in the child after fork() in order to kill off those other threads.

On a related theme, it seems like the 'rb_proc_exec' in process.c:pipe_open() should be protected with rb_protect or similar, to prevent any exceptions raised during rb_proc_exec() from being propagated to the soon-to-be-dead main thread in the child process. I'm not familiar enough with use of rb_protect to provide a proper patch for that.


Patch attached and included inline below:


diff -ur orig/ruby/io.c ruby/io.c
--- orig/ruby/io.c	2006-06-26 08:23:47.000000000 +0100
+++ ruby/io.c	2006-07-18 22:27:33.000000000 +0100
@@ -3102,6 +3102,7 @@
   retry:
     switch ((pid = fork())) {
       case 0:			/* child */
+	rb_thread_atfork();
 	if (modef & FMODE_READABLE) {
 	    close(pr[0]);
 	    if (pr[1] != 1) {


----------------------------------------------------------------------

Comment By: Jonathan Paisley (jzp)
Date: 2007-03-18 09:43

Message:
This problem still occurs in ruby-1.8.6. What can be done to get the simple 
patch to io.c into 1.8.x?

There was some discussion around the original submission with patches by 
Nobu Nakada:

   http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-core/8262


----------------------------------------------------------------------

You can respond by visiting: 
http://rubyforge.org/tracker/?func=detail&atid=1700&aid=5111&group_id=426