summaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
authorYukihiro "Matz" Matsumoto <[email protected]>2013-03-13 20:32:34 -0700
committerYukihiro "Matz" Matsumoto <[email protected]>2013-03-13 20:32:34 -0700
commit4da772c0d48a4fe3da5a203f6b41689f93742dbe (patch)
treedba6aa3d9e0d35934aaafe34300b6dd95fbfc845 /src
parentcf4d53d02c7f1f1c1c16f4abc08d41623008de80 (diff)
parentc0b844033f19cc6ae2a2beee5383f335eebaeba4 (diff)
downloadmruby-4da772c0d48a4fe3da5a203f6b41689f93742dbe.tar.gz
mruby-4da772c0d48a4fe3da5a203f6b41689f93742dbe.zip
Merge pull request #996 from iij/pr-systemcallerror
mrb_sys_fail raises an instance of (subclass of) SystemCallError if we have it
Diffstat (limited to 'src')
-rw-r--r--src/class.c6
-rw-r--r--src/error.c16
2 files changed, 21 insertions, 1 deletions
diff --git a/src/class.c b/src/class.c
index 0ba702919..a00000375 100644
--- a/src/class.c
+++ b/src/class.c
@@ -203,6 +203,12 @@ mrb_vm_define_class(mrb_state *mrb, mrb_value outer, mrb_value super, mrb_sym id
return c;
}
+int
+mrb_class_defined(mrb_state *mrb, const char *name)
+{
+ return mrb_const_defined(mrb, mrb_obj_value(mrb->object_class), mrb_intern(mrb, name));
+}
+
static struct RClass *
class_from_sym(mrb_state *mrb, struct RClass *klass, mrb_sym id)
{
diff --git a/src/error.c b/src/error.c
index 421321c3d..6bd891768 100644
--- a/src/error.c
+++ b/src/error.c
@@ -5,6 +5,7 @@
*/
#include "mruby.h"
+#include <errno.h>
#include <stdarg.h>
#include <setjmp.h>
#include <string.h>
@@ -401,7 +402,20 @@ mrb_make_exception(mrb_state *mrb, int argc, mrb_value *argv)
void
mrb_sys_fail(mrb_state *mrb, const char *mesg)
{
- mrb_raise(mrb, E_RUNTIME_ERROR, mesg);
+ struct RClass *sce;
+ mrb_int no;
+
+ no = (mrb_int)errno;
+ if (mrb_class_defined(mrb, "SystemCallError")) {
+ sce = mrb_class_get(mrb, "SystemCallError");
+ if (mesg != NULL) {
+ mrb_funcall(mrb, mrb_obj_value(sce), "_sys_fail", 2, mrb_fixnum_value(no), mrb_str_new_cstr(mrb, mesg));
+ } else {
+ mrb_funcall(mrb, mrb_obj_value(sce), "_sys_fail", 1, mrb_fixnum_value(no));
+ }
+ } else {
+ mrb_raise(mrb, E_RUNTIME_ERROR, mesg);
+ }
}
void