summaryrefslogtreecommitdiff
path: root/lang/ruby18-base/patches/patch-eu
blob: 835f5b821c4e8e980841100b06efc914137e690d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
$NetBSD: patch-eu,v 1.1 2010/09/10 03:29:01 taca Exp $

* r26783: (Open3#popen3): use Thread.detach instead of double-fork, so that
	  the exit status can be obtained.
* r26784: (Open3#popen3): ignore trap and at_exit also when exec failed.
	  [ruby-dev:30181]

--- lib/open3.rb.orig	2009-12-14 04:28:06.000000000 +0000
+++ lib/open3.rb
@@ -56,39 +56,40 @@ module Open3
 
     pid = fork{
       # child
-      fork{
-	# grandchild
-	pw[1].close
-	STDIN.reopen(pw[0])
-	pw[0].close
-
-	pr[0].close
-	STDOUT.reopen(pr[1])
-	pr[1].close
-
-	pe[0].close
-	STDERR.reopen(pe[1])
-	pe[1].close
-
-	exec(*cmd)
-      }
-      exit!(0)
+      pw[1].close
+      STDIN.reopen(pw[0])
+      pw[0].close
+
+      pr[0].close
+      STDOUT.reopen(pr[1])
+      pr[1].close
+
+      pe[0].close
+      STDERR.reopen(pe[1])
+      pe[1].close
+
+      trap("EXIT", "DEFAULT")
+      at_exit {exit!(false)}
+      at_exit {raise($!)}
+      exec(*cmd)
     }
 
     pw[0].close
     pr[1].close
     pe[1].close
-    Process.waitpid(pid)
+    waiter = Process.detach(pid)
     pi = [pw[1], pr[0], pe[0]]
+    result = pi + [waiter]
     pw[1].sync = true
     if defined? yield
       begin
-	return yield(*pi)
+	return yield(*result)
       ensure
 	pi.each{|p| p.close unless p.closed?}
+        waiter.join
       end
     end
-    pi
+    result
   end
   module_function :popen3
 end