Bug #13085 » 0001-io.c-io_fwrite-temporarily-freeze-string-when-writin.patch
| io.c | ||
|---|---|---|
| 
         return str; 
   | 
||
| 
     } 
   | 
||
| 
     struct fwrite_tmp_freeze { 
   | 
||
| 
         VALUE str; 
   | 
||
| 
         union { 
   | 
||
| 
     	rb_io_t *fptr; 
   | 
||
| 
     	long written; 
   | 
||
| 
         } as; 
   | 
||
| 
         int nosync; 
   | 
||
| 
     }; 
   | 
||
| 
     static VALUE 
   | 
||
| 
     fwrite_freeze(VALUE p) 
   | 
||
| 
     { 
   | 
||
| 
         struct fwrite_tmp_freeze *x = (struct fwrite_tmp_freeze *)p; 
   | 
||
| 
         const char *ptr; 
   | 
||
| 
         long len; 
   | 
||
| 
         OBJ_FREEZE_RAW(x->str); 
   | 
||
| 
         RSTRING_GETMEM(x->str, ptr, len); 
   | 
||
| 
         x->as.written = io_binwrite(x->str, ptr, len, x->as.fptr, x->nosync); 
   | 
||
| 
         return Qfalse; 
   | 
||
| 
     } 
   | 
||
| 
     static VALUE 
   | 
||
| 
     fwrite_unfreeze(VALUE str) 
   | 
||
| 
     { 
   | 
||
| 
         FL_UNSET_RAW(str, FL_FREEZE); 
   | 
||
| 
         return Qfalse; 
   | 
||
| 
     } 
   | 
||
| 
     static long 
   | 
||
| 
     io_fwrite(VALUE str, rb_io_t *fptr, int nosync) 
   | 
||
| 
     { 
   | 
||
| ... | ... | |
| 
         str = do_writeconv(str, fptr, &converted); 
   | 
||
| 
         if (converted) 
   | 
||
| 
     	OBJ_FREEZE(str); 
   | 
||
| 
         else 
   | 
||
| 
     	str = rb_str_new_frozen(str); 
   | 
||
| 
         else if (!OBJ_FROZEN_RAW(str)) { 
   | 
||
| 
     	struct fwrite_tmp_freeze x; 
   | 
||
| 
     	x.str = str; 
   | 
||
| 
     	x.as.fptr = fptr; 
   | 
||
| 
     	x.nosync = nosync; 
   | 
||
| 
     	rb_ensure(fwrite_freeze, (VALUE)&x, fwrite_unfreeze, str); 
   | 
||
| 
     	return x.as.written; 
   | 
||
| 
         } 
   | 
||
| 
         return io_binwrite(str, RSTRING_PTR(str), RSTRING_LEN(str), 
   | 
||
| 
     		       fptr, nosync); 
   | 
||
| 
     -  
   | 
||