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
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
|
diff --git a/kernel/bootstrap/compiled_method.rb b/kernel/bootstrap/compiled_method.rb
index 7fc1ac7..05e7d32 100644
@@ -1,4 +1,14 @@
class CompiledMethod
+ def self.load_from_file(path, version)
+ Ruby.primitive :load_file
+ raise PrimitiveFailure, "primitive failed"
+ end
+
+ def activate_as_script
+ Ruby.primitive :activate_as_script
+ raise PrimitiveFailure, "primitive failed"
+ end
+
def compile
Ruby.primitive :iseq_compile
raise PrimitiveFailure, "primitive failed"
diff --git a/kernel/bootstrap/io.rb b/kernel/bootstrap/io.rb
index e3e282f..9ae1bf3 100644
@@ -4,6 +4,11 @@ class IO
raise PrimitiveFailure, "primitive failed"
end
+ def self.create_pipe(lhs, rhs)
+ Ruby.primitive :create_pipe
+ raise PrimitiveFailure, "primitive failed"
+ end
+
def write(str)
Ruby.primitive :io_write
raise PrimitiveFailure, "IO#write failed. Might not have passed a string."
@@ -31,4 +36,19 @@ class IO
def ttyname
prim_operation(1)
end
+
+ def reopen(other)
+ Ruby.primitive :io_reopen
+ raise ArgumentError, "only accepts an IO object"
+ end
+
+ def io_close
+ Ruby.primitive :io_close
+ raise PrimitiveFailure, "primitive failed"
+ end
+
+ def close
+ Ruby.primitive :io_close_ng
+ raise PrimitiveFailure, "IO#close primitive failed"
+ end
end
diff --git a/kernel/bootstrap/object.rb b/kernel/bootstrap/object.rb
index 75aeb87..980bca7 100644
@@ -47,4 +47,8 @@ class Object
raise PrimitiveFailure, "primitive failed"
end
+ def become!(obj)
+ Ruby.primitive :object_become
+ raise PrimitiveFailure, "primitive failed"
+ end
end
diff --git a/kernel/bootstrap/primitives.rb b/kernel/bootstrap/primitives.rb
deleted file mode 100644
index 95c22e2..0000000
@@ -1,37 +0,0 @@
-# All primitives not else where in the bootstrap must be here.
-
-class Object
- def become!(obj)
- Ruby.primitive :object_become
- raise PrimitiveFailure, "primitive failed"
- end
-end
-
-class IO
- def self.create_pipe(lhs, rhs)
- Ruby.primitive :create_pipe
- raise PrimitiveFailure, "primitive failed"
- end
-
- def reopen(other)
- Ruby.primitive :io_reopen
- raise ArgumentError, "only accepts an IO object"
- end
-
- def io_close
- Ruby.primitive :io_close
- raise PrimitiveFailure, "primitive failed"
- end
-end
-
-class CompiledMethod
- def self.load_from_file(path, version)
- Ruby.primitive :load_file
- raise PrimitiveFailure, "primitive failed"
- end
-
- def activate_as_script
- Ruby.primitive :activate_as_script
- raise PrimitiveFailure, "primitive failed"
- end
-end
diff --git a/kernel/core/io.rb b/kernel/core/io.rb
index b521bfa..c72e2e5 100644
@@ -529,13 +529,6 @@ class IO
return 0
end
- def close()
- raise IOError, "Instance of IO already closed" if closed?
-
- io_close or raise SystemCallError, "Invalid file descriptor"
- nil
- end
-
def descriptor
@descriptor
end
diff --git a/shotgun/lib/primitives.rb b/shotgun/lib/primitives.rb
index a9492b7..a6abb18 100644
@@ -4538,6 +4538,28 @@ class ShotgunPrimitives
}
CODE
end
+
+ defprim :io_close_ng
+ def io_close_ng
+ <<-CODE
+ ARITY(0);
+ native_int j;
+
+ GUARD(IO_P(msg->recv));
+
+ j = io_to_fd(msg->recv);
+
+ if(j == -1) {
+ RAISE("IOError", "instance of IO already closed");
+ } else if(close(j)) {
+ RAISE_FROM_ERRNO("Unable to close IO object");
+ } else {
+ cpu_event_clear(state, j);
+ io_set_descriptor(msg->recv, I2N(-1));
+ RET(Qnil);
+ }
+ CODE
+ end
end
prim = ShotgunPrimitives.new
|