summaryrefslogtreecommitdiff
blob: a86587f7a7be167dbe0516a14dbd6d2c48fe53cd (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
71
72
73
74
75
76
77
78
79
80
Index: test/ruby/test_beginendblock.rb
===================================================================
--- test/ruby/test_beginendblock.rb	(revision 12125)
+++ test/ruby/test_beginendblock.rb	(revision 12126)
@@ -54,4 +54,34 @@
     assert_equal(expected, File.read(erroutpath))
     # expecting Tempfile to unlink launcher and errout file.
   end
+
+  def test_raise_in_at_exit
+    # [ruby-core:09675]
+    ruby = EnvUtil.rubybin
+    out = IO.popen("#{q(ruby)} -e 'STDERR.reopen(STDOUT);" \
+		   "at_exit{raise %[SomethingBad]};" \
+		   "raise %[SomethingElse]'") {|f|
+      f.read
+    }
+    assert_match /SomethingBad/, out
+    assert_match /SomethingElse/, out
+  end
+
+  def test_should_propagate_exit_code
+    ruby = EnvUtil.rubybin
+    assert_equal false, system("#{q(ruby)} -e 'at_exit{exit 2}'")
+    assert_equal 2, $?.exitstatus
+    assert_nil $?.termsig
+  end
+
+  def test_should_propagate_signaled
+    ruby = EnvUtil.rubybin
+    out = IO.popen("#{q(ruby)} -e 'STDERR.reopen(STDOUT);" \
+		   "at_exit{Process.kill(:INT, $$)}'"){|f|
+      f.read
+    }
+    assert_match /Interrupt$/, out
+    assert_nil $?.exitstatus
+    assert_equal Signal.list["INT"], $?.termsig
+  end
 end
Index: eval.c
===================================================================
--- eval.c	(revision 12125)
+++ eval.c	(revision 12126)
@@ -1562,11 +1562,15 @@
     int ex;
 {
     int state;
-    volatile VALUE err = ruby_errinfo;
+    VALUE err;
+    volatile VALUE errs[2];
+    int nerr;
 
+    errs[0] = ruby_errinfo;
     ruby_safe_level = 0;
     Init_stack((void*)&state);
     ruby_finalize_0();
+    errs[1] = ruby_errinfo;
     PUSH_TAG(PROT_NONE);
     PUSH_ITER(ITER_NOT);
     if ((state = EXEC_TAG()) == 0) {
@@ -1577,15 +1581,15 @@
 	ex = state;
     }
     POP_ITER();
-    ruby_errinfo = err;
+    ruby_errinfo = errs[0];
     ex = error_handle(ex);
     ruby_finalize_1();
     POP_TAG();
 
-    if (err) {
+    for (nerr = sizeof(errs) / sizeof(errs[0]); nerr;) {
+	if (!(err = errs[--nerr])) continue;
 	if (rb_obj_is_kind_of(err, rb_eSystemExit)) {
-	    VALUE st = rb_iv_get(err, "status");
-	    return NUM2INT(st);
+	    return sysexit_status(err);
 	}
 	else if (rb_obj_is_kind_of(err, rb_eSignal)) {
 	    VALUE sig = rb_iv_get(err, "signo");