/* * call-seq: * SystemCallError.new(msg, errno) => system_call_error_subclass * * If _errno_ corresponds to a known system error code, constructs * the appropriate <code>Errno</code> class for that error, otherwise * constructs a generic <code>SystemCallError</code> object. The * error number is subsequently available via the <code>errno</code> * method. */ static VALUE syserr_initialize(argc, argv, self) int argc; VALUE *argv; VALUE self; { #if !defined(_WIN32) && !defined(__VMS) char *strerror(); #endif char *err; VALUE mesg, error; VALUE klass = rb_obj_class(self); if (klass == rb_eSystemCallError) { rb_scan_args(argc, argv, "11", &mesg, &error); if (argc == 1 && FIXNUM_P(mesg)) { error = mesg; mesg = Qnil; } if (!NIL_P(error) && st_lookup(syserr_tbl, NUM2LONG(error), &klass)) { /* change class */ if (TYPE(self) != T_OBJECT) { /* insurance to avoid type crash */ rb_raise(rb_eTypeError, "invalid instance type"); } RBASIC(self)->klass = klass; } } else { rb_scan_args(argc, argv, "01", &mesg); error = rb_const_get(klass, rb_intern("Errno")); } if (!NIL_P(error)) err = strerror(NUM2LONG(error)); else err = "unknown error"; if (!NIL_P(mesg)) { VALUE str = mesg; size_t len; StringValue(str); len = strlen(err)+RSTRING(str)->len+3; mesg = rb_str_new(0, len); snprintf(RSTRING(mesg)->ptr, len+1, "%s - %.*s", err, (int)RSTRING(str)->len, RSTRING(str)->ptr); rb_str_resize(mesg, strlen(RSTRING(mesg)->ptr)); } else { mesg = rb_str_new2(err); } rb_call_super(1, &mesg); rb_iv_set(self, "errno", error); return self; }