Bug #4289 » 0002-error.c-rb_mod_sys_fail-use-subclass-and-cache.patch
| error.c | ||
|---|---|---|
| 
     extern const char ruby_description[]; 
   | 
||
| 
     static VALUE mod_sys_fail_cache; 
   | 
||
| 
     static const char * 
   | 
||
| 
     rb_strerrno(int err) 
   | 
||
| 
     { 
   | 
||
| ... | ... | |
| 
     void 
   | 
||
| 
     rb_mod_sys_fail(VALUE mod, const char *mesg) 
   | 
||
| 
     { 
   | 
||
| 
         VALUE exc = make_errno_exc(mesg); 
   | 
||
| 
         rb_extend_object(exc, mod); 
   | 
||
| 
         int n = errno; 
   | 
||
| 
         int need_aset_tmp = 0; 
   | 
||
| 
         VALUE super_class; 
   | 
||
| 
         VALUE cached_class; 
   | 
||
| 
         VALUE per_class; 
   | 
||
| 
         VALUE exc; 
   | 
||
| 
         VALUE arg; 
   | 
||
| 
         errno = 0; 
   | 
||
| 
         if (n == 0) { 
   | 
||
| 
            rb_bug("rb_mod_sys_fail(%s) - errno == 0", mesg ? mesg : ""); 
   | 
||
| 
         } 
   | 
||
| 
         super_class = get_syserr(n); 
   | 
||
| 
         if (! mod_sys_fail_cache) { 
   | 
||
| 
            mod_sys_fail_cache = rb_hash_new(); 
   | 
||
| 
            rb_global_variable(&mod_sys_fail_cache); 
   | 
||
| 
         } 
   | 
||
| 
         per_class = rb_hash_aref(mod_sys_fail_cache, super_class); 
   | 
||
| 
         if (NIL_P(per_class)) { 
   | 
||
| 
            need_aset_tmp = 1; 
   | 
||
| 
            per_class = rb_hash_new(); 
   | 
||
| 
         } 
   | 
||
| 
         cached_class = rb_hash_aref(per_class, mod); 
   | 
||
| 
         if (NIL_P(cached_class)) { 
   | 
||
| 
            cached_class = rb_obj_dup(super_class); 
   | 
||
| 
            rb_include_module(cached_class, mod); 
   | 
||
| 
            rb_hash_aset(per_class, mod, cached_class); 
   | 
||
| 
            if (need_aset_tmp) 
   | 
||
| 
                rb_hash_aset(mod_sys_fail_cache, super_class, per_class); 
   | 
||
| 
         } 
   | 
||
| 
         arg = mesg ? rb_str_new2(mesg) : Qnil; 
   | 
||
| 
         exc = rb_class_new_instance(1, &arg, cached_class); 
   | 
||
| 
         rb_exc_raise(exc); 
   | 
||
| 
     } 
   | 
||